Протокол GPS NMEA 0183: основы работы с сообщениями
Разбираем протокол GPS NMEA 0183: структуру предложений, типы сообщений и то, какие платы Arduino умеют с ним работать.
С помощью смартфона мы можем определить своё местоположение с точностью до нескольких метров. Это стало возможным благодаря встроенному чипу, который общается с группой спутников на орбите — такая система называется глобальной навигационной спутниковой системой (GNSS). GNSS — это группа (или «созвездие») из 24 и более спутников, которые совместно обеспечивают позиционирование и синхронизацию времени в любой точке планеты при любых погодных условиях.
Американская система глобального позиционирования (GPS) — самая распространённая GNSS в мире, но существуют и другие:
BeiDou Navigation Satellite System (BDS) — Китай. Navigation Indian Constellation (NavIC) — Индия. European Global Navigation System (Galileo) — Европа. Quasi-Zenith Satellite System (QZSS) — Япония. * Globalnaya Navigazionnaya Sputnikovaya Sistema (GLONASS) — Россия.
Для вычисления координат в трёх измерениях и поправки часов приёмника нужно не менее четырёх спутников. Чем больше спутников видит приёмник, тем точнее данные о положении, скорости и времени.
На практике слово «GPS» часто используют как общий термин для любого оборудования и процессов, связанных с определением координат через GNSS.
GPS-приёмники общаются с внешним миром на нескольких «языках» — протоколах, как стандартных, так и фирменных (проприетарных). Данные передаются либо в бинарном виде (нули и единицы), либо в кодировке ASCII. Среди всех стандартов, применяемых в GPS-приёмниках, NMEA 0183 является наиболее широко используемым.
NMEA — аббревиатура от National Marine Electronics Association. Ассоциация была основана в 1957 году дилерами электроники с целью повышения безопасности и технического уровня морской электроники через обучение специалистов и стандартизацию интерфейсов. Протокол NMEA 0183 был принят в 1983 году изначально для стыковки морского оборудования, но со временем распространился и на наземную электронику [3].
NMEA 0183 — простой протокол, в котором данные передаются в виде ASCII-строк, или «предложений» (sentences), от одного «говорящего» (talker) сразу нескольким «слушателям» (listeners). Ещё одна особенность: протокол использует электрический стандарт RS-422, хотя совместим и с RS-232 [3]. Параметры последовательного соединения:
Скорость: 4800 бод. Биты данных: 8. Чётность: отсутствует. Стоп-бит: отсутствует.
«Говорящим» в NMEA 0183 может быть, например, спутник, эхолот или компас, а «слушателем» — картплоттер, радар или GPS-приёмник вроде того, что используется в Arduino MKR GPS Shield.
Нередко протокол NMEA 0183 вызывает путаницу, потому что существует не одно, а множество разных «предложений» — каждое со своими возможностями и назначением. Чтобы разобраться в них, начнём со структуры.
Структура предложений GPS NMEA 0183
Каждое предложение NMEA 0183 начинается со знака $ и заканчивается символом возврата каретки и переводом строки; поля данных внутри предложения разделяются запятыми:
$aaaaa,df1,df2,df3*hh<CR><LF>
Вслед за знаком $ всегда идёт пятисимвольное поле адреса, а hh — двузначная шестнадцатеричная контрольная сумма. Максимальная длина предложения NMEA 0183 — 80 символов плюс возврат каретки и перевод строки.
Разберём пример реального предложения GPS NMEA 0183:
$GPGGA,181908.00,3404.7041778,N,07044.3966270,W,4,13,1.00,495.144,M,29.200,M,0.10,0000,*40
Базовая структура предложения NMEA 0183 — поля разделены запятыми, первое поле — идентификатор сообщения, последнее — контрольная сумма.
В этом предложении можно выделить следующие данные:
GP — обозначает позицию GPS (GL — GLONASS). 181908.00 — временна́я метка (UTC: часы, минуты, секунды). 3404.7041778 — широта в формате DDMM.MMMMM. N — северная широта. 07044.3966270 — долгота в формате DDDMM.MMMMM. W — западная долгота. 4 — индикатор качества (точности). 13 — количество спутников, использованных для вычисления координат. 1.00 — горизонтальное ухудшение точности (HDOP). 495.144 — высота GPS-антенны. M — единица высоты (метры или футы). 29.200 — геоидальное разделение. M — единица геоидального разделения (метры или футы). 1.0 — возраст поправки (при наличии). 0000 — ID станции коррекции (при наличии). *40 — контрольная сумма.
$GPGGA — базовое и наиболее распространённое предложение NMEA 0183. Существуют и другие предложения, которые дополняют или расширяют этот набор данных.

