Introduction: I've written a handful of applications that deal with GPS position data. The world standard for this data is the NMEA sentence. Here is an example of a NMEA GGA sentence:
$GPGGA,115739.00,4158.8441367,N,09147.4416929,W,4,13,0.9,255.747,M,-32.00,M,01,0000*6E
If you've never seen this before, it will look a little cryptic. However, the above characters contain a lot of useful info, and are actually somewhat human-readable if you know what you're looking at. This page is intended to help you understand the various parts of the message so that you can quickly write software to read or create NMEA sentences, and hopefully overcome problems such as corrupted or invalid data.
NEMA Sentence Structure: The first thing you need to know is that each NMEA sentence is on its own line, separated by two characters, a carriage return (ASCII 13) and a line feed (ASCII 10). If you're looking at the data stream in a terminal program such a PuTTy, you'll see this as a new line. Here is an example of multiple messages from a GPS receiver:
$GPGGA,115739.00,4158.8441367,N,09147.4416929,W,4,13,0.9,255.747,M,-32.00,M,01,0000*6E
$GPGGA,115740.00,4158.8441367,N,09147.4416924,W,4,13,0.9,255.739,M,-32.00,M,01,0000*64
$GPGGA,115741.00,4158.8441360,N,09147.4416934,W,4,13,0.9,255.738,M,-32.00,M,01,0000*62
$GPGGA,115742.00,4158.8441378,N,09147.4416932,W,4,13,0.9,255.740,M,-32.00,M,01,0000*61
$GPGGA,115743.00,4158.8441389,N,09147.4416944,W,4,13,0.9,255.739,M,-32.00,M,01,0000*61
$GPGGA,115744.00,4158.8441396,N,09147.4416939,W,4,13,0.9,255.741,M,-32.00,M,01,0000*6D
$GPGGA,115745.00,4158.8441395,N,09147.4416936,W,4,13,0.9,255.744,M,-32.00,M,01,0000*65
Any well-behaved GPS receiver will output both the carriage return and line feed characters immediately following each line. For this reason, you can usually separate lines by looking for these two characters. Below is a VB.Net code sample used to read data coming in from a serial port:
ReceiveBuffer += COMPort.ReadExisting
If InStr(ReceiveBuffer, vbCrLf) Then
Dim lines() As String = Split(ReceiveBuffer, vbCrLf)
For i = 0 To UBound(lines) - 1
If lines(i).Length > 5 Then
ParseLine(lines(i))
End If
Next
ReceiveBuffer = lines(UBound(lines))
Else
If ReceiveBuffer.Length > 4000 Then
ReceiveBuffer = ""
End If
End If
The Checksum: The next thing you'll notice is that all NMEA sentences start with a dollar sign ($) indicating the start of a message. Sentences also end with an asterisk (*) followed by two characters. Those two characters are the checksum for the message. The checksum allows you to confirm that the message is the same as when it was created, and no data corruption along the way. It is a simple method of error checking.
$GPGGA,115739.00,4158.8441367,N,09147.4416929,W,4,13,0.9,255.747,M,-32.00,M,01,0000*6E
The checksum is actually computed as a single byte of data (8 bits), but is formatted as a two-character hexadecimal so that it is valid in ASCII. If you are reading NMEA data, you will need to separate the line to get everything between the dollar sign ($) and the asterisk (*), highlighted above in green. That data needs to have the checksum calculated for it. At that point, if you’re reading the data, you can compare your computed checksum with the one at the end of the sentence. Below is a VB.Net code sample used to calculate the checksum:
Public Function CalculateChecksum(ByVal sentence As String) As String
' Calculates the checksum for a sentence
' Loop through all chars to get a checksum
Dim Character As Char
Dim Checksum As Integer
For Each Character In sentence
Select Case Character
Case "$"
' Ignore the dollar sign
Case "*"
' Stop processing before the asterisk
Case Else
' Is this the first value for the checksum?
If Checksum = 0 Then
' Yes. Set the checksum to the value
Checksum = Convert.ToByte(Character)
Else
' No. XOR the checksum with this character's value
Checksum = Checksum Xor Convert.ToByte(Character)
End If
End Select
Next
' Return the checksum formatted as a two-character hexadecimal
Return Checksum.ToString("X2")
End Function
End If
The Header: As mentioned above, all messages start with a $. The next five characters indicate the type of message that follows. Of these, the first character is always the letter ‘G’.
The second character is used to describe the primary positioning system used to create the data. This will almost always be the letter ‘P’ for GPS, but I have also seen ‘L’ for GLONASS.
$GPGGA,
The next three characters define the type of sentence that follows.
$GPGGA,
Some common sentence types are:
GGA = Position, elevation, time, number of satellites used, fix type, correction age.
RMC = Position, date, time, speed, heading.
VTG = Heading, speed.
GSV = Satellites in view, their PRN number, elevation, azimuth, and signal strength.
GSA = PRNs of satellites used, Dilution of precision.
Last updated: December 10, 2013