View Full Version : 28146 GPS module

09-16-2011, 11:16 PM
Hi, so I have a Parallax 28146 SIO GPS module...I was looking at the datasheet and I was wondering if anyone could clear me up on a few things.. first off I'm using MCC18 C language, I want to know how to initialize the GPS and I want to know how to send commands to the GPS so that I can display the result on an LCD module. Can anyone help me???

PJ Allen
09-16-2011, 11:23 PM
The GPS knocks its out data (sentences) unprompted, constantly.
You might want to consider configuring it to output only a specific sentence of interest.

PE - If you're looking for a "C" program done up, then ask for that.

09-16-2011, 11:40 PM
That GPS module can be used in "raw" mode where it just spits out the NMEA data continuously, but normally you would use it in command mode (otherwise why buy it?). It will initialize itself, when the LED stops blinking it's ready (locked on to enough satellites to function).

There's about 10 or 12 different commands you can send over the serial I/O line. They're in the data sheet. You just send an ascii string (!GPS) followed by the hex code for the command you want to issue and the result comes back immediately over the same I/O line. It's just basic serial communication at 4800 bps (8n1). I've never used it with anything but a Basic Stamp2, but it shouldn't be too hard.

PJ Allen
09-16-2011, 11:50 PM
The GPS data can't update any more than once a second, anyway (RAW, /RAW), can it?

So, you can poll for possibly slightly stale data, or wait for the latest 1/sec. Either way.

Are you looking for help with serial comms in re. "C" (or what)?

09-16-2011, 11:59 PM
I'd have to hook it up to verify, but I don't think (in command mode anyway) it does much better than every 5 seconds or so. I base that on watching the seconds update on a time display. I think there's newer GPS chipsets that can update much faster than once a second though.

09-17-2011, 12:08 AM
The module appears to be able to return data within a little more than a second after it receives a command. I haven't looked at the firmware, but I would assume it waits for the next string to come by before parsing it all over again. This delay is for each command, so if you're getting latitude, longitude, altitude, heading, time, and other data, it will be 1sec * whatever pieces you're querying for.

PJ, MCC18 is a popular C variant for the PIC. So my guess is he's interfacing the module to a PIC, and using an LCD to display whatever values he's looking for. Draetoxtheloon, is that about right?

-- Gordon

09-17-2011, 12:15 AM
Thank you all for your replies for starters...Okay so yes I want to keep it in SMART mode where all I have to do is send it characters and it should send the corresponding data back, correct? so for instance if I want Latitude I would transmit 0x05 (GetLat), and hopefully I would be able to read the data coming back and display it on my LCD. Now I have a question...since I'm using MCC18 libraries I'm using the WriteUART() function and the putsUART() function. Can I just say WriteUART(0x20), followed by data = ReadUART(), putsXLCD(data)??? do you think that would work...these are built in functions by the way.

09-17-2011, 12:18 AM
Hi RDL2004, thanks for the reply....so would I then go WriteUART(!GPS), then WriteUART(0x05) for latitude....or would it be something like WriteUART(!GPS, 0x05)????

09-17-2011, 12:25 AM
It's not quite that easy.

First you need to prepend all command bytes with the string !GPS (with the "bang" character). Second, you to review the electrical connection between your MCU and the GPS. The GPS uses half-duplex serial, and your MCU will need to either have open collector I/O so you can use just one pin for both input and output, or you'll need to cheat by separating the SIO line from the GPS into Rx and Tx lines on your MCU. You can do this by pulling the Rx line high with a 10K resistor, and placing a diode between the SIO line and the Tx line. The cathode faces the Tx line. (Do a search in the forums and you should be able to find some examples of this).

Commands like GetLat return five bytes, which you must then combine to get the actual GPS coordinates. The coordinate data is in several separate bytes. Review the Basic Stamp 2 code in the data sheet for the conversion on how to convert the byte values to standard GPS dd.mmmm display.

As for what programming functions you can use, hopefully someone familiar with MCC18 can help. You might have better luck with that aspect in a PIC-C forum, where you'll happen on more people familiar with the libraries.

-- Gordon