Распространённые предложения GPS NMEA 0183
Ниже в таблице описаны наиболее часто встречающиеся предложения протокола NMEA 0183, связанные с GPS:
| Sentence | Description |
|---|---|
| $GPGGA | Time, position, fix type data. |
| $GPGLL | Latitude, longitude, UTC time of position fix and status. |
| $GPGSA | GPS receiver operating mode, satellites used in the position solution, DOP values. |
| $GPGSV | Number of satellites in view, satellite ID numbers, elevation, azimuth, SNR values. |
| $GPRMC | Time, date, position, course, speed data. |
| $GPVTG | Course, speed information relative to the ground. |
Обратите внимание: предложение $GPRMC является ключевым — оно содержит минимально необходимый набор навигационных данных, которые должен предоставлять любой GNSS-приёмник.
Чтобы получить данные о позиции, достаточно записывать хотя бы одно из следующих предложений: $GPGGA, $GPGLL, $GPRMC.
Практические замечания
При работе с NMEA 0183 на Arduino важно учитывать несколько моментов:
- Пустые поля — если данные недоступны (например, нет фиксации спутников), соответствующее поле в предложении остаётся пустым, но запятые-разделители сохраняются. Парсер должен уметь обрабатывать такие ситуации.
- Контрольная сумма — вычисляется как XOR всех байт между
$и*. Всегда проверяйте её перед использованием данных. - Время фиксации — после включения приёмник может несколько минут искать спутники (холодный старт). В это время поля координат будут пустыми.
- Формат координат — широта и долгота передаются в формате DDMM.MMMMM, а не в десятичных градусах. Не забудьте выполнить преобразование, если нужны десятичные градусы:
DD + MM.MMMMM / 60.
Arduino® и протокол GPS NMEA 0183
Платы семейства Arduino MKR могут работать с протоколом NMEA 0183 с помощью Arduino MKR GPS Shield и Arduino_MKR GPS library.

Шилд Arduino MKR GPS на базе модуля u-blox SAM-M8Q.
MKR GPS Shield построен на модуле u-blox SAM-M8Q GNSS. Этот модуль одновременно принимает сигналы до трёх GNSS (GPS, Galileo и GLONASS) и поддерживает SBAS и QZSS. Модуль способен распознавать несколько созвездий одновременно и обеспечивает высокую точность позиционирования даже в городских условиях с частичным перекрытием неба или при слабом сигнале.
MKR GPS Shield предназначен для установки поверх плат семейства MKR, но его также можно подключить к другим платам Arduino на базе SAM D через пины UART или I2C (библиотека Arduino_MKR GPS поддерживает оба протокола связи).
Подробную документацию по шилду можно найти здесь: here.
Уроки по MKR GPS Shield
Если хотите научиться работать с MKR GPS Shield, изучите следующие уроки:
Источники
[1] "SAM-M8Q Data Sheet", u-blox.com, 2020. [Online]. Available: https://www.u-blox.com/en/docs/UBX-16012619. [Accessed: 05- Oct- 2021]. [2] "u-blox 8 / u-blox M8 Receiver Description", u-blox.com, 2021. [Online]. Available: https://www.u-blox.com/en/docs/UBX-16018358. [Accessed: 05- Oct- 2021]. * [3] "NMEA 0183 Interface Standard", NMEA, 2021. [Online]. Available: https://www.nmea.org/nmea-0183.html. [Accessed: 05- Oct- 2021].