NMEA 0183 Message Format
Written by Jeremy Chan on May 23rd, 2007 for Team Daedalus
Reposted from the Daedalus Archive: While working on one of my first EE projects back in 2007, I encountered a GPS checksum which I couldn’t find an algorithm for. After searching online, I found a few forum posts on how to do it, but the directions weren’t clear. I wrote this article for those like me, who understand C better than they understand vague documentation.
First off, most off-the-shelf GPS receivers give you its data via RS232 in the NMEA 0183 format:
e.g. $GPGGA,,,,,,0,02,,,,,,,*64
$ begins the message, and the next character is the first byte of data
GPGGA is the message type, followed by comma separated GPS fields
* is the beginning of the checksum, and the previous character was the last byte of data
64 is the checksum value in hex (0×64) (100 in decimal)
The checksum value is generated by X-OR’ing all the data characters together. The way that I found works is to XOR the characters in sequence. Starting with the first ‘data’ character, XOR it with the next. Then take that result, and XOR it with the next, and so on.
C Code Example
The following code demonstrates how the calculation is done, and assumes that the $ and *xx data has been stripped. The calculated hex output checksum should match the data’s xx checksum exactly.
#include <stdio.h> int main(void)
{
/* Source Data Line: $GPGGA,,,,,,0,02,,,,,,,*64 */ char data[] = "GPGGA,,,,,,0,02,,,,,,,"; /* Variables for keeping track of data index and checksum */ char *datapointer=&data[0]; char checksum=0; /* Loop through entire string, XORing each character to the next */
while (*datapointer != '\0')
{
checksum ^= *datapointer;
datapointer++;
}
/* Print out the checksum in ASCII hex nybbles */
printf("The calculated checksum is 0x%02x\n", checksum);
return; } |
Now when running the above code, I’m able to get the calculated checksum of 0×64 – matching the original checksum sent by the GPS receiver.
I like this!
Just curious as to what you’ve used this for? was it for can sat?
btw, my skill right now in C is pretty rusty, so I first saw the pointer indexing and was like why? then i was like OHH!! wow! nice!!
Yeah, used it in cansat back in the undergrad days. Used it a bunch more since then too. Seems to be a pretty common algorithm.