Expand description
A GPS receiver’s NMEA 0183 sentences, as a logger writes them to a text file.
An NMEA 0183 receiver writes text, one sentence a line: a $, a five-character address (a
two-letter talker, GP for GPS, GN for several systems at once, then a three-letter sentence
type), the sentence’s fields separated by commas, a * and a two-digit hexadecimal checksum,
the exclusive-or of every character between the $ and the *, and CR LF:
$GPGGA,123519.000,4807.0380,N,01131.0000,E,1,08,0.9,545.4,M,46.9,M,,0000*59
$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
$GPRMC,123519.000,A,4807.0380,N,01131.0000,E,022.4,084.4,230394,,,A*62The standard itself is sold by the National Marine Electronics Association; this reader works
from the public description gpsd’s authors keep, Eric S. Raymond’s NMEA Revealed
(https://gpsd.gitlab.io/gpsd/NMEA.html, as last updated 2026-10-11): the sentence layout and
checksum under “NMEA Encoding Conventions” and “NMEA 0183 physical protocol layer”, the four
sentences read under “NMEA Standard Sentences” (GGA, RMC, GSA, GSV), the FAA mode
letters under “Error status indications”, and the clock under “Dates and times”.
The sample files. As of 2026-10-12, among the project’s sample logs, 12 distinct files are
NMEA 0183, all from one kind of receiver, all from the private collection of flights this
project checks against. Each holds talker GP only, and one second’s sentences in the same
order: GGA, GSA, on one second in five a burst of three GSV, then RMC, the RMC with
the GGA’s time in every one of them. Lines end in CR LF. Every complete sentence carries a
checksum, and all but two check out. Their quirks, each handled below:
- 10 open with a line that isn’t a whole sentence: in 4, bytes of noise before a sentence’s
$; in 5, a few bytes of noise alone; in 1, a sentence cut at its start. - 2 end in bytes that aren’t text, NUL among them, on the line of their last sentence: in one that sentence is cut off before its checksum, in the other its checksum fails.
- 1 more holds a sentence with bytes that aren’t text among its fields, whose checksum fails.
- Before its first fix the receiver writes
GGAandRMCwith an empty time (in 11 files), then a time with a placeholder date onRMC(one of two fixed dates, years before the flights), then the real date while the status is stillV, void, and only then statusA, a valid fix. - 9 step back 2 s once (one by 1.999 s): in 7 a few minutes after the first fix, in 2 before it. Plausibly the receiver taking up the leap-second count the satellites broadcast “once every 12.5 minutes”, reported UTC being “slightly inaccurate between a cold boot … and the following subframe broadcast” (NMEA Revealed, “Dates and times”); this is an inference.
GGA’s fix quality is 0, 1 or, in 9 files, 6, dead reckoning, whenRMC’s mode isE.- One file, 80 lines and 10 s long, never gets a fix: its positions are all gaps.
- None crosses midnight UTC.
Sentences. A line may hold noise around a sentence, or two sentences run together where a
line end was lost. So a sentence is read wherever a $ opens one whose characters are
printable ASCII (none of *, !, \ or ~ among its fields), ending at the first *
with two hexadecimal digits that equal its checksum; anything else on the line is left out,
and counted in a note. A line that holds no such sentence is skipped and counted, by kind:
no $ at all; a sentence cut off before its checksum; or a checksum that fails, or bytes the
standard doesn’t allow. A sentence without a checksum isn’t read: every sample has one, and
NMEA Revealed calls it mandatory. Sentences longer than the standard’s 82 characters are
read all the same. NUL bytes, and bytes that aren’t UTF-8 (each a U+FFFD after decoding), are
counted in a note.
A file is taken for NMEA 0183 when at least 3 of its first 50 lines that aren’t blank open with a sentence whose checksum checks out (or every line does, in a shorter file), so that a first line of noise doesn’t hide it, and a log of another kind that quotes sentences inside its own lines, as a ground station’s may, isn’t taken for one.
Channels. The file has no barometer: the record’s primary track is empty, with a note, and
every value is a channel, named for its sentence’s address and field, such as GPGGA altitude
or GPGSV PRN 12 SNR (the PRN without its leading zeros). The address keeps a file mixing talkers, as a multi-system receiver
writes GNGGA beside GPGSV and GLGSV, from mixing their channels. Each sentence read
adds one sample to each of its channels, in the file’s order; an empty field is a gap, NaN,
and a field that isn’t what its channel holds is a gap counted in a note.
| Sentence | Channel | Quantity | From the field |
|---|---|---|---|
GGA | latitude, longitude | Quantity::Latitude, Quantity::Longitude, degrees | ddmm.mmmm and N/S, dddmm.mmmm and E/W, made signed degrees, south and west negative |
GGA | fix quality | Quantity::Number | as written: 0 no fix, 1 GPS, 2 DGPS, 3 PPS, 4 RTK, 5 float RTK, 6 estimated (dead reckoning), 7 manual, 8 simulation |
GGA | satellites used, HDOP | Quantity::Number | as written |
GGA | altitude | Quantity::GnssAltitude, m above mean sea level | meters, when the unit field is M, as the layout gives |
GGA | geoid separation | Quantity::Distance, m | meters, when its unit field is M |
GGA | DGPS age, DGPS station | Quantity::Number | as written: seconds since the last differential correction, and the station’s id |
RMC | status | Quantity::Number | 1 for A, a valid fix; 0 for V, void |
RMC | latitude, longitude | as GGA’s | as GGA’s |
RMC | speed | Quantity::Speed, m/s | knots, × 1852/3600 (the international nautical mile, 1852 m exactly) |
RMC | course | Quantity::Angle, degrees | degrees from true north, as written |
RMC | magnetic variation | Quantity::Angle, degrees | degrees and E/W, east positive |
RMC | mode | Quantity::Number | the FAA mode letter as GGA’s fix quality code for the same mode: N 0, A 1, D 2, P 3, R 4, F 5, E 6, M 7, S 8 |
GSA | selection | Quantity::Number | 1 for A, automatic 2D/3D; 0 for M, manual |
GSA | fix type | Quantity::Number | as written: 1 no fix, 2 2D, 3 3D |
GSA | satellites used | Quantity::Number | how many of its 12 satellite fields are filled |
GSA | PDOP, HDOP, VDOP | Quantity::Number | as written |
GSV | satellites in view | Quantity::Number | as written, once a burst, from its first sentence |
GSV | PRN n elevation, PRN n azimuth | Quantity::Angle, degrees | as written, azimuth from true north |
GSV | PRN n SNR | Quantity::Number | as written, dB, 00 to 99 |
RMC’s magnetic variation and mode, and GGA’s DGPS age and station, are left out when every
sentence leaves them empty (no sample fills the variation). A GSV sentence’s message count
and number order the burst, and GSA’s list of satellites used is kept as its count; fields
past the ones in the table, such as NMEA 4.10’s signal and system ids, are left out and
counted in a note. An altitude or geoid separation whose unit field isn’t M is kept apart,
as written, in a channel such as GPGGA altitude, unit "F" (Quantity::Unrecognized), with
a note. Sentence types other than these four are counted in a note, their fields left out.
Clocks. GGA and RMC state the time of day in UTC, hhmmss.sss; RMC states the date,
ddmmyy (a year yy of 80 or more is 19yy, else 20yy, as GPS began in 1980). A sample’s
time is its sentence’s, in seconds from the log’s zero, the first sentence with a time. The
day is the date of the last RMC with status A: a void RMC‘s date is a placeholder in the
samples, so it is left out, with a note. Before such an RMC, and in a file without one,
times are times of day alone. A time of day more than 12 hours before the last is the next
day, and one more than 12 hours after it the day before; where an RMC with status A dates
it, the date settles the day instead. GSA and GSV carry no time: each takes the time of the
GGA or RMC before it, its second’s, as the samples’ order shows, with a note giving the
file’s own evidence; one before any time has a gap for its time, as does a GGA or RMC whose
time is empty. Each channel keeps its samples in the file’s order, so a time may go back,
as the samples’ 2 s step does: a note says how often and how far.
Hostile input. Work is linear in the file: a line is cut at its $s once. At most
MAX_ADDRESSES sentence addresses are read and MAX_SATELLITES satellites a GSV
address, the rest counted; notes about single channels are capped; text quoted in a note is
cut short.
Constants§
- MAX_
ADDRESSES - The most sentence addresses of the four types read, such as
GPGGAandGNGGA; sentences at further addresses are counted in a note. The samples have four. - MAX_
SATELLITES - The most satellites one
GSVaddress gives channels to; further satellites are counted in a note. The samples see at most 28.
Functions§
- read
- Reads a GPS receiver’s NMEA 0183 sentences.