09-17-2011, 12:41 AM
Okay, I'll try that...I'm pretty sure that the software UART is in full duplex so I will have to split the lines I'm sure....I need this part completed by Sunday so I will most likely be on the forums again tomorrow.

09-17-2011, 01:04 AM
Well, I just hooked my GPS module up to verify, and it definitely only updates the time every 5 seconds (running the sample code on a BS2px). Now that I think about it, that just doesn't make sense. I can only assume it's something in the SX firmware. Mine is an older model though, it's version 1 from 2006.

edit: ah, reading comprehension 101

it will be 1sec * whatever pieces you're querying for.

valid signal, number of sats, time, lat, long = 5

So, for a 1 second accurate clock, you would have to request only the time.

09-17-2011, 09:31 PM
Currently I'm getting garbage output to my LCD from the GPS....I don't think I'm sending the commands correctly.........first you need to send the STRING !GPS correct? so I would use a string sending function for this correct? Then secondly you would need to send the bytes to the GPS unit, so I would then use a function which sends bytes correct??? if all of this is correct then I'm unsure as to why I'm getting a strange symbol on the first character block of the LCD module, and blanks everywhere else....can someone help me?

09-17-2011, 09:35 PM
That's because you're sending bytes to your LCD, and not printable characters. Your LCD expects the bytes to be within ASCII 32 and 128. You need to find a function in your library to convert (as an example) a byte value of 2 into the numeral 2.

-- Gordon

09-18-2011, 01:08 AM
Hi Gordon, okay so I attempted that and it did work, although I'm not getting what I expected. So I was wondering if you could help me understand one of the functions in the Parallax 28146 Datasheet so that I can try and convert it to C code and use it in my program....The one I'm looking at is the subroutine Get_Lat: I don't really understand what these lines do:
SEROUT Sio, Baud, ["GPS", GetLat]
SERIN Sio, Baud, 3000, No_Response, [degrees, minutes, minutesD.HIGHBYTE, minutesD.LOWBYTE, dir]

I kind of understand the SEROUT line but tell me if I'm wrong, First you are calling the SEROUT function and telling it that it is on the Sio line, then you are giving it a Baud rate (mine is 4800), then it looks like it is writing strings using RX and TX....is this correct?

I don't understand the SERIN line....mainly the 3000, No_Response, [degrees, minutes, minutesD.HIGHBYTE, minutesD.LOWBYTE, dir] part

09-18-2011, 02:28 AM
I don't understand the SERIN line....mainly the 3000, No_Response, [degrees, minutes, minutesD.HIGHBYTE, minutesD.LOWBYTE, dir] part
If you use
SERIN <Pin>, <Baud Rate>, <Timeout> (3 seconds in this example), <where to go if there is a timeout>, [ BYTE <degrees>, BYTE <minutes>, HIGH BYTE of <minutesD> LOW BYTE of <minutesD> (to be combined into a word varable <minuteD>), BYTE dir]

09-18-2011, 07:37 PM
Okay, thank you Franklin...I now need to figure out how I can do this using RX and TX of USART or Software UART on a PIC micro controller....do you know how I would accomplish this? I can define bytes like the code examples...I'm just not sure how to use them in MCC18 libraries, the two I'm using is WriteUART and ReadUART, this, I'm thinking that I could make WriteUART act like SEROUT and ReadUART act like SERIN...do you think that makes sense?

09-18-2011, 08:48 PM
Also I was wondering if anyone new what the DEBUG statement does...I'm assuming its an assembly function, and I was wonder where the DEC1, DEC2, DEC3, and DEC4 are allocated and what they mean...for instance in the lines:

