Aggiornamento (12 / 06 / 2026): Abbiamo un ampio stock di tutti i nostri prodotti, trovaci anche in e    Come ottenere un preventivo

Descrizione del protocollo e dei messaggi NMEA

Sommario

A protocollo È un insieme di regole che definisce come i dati vengono formattati, trasmessi e interpretati tra due o più dispositivi affinché possano comprendersi reciprocamente.

Pensatela come una lingua con regole grammaticali rigide: sia il mittente che il destinatario devono seguire esattamente le stesse regole, altrimenti il ​​messaggio è privo di significato. Senza protocolli, ogni produttore inventerebbe il proprio formato e i dispositivi di marche diverse non sarebbero in grado di comunicare tra loro.

Il protocollo NMEA-0183 (d'ora in poi NMEA) è lo standard di settore per la tecnologia GNSS.
Abbiamo preparato questa pagina come riferimento per la definizione del protocollo NMEA e per fornire anche una descrizione dei messaggi più comuni. Se ti manca qualche messaggio o trovi qualche errore di battitura, Contattaci e lo sistemeremo 🙂

Messaggio Descrizione Disponibilità
GGADati di posizionamento globale (GPS): posizione, altitudine, qualità del rilevamento e numero di satelliti.Tutti i ricevitori
GLLPosizione geografica: latitudine e longitudine con tempo e statoTutti i ricevitori
GNSDati di fix GNSS — simile a GGA ma supporta più costellazioni (GPS, GLONASS, Galileo...)Tutti i ricevitori
GRSResidui di portata GNSS — residui delle distanze utilizzate nella soluzione di navigazioneTutti i ricevitori
GSAGNSS DOP e satelliti attivi: tipo fisso (2D/3D) e satelliti utilizzatiTutti i ricevitori
GSTStatistiche sull'errore di pseudodistanza GNSS: stime dell'errore di posizione (RMS, latitudine, longitudine, altitudine)Tutti i ricevitori
GSVSatelliti GNSS visibili: numero, elevazione, azimut e intensità del segnale dei satelliti visibiliTutti i ricevitori
HDTDirezione vera — rotta effettiva della nave rispetto al nord geograficoSeptentrio Mosaic-H simpleRTK3B Heading
INSPVAXADati di fusione dei sensori: posizione, velocità, assetto integrati e relativi errori stimati.Unicore UM981 simpleRTK3B Fusion
PUBX,00Dati di posizione: latitudine, longitudine, altitudine e qualità del fix (u-blox dispositivi)Tutti u-blox Ricevitori
PUBX,04Ora del giorno — Ora UTC e dati dell'orologiou-blox dispositivi)Tutti u-blox Ricevitori
RMCDati GNSS minimi raccomandati: posizione, velocità, rotta e data.Tutti i ricevitori
REDVelocità di virata: velocità di rotazione dell'imbarcazione in gradi al minuto.Septentrio Mosaic-H simpleRTK3B Heading
VTGRotta e velocità rispetto al terreno: rotta e velocità in nodi e km/hTutti i ricevitori
Stati Uniti d'AmericaOra e data: ora UTC, giorno, mese, anno e fuso orario locale.Tutti i ricevitori
Nessun risultato trovato.

Struttura del messaggio NMEA

Ogni messaggio inizia con un $ un simbolo seguito da un codice breve che identifica il tipo di dati che contiene (vedi tabella nella sezione successiva).
Il ricevitore quindi inserisce tutti i campi dati separati da virgole — latitudine, longitudine, altitudine, ora, numero di satelliti, ecc. — e termina il messaggio con un checksum, che è un piccolo numero che consente al dispositivo ricevente di verificare che i dati non siano stati corrotti durante la trasmissione.
Il messaggio termina con un'interruzione di riga e il messaggio successivo inizia immediatamente dopo.

L'immagine seguente riassume il processo di generazione di un messaggio NMEA.

Struttura del messaggio NMEA – infografiche estratte da u-blox documentazione

Generazione del checksum NMEA

Esempi di codice per generare il checksum NMEA in base a un payload 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)
    
   

Validazione del checksum NMEA

Se si desidera verificare se un messaggio NMEA è legittimo o meno, utilizzare il codice di esempio riportato di seguito:

    
     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"
    
   

Calcolatore online del checksum NMEA

$ *--

Checksum (esadecimale)

--

Checksum (decimale)

--

lunghezza del carico utile

--

Frase completa

-

Verificare una frase

Hai domande o richieste?
Contattaci! Risponderemo <24 ore!

Icona
Contatti ArduSimple
Chiudi
ArduSimple – Apparecchiature e soluzioni di rilevamento RTK ad alta precisione, semplificate

Vuoi saperne di più su GPS e RTK?

Se in questo momento sei impegnato, i nostri ingegneri possono inviarti 3 brevi e-mail, spiegandoti tutto ciò che devi sapere per iniziare il tuo progetto.