Aktualizace (16 / 06 / 2026): Všech našich produktů máme dostatek skladem, najdete nás také v a    Jak získat cenovou nabídku

Protokol NMEA a popis zprávy

Obsah

A protokol je sada pravidel, která definují, jak jsou data formátována, přenášena a interpretována mezi dvěma nebo více zařízeními, aby si vzájemně rozuměla.

Představte si to jako jazyk s přísnými gramatickými pravidly – ​​odesílatel i příjemce musí dodržovat úplně stejná pravidla, jinak je zpráva bezvýznamná. Bez protokolů by si každý výrobce vymyslel vlastní formát a zařízení od různých značek by spolu nemohla komunikovat.

Protokol NMEA-0183 (dále jen NMEA) je průmyslovým standardem pro technologii GNSS.
Tuto stránku jsme připravili jako referenci pro definici protokolu NMEA a také pro popis nejčastějších zpráv. Pokud vám nějaká zpráva unikne nebo najdete nějaký překlep, kontaktujte nás a my to opravíme 🙂

Zpráva Popis dostupnost
GGAData o fixaci globálního pozičního systému – poloha, nadmořská výška, kvalita fixace a počet satelitůVšichni přijímači
GLLZeměpisná poloha – zeměpisná šířka a délka s časem a stavemVšichni přijímači
GNSData o fixaci GNSS – podobná GGA, ale podporuje více souhvězdí (GPS, GLONASS, Galileo...)Všichni přijímači
GRSZbytky dosahu GNSS – zbytky dosahů použitých v navigačním řešeníVšichni přijímači
GSAGNSS DOP a aktivní satelity – typ fixu (2D/3D) a použité satelityVšichni přijímači
GSTStatistika chyb pseudovzdáleností GNSS — odhady chyb polohy (RMS, zeměpisná šířka, délka, nadmořská výška)Všichni přijímači
GSVZobrazené satelity GNSS – počet, nadmořská výška, azimut a síla signálu viditelných satelitůVšichni přijímači
HDTSkutečný směr – skutečný směr plavidla vzhledem k skutečnému severuSeptentrio Mosaic-H simpleRTK3B Heading
INSPVAXAData fúze senzorů – integrovaná poloha, rychlost, orientace a jejich odhadované chybyUnicore UM981 simpleRTK3B Fusion
PUBX,00Údaje o poloze – zeměpisná šířka, délka, nadmořská výška a kvalita fixu (u-blox zařízení)Vše u-blox přijímače
PUBX,04Denní čas — čas a hodiny UTC (u-blox zařízení)Vše u-blox přijímače
RMCDoporučené minimální specifické údaje GNSS – poloha, rychlost, kurz a datumVšichni přijímači
REDRychlost otáčení – rychlost otáčení plavidla ve stupních za minutuSeptentrio Mosaic-H simpleRTK3B Heading
VTGKurz vzhledem k zemi a rychlost od země – dráha a rychlost v uzlech a km/hVšichni přijímači
USAČas a datum — čas UTC, den, měsíc, rok a místní časové pásmoVšichni přijímači
Nebyly nalezeny žádné výsledky.

Struktura zpráv NMEA

Každá zpráva začíná slovem $ znak následovaný krátkým kódem, který identifikuje typ dat, která obsahuje (viz tabulka v další části).
Přijímač poté vyplní všechna datová pole oddělená čárkami – zeměpisnou šířku, délku, nadmořskou výšku, čas, počet satelitů atd. – a zprávu zakončí slovem kontrolní součet, což je malé číslo, které umožňuje přijímajícímu zařízení ověřit, zda data nebyla během přenosu poškozena.
Zpráva končí zalomením řádku a bezprostředně poté začíná další zpráva.

Obrázek níže shrnuje, jak se generuje zpráva NMEA.

Struktura zpráv NMEA – infografika extrahovaná z u-blox dokumentace

Generování kontrolního součtu NMEA

Příklady kódu pro generování kontrolního součtu NMEA na základě datové zátěže NMEA:

    
     def nmea_checksum(payload):
    checksum = 0
    for char in payload:
        checksum ^= ord(char)
    return f"{checksum:02X}"
    
# Pass only the part between $ and *
print(nmea_checksum("GNGGA,092725.00,4717.11399,N,00833.91986,E,1,08,1.01,499.6,M,48.0,M,,"))
# Returns: '4E' (or whatever the correct checksum is)
    
   