DEBUG MoveTo, FieldLen, 12, DEC3 degrees, DegSym, " ", DEC2 minutes, MinSym, " "
DEBUG DEC2 (workVal / 10), ".", DEC1 (workVal // 10), SecSym, " "
DEBUG "N" + (dir * 5)

PJ Allen
09-18-2011, 08:59 PM
DEBUG is a PBasic command for "printing" data to an IDE-based serial terminal.

You don't "need" to implement a Timeout equivalent if you're happy to have your program hang till it gets GPS data. The Timeout is an option whereby the program can move on if there's no data within some given time.

DEC3 is a formatter, indicating that 'degrees' is 3 decimal numbers. DEC2 stipulates that 'minutes' is 2 decimal numbers.

The data from the GPS is all ASCII.

09-18-2011, 09:21 PM
Okay thank you PJ, I am attempting to get the Latitude function of the Parallax 28146 GPS datasheet to work in C rather than whatever language (looks like assembly) it is in. So I do have a lot of questions...so I'll post more as they come to me..thanks again.

09-18-2011, 09:23 PM
Oh, quick question, what do you mean by the Timeout Equivalent, basically I want the GPS to send its Latitude once it is activated, then do nothing if it isn't activated.

PJ Allen
09-18-2011, 11:27 PM

OK, back in #14, you stated, "I don't understand the SERIN line....mainly the 3000, No_Response... part."
So, in that line of code, the program is going to SERIN (ReadUART), but if it doesn't get any data in 3000msec then it's going to go to a subroutine called No_Response. If those parameters (optional) aren't specified then the program will stay there, waiting for data.

Typically, "we" SERIN the data to a data array and then transmit that out to an LCD with some formatting (starting on a particular line or place.)

[If you are using a serial LCD (has that been specified yet?) you could run the GPS data_out right into the LCD input (it won't be formatted) - assuming they have a common baudrate.]

PE - I don't know how you guys send characters, but as a hex/data proposition, if you send the GPS the following string: 21 47 50 53 05
(representing "! G P S" 05)
then it should send out Latitude data (once)

There's a member, his handle is Zoot, who probably knows your "C"-deal well enough to connect with you there.

09-19-2011, 01:29 AM
Excellent thanks for your help, this is all starting to make a lot of sense....to answer your question No my LCD is not Serial....I'm using a NewHaven 16X2 character display, the upper four bits (D4-D7) are connected to my PIC. I'll check for Zoot, though I'm meeting with an Instructor in the morning so hopefully he can help as well. The ASCII string may definitely work, I'm going to try it out.

09-19-2011, 11:18 PM
So I still can't get the proper information to display on my LCD module......What does the Parallax GPS output..it says a number of bytes, but are those characters? or are they ASCII??

PJ Allen
09-19-2011, 11:37 PM
Right, the GPS outputs ASCII characters, they're arranged as bytes.
Assuming the GPS gets the latitude query then it'll shoot back the latitude data, 9 bytes of ASCII code: 4 numeric characters, a period, and 4 numeric characters -- the degrees MSD, the degrees LSD, the minutes MSD, the minutes LSD, a period, the 1/10min digit, the 1/100min digit, the 1/1000 min digit, the 1/10000 minute digit.

Are you using a microcontroller or a PC or what?

09-20-2011, 05:36 PM
I'm using a PIC18F26K22 micro controller

PJ Allen
09-20-2011, 06:39 PM
So, you understand serial comms, ASCII, and so on -- or is this your first time with any of that?

Any progress yet?

09-20-2011, 09:08 PM
I have some experience with serial comms and ASCII, I'm a student at DeVry, I am having a little success...after a bunch of changes to my code I'm able to receive something on the LCD, although it isn't correct. The numbers displayed seem to change drastically when I reset the Micro controller....so I'm sending 0x05 for Latitude, then when I ReadUART() as you mentioned it comes out ASCII, so I'm trying to use atoi, atob, to convert the ASCII to an 8-bit signed byte for display (atob), or use atoi to convert ASCII string to 16-bit signed integer....I know you may not understand this code, but I'm going to write some and see what you can make from it...

putsUART(headerString); //HeaderString is "!GPS"

WriteUART(0x05); //Get Latitude
DelayRXHalfBitUART(); //Delay recieve by 275ms
DelayRXHalfBitUART(); //Delay recieve by 275ms

for(i = 0; i <= 5; i++) //iterated until 5 because the Latitude command returns "5 Bytes" oh and data is of type char (Byte)
*data[i] = ReadUART(); //read a byte
//atob(*data); //convert ASCII string to 8-bit signed byte, I get 85 on LCD
//atoi(*data); //convert ASCII string to 16-bit signed integer, I get -1 on LCD //both the lines are commented because I'm not sure which to use
degrees = *data[0];
gpsMinutes = *data[1];
fracMinutes = *data[2];

Delay1KTCYx(30); // Delay of 15ms
Delay1KTCYx(10); // Delay of 5ms

sprintf(*data, "%02d:%02d:%02d", degrees, gpsMinutes, fracMinutes); //for Latitude

09-20-2011, 10:03 PM
You might want to seek out help on a forum for your PIC and C language, as they'll know the particulars better than anyone. Your example shows you're using a 'char', which can be either signed or unsigned. It's often signed (depends on the platform), so a value of 128 and above is being treated differently than what you're thinking is happening. The GPS returns unsigned bytes, so be sure not to use signed chars (or signed anything), except when displaying standard ASCII, which is always between 32 and 127.

It's easy to get confused if you try to do too many things at once. You should first try by manually setting byte variables to display as characters on your LCD. Forget the GPS for now. Once you're sure that a byte with the value "205" is displayed correctly on the LCD you're ready to move on. Be sure to also try values under 32. If you get weird characters instead, you're sending actual bytes for those values, and not strings.

Then test the connection with your GPS and your conversion by putting the unit in RAW mode. Simply echo the strings you get back from the GPS. If you have a debug window send the serial output from the GPS there. It'll be easier to see what's happening, because LCD displays have limited space for characters.

When all of this is working you can put the GPS back into Smart Mode. Try a simpler one-byte return type. Number of satellites is a good one, as it returns just one byte. The value will always be under 20, as that's the limit of the receiver itself. (BE SURE you're back into Smart Mode, or else it'll appear you're getting data, when it's actually just random values being picked up from the receive pin in RAW mode.)

Okay, *now* you're ready to query the GPS for the five bytes for reading latitude or longitude.

-- Gordon

09-20-2011, 10:17 PM
To clarify an earlier post by PJAllen, in Smart Mode the 28146 outputs bytes, and not ASCII strings. This type of module contains its own microcontroller which pre-parses the GPS strings from the receiver. When the module is in Smart Mode, and you ask for data, the controller on the module parses one of the NEMA GPS strings it gets, and then returns the data as unsigned bytes. For latitude and longitude, there are five bytes, as outlined in the documentation.

That means, for example, if the degrees value is 33, it's not ASCII 3 and 3, but a byte value of 33.

From these bytes you must construct the actual degrees/minutes display. The receiver provides GPS coordinates in the format DDmm.mmmm, but you probably want degrees in minutes and seconds in the more readable dd.mmmm format, or decimal degrees.

-- Gordon

PJ Allen
09-20-2011, 11:03 PM
I thought the SmartMode was supposed to make things easier.

"That means, for example, if the degrees value is 33, it's not ASCII 3 and 3, but a byte value of 33."
Now I have to go set myself on fire (again.)

09-20-2011, 11:56 PM
If it were up to me, Smart Mode would have two modes. Something like this:

A. Prefix with !GPS, and you get the individual bytes, which you can then use for numeric calculations. (If they were strings you'd have to then parse them down if you wanted, for example, to calculate the distance between two points.)

B. Prefix with !GPX, and you get the value as a single ASCII null terminated string. You can use that kind of data to directly display on an LCD without any further processing except basic formatting.

Variations on the theme, or an additional control byte sent in, might provide the latitude and longitude in various coordinate types. DD.mmmm in min/sec could be directly plugged into Google Maps API (it won't take decimal or DDmm.mmmm GPS coordinates, it seems).

-- Gordon

09-21-2011, 05:55 PM
Okay, again thanks for all the help, I managed to get it so if I say data = "205"; and say

sprintf(idata, "%02d",data);

Then I get 205 to show up on LCD, if I say data = "205" and say


I get the ASCII equivalent symbol -> Latin capital letter I with acute

09-21-2011, 05:57 PM
So this means I could probably send the command WriteUART(0x02) <-- Get Satellites, then just read it back, data = ReadUART() and then put it into my sprintf function for formatting to the LCD...I have yet to attempt this but hopefully it works.