Обновление (12 / 06 / 2026): У нас есть большой запас всех наших продуктов, найти нас также в и    Как получить расценки

Описание протокола и сообщения NMEA

Содержание

A протокол Это набор правил, определяющих, как данные форматируются, передаются и интерпретируются между двумя или более устройствами, чтобы они могли понимать друг друга.

Представьте это как язык со строгими грамматическими правилами — и отправитель, и получатель должны следовать одним и тем же правилам, иначе сообщение бессмысленно. Без протоколов каждый производитель изобрел бы свой собственный формат, и устройства разных марок не смогли бы взаимодействовать друг с другом.

Протокол NMEA-0183 (далее NMEA) является отраслевым стандартом для технологии GNSS.
Мы подготовили эту страницу в качестве справочника по определению протокола NMEA, а также для предоставления описания наиболее часто используемых сообщений. Если вы пропустили какое-либо сообщение или обнаружили опечатку, Свяжитесь с нами И мы это исправим 🙂

Сообщение Описание Доступность
GGAДанные системы глобального позиционирования (GPS) — местоположение, высота, качество определения местоположения и количество спутников.Все приемники
GLLГеографическое положение — широта и долгота с указанием времени и статуса.Все приемники
GNSДанные о местоположении GNSS — аналогичны GGA, но поддерживают несколько спутниковых систем (GPS, GLONASS, Galileo...)Все приемники
GRSОстаточные значения дальности GNSS — остаточные значения дальности, использованной в навигационном решении.Все приемники
GSAGNSS DOP и активные спутники — тип фиксации (2D/3D) и используемые спутники.Все приемники
GSTСтатистика ошибок псевдодальности GNSS — оценки ошибок определения местоположения (среднеквадратичное отклонение, широта, долгота, высота).Все приемники
GSVСпутники GNSS в поле зрения — количество, угол места, азимут и уровень сигнала видимых спутников.Все приемники
HDTИстинный курс — фактический курс судна относительно истинного севера.Septentrio Mosaic-H simpleRTK3B Heading
ИНСПАВАКСАДанные, полученные методом слияния данных с датчиков — интегрированные данные о положении, скорости, ориентации и их оценочные погрешности.Unicore UM981 simpleRTK3B Fusion
PUBX,00Данные о местоположении — широта, долгота, высота и качество определения местоположения (u-blox устройства)Все u-blox приемники
PUBX,04Время суток — данные о времени и часах по UTC (Всемирному координированному времени).u-blox устройства)Все u-blox приемники
RMCРекомендуемый минимальный набор необходимых данных GNSS: местоположение, скорость, курс и дата.Все приемники
REDСкорость вращения — скорость вращения судна в градусах в минуту.Septentrio Mosaic-H simpleRTK3B Heading
VTGКурс относительно земли и скорость относительно земли — траектория и скорость в узлах и км/ч.Все приемники
Соединенные Штаты АмерикиВремя и дата — время UTC, день, месяц, год и местный часовой пояс.Все приемники
Результатов не найдено.

Структура сообщения NMEA

Каждое сообщение начинается с $ Знак, за которым следует короткий код, идентифицирующий тип содержащихся в нем данных (см. таблицу в следующем разделе).
Затем получатель заполняет все поля данных, разделенные запятыми — широту, долготу, высоту, время, количество спутников и т. д. — и завершает сообщение. контрольная суммаЭто небольшое число, позволяющее принимающему устройству убедиться в том, что данные не были повреждены во время передачи.
Сообщение заканчивается переносом строки, и следующее сообщение начинается сразу после него.

На приведенном ниже рисунке наглядно показано, как генерируется сообщение NMEA.

Структура сообщения NMEA – инфографика, извлеченная из u-blox документации

генерация контрольной суммы NMEA

Примеры кода для генерации контрольной суммы NMEA на основе данных 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)
    
   

Проверка контрольной суммы NMEA

Чтобы проверить подлинность сообщения NMEA, воспользуйтесь приведенным ниже примером кода:

    
     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"
    
   

Онлайн-калькулятор контрольной суммы NMEA

$ * -

Контрольная сумма (шестнадцатеричная)

--

Контрольная сумма (в десятичном формате)

--

Длина полезной нагрузки

--

Полное предложение

-

Проверьте правильность предложения.

Есть вопросы или пожелания?
Связаться с нами! Мы ответим <24 часов!

Значок
Контакты ArduSimple
Закрыто
ArduSimple – Высокоточное RTK-оборудование и решения для геодезических работ, упрощенные в использовании

Хотите узнать больше о GPS и RTK?

Если вы сейчас заняты, наши инженеры могут отправить вам 3 коротких электронных письма, в которых подробно объяснят все, что вам нужно знать для начала вашего проекта.