Ověření kontrolního součtu NMEA

Pokud chcete ověřit, zda je zpráva NMEA platná, použijte níže uvedený příklad kódu:

    
     def validate_nmea(sentence):
    sentence = sentence.strip()
    if not sentence.startswith('$') or '*' not in sentence:
        return False
    
    payload, claimed = sentence[1:].split('*', 1)
    
    checksum = 0
    for char in payload:
        checksum ^= ord(char)
    
    return f"{checksum:02X}" == claimed.strip()[:2].upper()
    
print(validate_nmea("$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"))  # True
print(validate_nmea("$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*FF"))  # False
print(validate_nmea("invalid sentence"))  # False
    
   
    
     #include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>

bool validate_nmea(const char *sentence) {
    if (!sentence || *sentence != '$') return false;

    const char *star = strchr(sentence, '*');
    if (!star || strlen(star) < 3) return false;

    uint8_t checksum = 0;
    const char *p = sentence + 1;
    while (p != star) {
        checksum ^= (uint8_t)*p++;
    }

    uint8_t claimed;
    if (sscanf(star + 1, "%2hhX", &claimed) != 1) return false;

    return checksum == claimed;
}

int main() {
    printf("%d\n", validate_nmea("$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A")); // 1
    printf("%d\n", validate_nmea("$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*FF")); // 0
    printf("%d\n", validate_nmea(NULL));  // 0
    printf("%d\n", validate_nmea("invalid")); // 0
    return 0;
}
    
   
    
     function validateNmea(sentence) {
    sentence = sentence.trim();
    if (!sentence.startsWith('$') || !sentence.includes('*')) return false;

    const starIdx = sentence.indexOf('*');
    const payload = sentence.slice(1, starIdx);
    const claimed = sentence.slice(starIdx + 1, starIdx + 3).toUpperCase();

    if (claimed.length < 2 || !/^[0-9A-F]{2}$/.test(claimed)) return false;

    let checksum = 0;
    for (let i = 0; i < payload.length; i++) {
        checksum ^= payload.charCodeAt(i);
    }

    return checksum.toString(16).toUpperCase().padStart(2, '0') === claimed;
}

validateNmea("$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"); // true
validateNmea("$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*FF"); // false
validateNmea("invalid"); // false
    
   
    
     #include <stdint.h>
#include <string.h>
#include <stdio.h>

uint8_t nmea_checksum(const char *sentence) {
    // Skip leading '$' if present
    if (*sentence == '$') sentence++;
    
    uint8_t checksum = 0;
    while (*sentence && *sentence != '*') {
        checksum ^= (uint8_t)*sentence++;
    }
    return checksum;
}

int main() {
    const char *sentence = "$GNGGA,092725.00,4717.11399,N,00833.91986,E,1,08,1.01,499.6,M,48.0,M,,";
    printf("Checksum: %02X\n", nmea_checksum(sentence));
    return 0;
}
    
   
    
     function nmeaChecksum(sentence) {
    // Strip leading $ and everything from * onwards
    sentence = sentence.replace(/^\$/, '').split('*')[0];
    
    let checksum = 0;
    for (let i = 0; i < sentence.length; i++) {
        checksum ^= sentence.charCodeAt(i);
    }
    return checksum.toString(16).toUpperCase().padStart(2, '0');
}

nmeaChecksum("GNGGA,092725.00,4717.11399,N,00833.91986,E,1,08,1.01,499.6,M,48.0,M,,");
// Returns: "4E"
    
   

Online kalkulačka kontrolního součtu NMEA

$ *--

Kontrolní součet (hex)

--

Kontrolní součet (desetinný)

--

Délka užitečného zatížení

--

Celá věta

-

Ověření věty

Máte nějaké dotazy nebo požadavky?
Kontaktujte nás! Odpovíme <24 hodin!

Ikona
Kontakt ArduSimple
zavřít
ArduSimple – vysoce přesné RTK geodetické vybavení a řešení zjednodušeně

Chcete se dozvědět více o GPS a RTK?

Pokud máte právě teď málo práce, naši technici vám mohou poslat 3 krátké e-maily s vysvětlením všeho, co potřebujete vědět k zahájení projektu.