Atualização (12/06/2026): Temos bastante estoque de todos os nossos produtos, encontre-nos também em e    Como obter um orçamento

Descrição do protocolo e da mensagem NMEA

Índice

A protocolo É um conjunto de regras que define como os dados são formatados, transmitidos e interpretados entre dois ou mais dispositivos para que possam se entender.

Imagine uma língua com regras gramaticais rígidas — tanto o remetente quanto o destinatário devem seguir exatamente as mesmas regras, caso contrário a mensagem não faz sentido. Sem protocolos, cada fabricante criaria seu próprio formato e dispositivos de marcas diferentes seriam incapazes de se comunicar entre si.

O protocolo NMEA-0183 (doravante NMEA) é o padrão da indústria para a tecnologia GNSS.
Preparamos esta página como referência para a definição do protocolo NMEA e também para fornecer uma descrição das mensagens mais comuns. Se você não encontrar alguma mensagem ou algum erro de digitação, entre em contato connosco E nós vamos resolver isso 🙂

Mensagem Descrição Disponibilidade
GGADados de localização do Sistema de Posicionamento Global (GPS) — posição, altitude, qualidade da localização e número de satélites.Todos os receptores
GLLPosição geográfica — latitude e longitude com hora e statusTodos os receptores
GNSDados de fixação GNSS — semelhante ao GGA, mas suporta múltiplas constelações (GPS, GLONASS, Galileo...)Todos os receptores
GRSResíduos de alcance GNSS — resíduos dos alcances usados ​​na solução de navegaçãoTodos os receptores
GSAGNSS DOP e satélites ativos — tipo de sinal (2D/3D) e satélites utilizadosTodos os receptores
GSTEstatísticas de erro de pseudodistância GNSS — estimativas de erro de posição (RMS, latitude, longitude, altitude)Todos os receptores
GSVSatélites GNSS visíveis — número, elevação, azimute e intensidade do sinal dos satélites visíveisTodos os receptores
HDTRumo verdadeiro — rumo real da embarcação em relação ao norte verdadeiro.Septentrio Mosaic-H simpleRTK3B Heading
INSPVAXADados de fusão de sensores — posição, velocidade, atitude integradas e seus erros estimados.Unicore UM981 simpleRTK3B Fusion
PUBX,00Dados de posição — latitude, longitude, altitude e qualidade da fixação (u-blox dispositivos)Todas as u-blox receptores
PUBX,04Hora do dia — Datas de hora e relógio UTC (u-blox dispositivos)Todas as u-blox receptores
RMCDados GNSS específicos mínimos recomendados — posição, velocidade, rumo e data.Todos os receptores
REDTaxa de rotação — velocidade de rotação da embarcação em graus por minutoSeptentrio Mosaic-H simpleRTK3B Heading
VTGRota sobre o solo e velocidade em relação ao solo — rumo e velocidade em nós e km/hTodos os receptores
EUAHora e data — Hora UTC, dia, mês, ano e fuso horário localTodos os receptores
Nenhum resultado encontrado.

Estrutura da mensagem NMEA

Cada mensagem começa com um $ sinal seguido de um código curto que identifica o tipo de dados que contém (consulte a tabela na próxima seção).
O receptor preenche então todos os campos de dados separados por vírgulas — latitude, longitude, altitude, hora, número de satélites, etc. — e finaliza a mensagem com um ponto. checksum, que é um número pequeno que permite ao dispositivo receptor verificar se os dados não foram corrompidos durante a transmissão.
A mensagem termina com uma quebra de linha e a próxima mensagem começa imediatamente em seguida.

A imagem abaixo resume como uma mensagem NMEA é gerada.

Estrutura da mensagem NMEA – infográfico extraído de u-blox documentação

Geração de checksum NMEA

Exemplos de código para gerar o checksum NMEA com base em uma carga útil 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)
				
			

Validação de checksum NMEA

Se você deseja validar se uma mensagem NMEA é legítima ou não, use o código de exemplo abaixo:

				
					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"
				
			

Calculadora online de checksum NMEA

$ *--

Soma de verificação (hexadecimal)

--

Soma de verificação (decimal)

--

comprimento da carga útil

--

Frase completa

-

Verifique uma frase

Tem alguma dúvida ou pedido?
Contate-nos! Responderemos <24 horas!

ícone
Contato ArduSimple
Fechar
ArduSimple – Equipamentos e soluções de levantamento topográfico RTK de alta precisão simplificados

Quer saber mais sobre GPS e RTK?

Se você estiver ocupado no momento, nossos engenheiros podem enviar três e-mails curtos explicando tudo o que você precisa saber para iniciar seu projeto.