TestBench.tools
GitHub

NMEA 0183 Sentence Generator

Build valid GGA/RMC/custom sentences with checksum, from decimal coordinates.

Sentence
$GPGGA,023000.00,3733.9900,N,12658.6800,E,1,08,0.9,38,M,,M,,*55
Coordinate encoding
37.5665° → 3733.9900,N
Coordinate encoding
126.978° → 12658.6800,E
Decodes back as
GPGGA · 14 fields · checksum OK

The checksum is computed here — XOR of every character between $ and * — so an invalid sentence cannot be produced. Coordinates are encoded as degrees and decimal minutes (ddmm.mmmm), which is the field format receivers expect.

This tool builds valid NMEA 0183 sentences — GGA, RMC, or any custom body — with the checksum computed for you. Coordinates go in as ordinary decimal degrees and come out in the ddmm.mmmm field format receivers expect, with the conversion shown so you can see exactly what changed. Every sentence is round-tripped through this site's own decoder before it is shown.

The coordinate field is the whole difficulty

Everything else in an NMEA sentence is plain text, but the position fields use a format nothing else uses: degrees concatenated with decimal minutes. Latitude is ddmm.mmmm, longitude is dddmm.mmmm, and the hemisphere travels in its own field as N/S/E/W rather than as a sign.

37.5665° N → 3733.9900,N (0.5665° × 60 = 33.99′)
126.9780° E → 12658.6800,E
−33.8688° → 3352.1280,S (sign becomes the hemisphere)

The two classic mistakes are writing decimal degrees straight into the field, and treating the field as one decimal number when reading it back. Both produce values that parse cleanly and are wrong by up to tens of kilometres — the error is silent, which is why this converter shows its work.

Worked example

lat 37.5665, lon 126.9780, 02:30:00 UTC, quality 1, 8 sats →
$GPGGA,023000.00,3733.9900,N,12658.6800,E,1,08,0.9,38.0,M,,M,,*4B

decoded back: GPGGA · 14 fields · checksum OK

RMC sentence fields, in order

RMC is the sentence most loggers and displays key on, because it is the only common one that carries the date. Its fields are positional — the meaning of a value is its place after the address, so an empty field still occupies its slot. Here is the same fix as the GGA example above, as RMC, moving at 12.5 knots on a course of 84.4°:

$GPRMC,023000.00,A,3733.9900,N,12658.6800,E,12.5,084.4,051026,,,A*63
ParameterValueNotes
1 · UTC time023000.00hhmmss.ss — 02:30:00 UTC
2 · StatusAA = valid, V = void
3 · Latitude3733.9900ddmm.mmmm
4 · N/SN
5 · Longitude12658.6800dddmm.mmmm
6 · E/WE
7 · Speed over ground12.5knots
8 · Course over ground084.4degrees
9 · Date051026ddmmyy — 5 October 2026
10 · Magnetic variation(empty)degrees
11 · Variation E/W(empty)
12 · Mode indicatorAabsent on older receivers
Checksum*63XOR of everything between $ and *

Two things trip up RMC parsers. The status field is the validity flag: with V the receiver still fills the slots it can, so a parser that ignores field 2 logs stale or empty positions as real ones. And the date is ddmmyy with a two-digit year — the century is yours to supply. This page's decoder labels all twelve fields; paste the sentence above into it to check.

Parameters

ParameterValueNotes
SentencesGGA · RMC · custom bodycustom covers proprietary $P…
Coordinates indecimal degreesencoded to ddmm.mmmm / dddmm.mmmm
ChecksumXOR of body, two hex digits$ and * excluded
TalkersGP · GN · GL · GA · BD
Verificationround-trip through this site's decoder

Python equivalent

Python
# The same GGA sentence in Python
lat, lon = 37.5665, 126.9780

def nmea_coord(deg, width):
    d = int(abs(deg)); m = (abs(deg) - d) * 60
    return f"{d:0{width}d}{m:07.4f}"

body = (f"GPGGA,023000.00,{nmea_coord(lat, 2)},{'N' if lat >= 0 else 'S'},"
        f"{nmea_coord(lon, 3)},{'E' if lon >= 0 else 'W'},1,08,0.9,38.0,M,,M,,")
checksum = 0
for ch in body:
    checksum ^= ord(ch)
print(f"${body}*{checksum:02X}")

FAQ

▸Why is my latitude wrong when I put decimal degrees in the sentence?

Because the NMEA coordinate field is not decimal degrees. It is degrees concatenated with decimal minutes — ddmm.mmmm for latitude, dddmm.mmmm for longitude. 37.5665° must be written 3733.9900 (0.5665° × 60 = 33.99′), not 3735.6650 or 37.5665. A receiver fed decimal degrees in that field places the fix tens of kilometres away, and nothing flags it, because the number still parses. This generator does the conversion and shows it next to the sentence.

▸How is the NMEA checksum calculated?

XOR every character between $ and * — exclusive of both — and print the result as two uppercase hex digits after the *. The $ and the * themselves are never included. That is the whole algorithm; it detects single-character corruption but is far weaker than a CRC, which is acceptable because a sentence also has strict framing to fail on.

▸What is the difference between GGA and RMC?

GGA is the fix: position, time, fix quality, satellites in use, HDOP and altitude — but no date and no speed. RMC is the recommended minimum: position, time, date, speed over ground and course — but no altitude and no satellite count. Loggers usually want both, which is why receivers interleave them.

▸What are the fields of an NMEA RMC sentence?

Twelve, in fixed order after the address: UTC time, status (A = valid, V = void), latitude, N/S, longitude, E/W, speed over ground in knots, course over ground in degrees, date (ddmmyy), magnetic variation, variation E/W and mode indicator, followed by the *HH checksum. Example: $GPRMC,023000.00,A,3733.9900,N,12658.6800,E,12.5,084.4,051026,,,A*63. The field table on this page walks through that sentence slot by slot.

▸What do the talker IDs GP, GN, GL, GA and BD mean?

The constellation the fix came from: GP is GPS, GL is GLONASS, GA is Galileo, BD (or GB) is BeiDou, and GN means the fix combined more than one system. A parser should match the sentence type and treat the talker as data — code that hard-matches only $GPGGA breaks the day a multi-constellation receiver starts sending $GNGGA, which is exactly what modern modules do.

▸Can I generate a proprietary or unlisted sentence?

Yes — the custom mode takes any body text, so $PMTK, $PUBX or your own $P… command gets a correct checksum appended. That is most of what a proprietary sentence needs; the field meanings are whatever the vendor defined.

▸Why generate sentences at all?

To test the consumer without the producer. A display, autopilot, PLC or LabVIEW VI that parses NMEA has to handle a receiver that is not on your desk: no fix (quality 0, empty fields), southern and western hemispheres, RTK quality codes, odd HDOP values. Typing those cases into a generator and replaying them over a serial port is faster than driving the hardware into each state — and some states, like RTK float, you cannot produce on demand.

▸Is anything uploaded?

No. The sentence is assembled entirely in your browser.

Related tools