NMEA 0183

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

NMEA 0183 — комбінований стандарт, який визначає як електричні так і функціональні характеристики комунікаційного протоколу для обміну інформацією між пристроями морського електронного обладнання[en], такими як ехолот, гідролокатор, анемометр, гірокомпас, автоматичний рульовий механізм[en], GPS-приймач та багатьма іншими типами обладнання. Стандарт створений та контролюється Національною асоціацією морської електроніки. Він замінив попередні стандарти NMEA 0180 та NMEA 0182.[1] У морських застосуваннях поступовою виходить з вжитку і замінюється новішим стандартом NMEA 2000.

На фізичному рівні стандарт використовує EIA-422, однак майже вся апаратура з виходами NMEA 0183 також здатна працювати з одним портом RS-232. Незважаючи на те, що стандарт передбачає ізоляцію входів і виходів, існує обладнання, де не дотримано цієї вимоги.

Стандарт NMEA 0183 використовує простий послідовний комунікаційний протокол. Передавання даних здійснюється ASCII-символами у вигляді повідомлень-«речень» від одного «промовця» (англ. talker) до багатьох «слухачів» (англ. listener) одночасно. За допомогою використання проміжних повторювачів «промовець» може здійснювати однонаправлену комунікацію з практично необмеженою кількістю «слухачів». Використовуючи мультиплексори, декілька давачів можуть промовляти до одного комп'ютерного порту.

На прикладному рівні стандарт визначає вміст кожного типу «речення», таким чином кожен listener може точно розібрати повідомлення.

Опис стандарту

[ред. | ред. код]

Канальний рівень

[ред. | ред. код]

На канальному рівні використовується конфігурація асинхронного послідовного порту «4800, 8N1», тобто:

Типова бітова швидкість 4800
Бітів даних 8
Біт парності нема
Стопових бітів 1
Узгодження обміну[en] Нема

Різновид стандарту під назвою NMEA-0183HS визначає бітову швидкість 38400. Цей варіант зазвичай використовується в автоматичних ідентифікаційних системах.

Прикладний рівень

[ред. | ред. код]
  • Всі дані представляються текстовими символами ASCII між 0x20 (знак пропуску) до 0x7e (~)
  • Символами, що кодують дані можуть бути усіма символами із вищезгаданого діапазону крім зарезервованих спеціальних символів (див. таблицю)
  • Зарезервованими символами в NMEA0183 є наступні символи:
ASCII Hex Дес Призначення
<CR> 0x0d 13 Символ повернення каретки
<LF> 0x0a 10 Початок нового рядка (string), розділювач закінчення
! 0x21 33 Розділювач який задає початок нової інкапсульованої послідовності
$ 0x24 36 Розділювач, що задає початок повідомлення
* 0x2a 42 Розділювач контрольної суми
, 0x2c 44 Розділювач полів
\ 0x5c 92 Розділювач блоку TAG
^ 0x5e 94 Розділювач для представлення HEX даних за стандартом ISO/IEC 8859-1 (ASCII) символи
~ 0x7e 126 Зарезервовано
  • Максимальна довжина повідомлення 82 символи, що включає початковий символ $ або ! і закінчення <LF>
  • Почаковим символом для кожного повідомлення може бути або $ (для традиційних повідомлень, що мають розділювачі полів) або ! (для повідомлень що мають спеціальну енкапсуляцію в середині)
  • Наступні п'ять символів ідентифікують джерело інформації (два символи) та тип повідомлення (три символи).
  • Всі наступні поля даних розділено символами коми ,.
  • Якщо дані недоступні, відповідне поле залишається порожнім — відсутні символи між двома розділовими знаками (див. приклад повідомлень).
  • Наступним символом, що слідує одразу після останнього поля є зірочка, але воно додається лише якщо присутня чексума.
  • Безпосередньо за зірочкою йде контрольна сума, представлення двозначним шістнадцятковим числом. Контрольна сума обчислюється як побітове виключне АБО ASCII-кодів всіх символів повідомлення між $ та * (не включаючи ці два символи). Згідно офіційної специфікації, контрольна сума не обов'язкова для більшості повідомлень, але вона вимагається, зокрема, для RMA, RMB та RMC.
  • Закінчують повідомлення символи <CR><LF>.

Приклад повідомлення, що інформує про прибуття на точку маршруту має наступний вигляд:

$GPAAM,A,A,0.10,N,WPTNME*32

де:

GP Ідентифікатор джерела (Talker ID — GP для GPS-приймача, GL для GLONASS)
AAM Сигнал прибуття
A Входження у коло прибуття
A Перпендикуляр пройдено
0.10 Радіус кола
N Морських миль
WPTNME Назва точки прибуття
*32 Контрольна сума

Розширення виробників

[ред. | ред. код]

На додаток до стандартного набору NMEA більшість виробників GPS додають у своїх продуктах спеціальні повідомлення для технічного обслуговування та діагностики. Розширені повідомлення починаються з послідовності символів $P (від англ. proprietary). Ці повідомлення не нормуються стандартом.

Приклад повідомлень

[ред. | ред. код]

Приклад отримано з GPS-логгера Tripmate 850. Двосекундний файл записано у Лейксліп[en], Кілдер, Ірландія.

$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43
$GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45

Зверніть увагу на порожні поля, наприклад:

  • У повідомленнях GSV з описом видимих супутників відсутнє поле SNR для супутника 16 і всі дані для супутника 36.
  • Повідомлення GSA з переліком супутників, використовуваних для визначення позиції[en] та величиною погіршення точності, має дванадцять полів для номерів супутників, але лише вісім супутників беруться до уваги, тому чотири поля залишено порожніми.

C-реалізація розрахунку контрольної суми

[ред. | ред. код]

Контрольна сума кожного повідомлення обчислюється як побітове виключне АБО ASCII-кодів всіх символів повідомлення між $ та * (не включаючи ці два символи). Наступний код генерує контрольну суму для рядка, записаного у масив mystring та друкує її у вихідний потік. Для розрахунку взято одне з повідомлень з прикладу вище.

#include <stdio.h>

int checksum(char *s) {
    int c = 0;

    // Пропустити стартовий символ
    if (*s == '$')
        ++s;

    // До кінця рядка або до початку поля контрольної суми
    while(*s != 0 && *s != '*')
        c ^= *s++;

    return c;
}

int main()
{
    char mystring[] = "GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A";

    printf("String: %s\nChecksum: 0x%02X\n", mystring, checksum(mystring));
    return 0;
}

Сумісність

[ред. | ред. код]

Стандарт NMEA 0183 широко підтримується навігаційними та картографічними програмами. Найвідоміші з них:

Статус

[ред. | ред. код]

Стандарти NMEA є комерційними й станом на вересень 2015 року продавалися за ціною від $250 (для членів асоціації — від $165)[3]. Однак, більшість з них доступні з відкритих джерел завдяки зворотній розробці[4][5].

Станом на 2012 рік стандарт NMEA 0183 продовжував розвиватися: версію 4.10 було опубліковано на початку травня 2012 року, перелік помилок — 12 травня того ж року[6].

Новіший стандарт, NMEA 2000, передбачає вищу бітову швидкість та декілька «промовців» (talkers) без використання центрального хаба чи кільцевої буферизації пакетів.

Див. також

[ред. | ред. код]

Примітки

[ред. | ред. код]
  1. Peter Bennett (15.09.1997). The NMEA FAQ (англ.) . Архів оригіналу за 15.02.2014. Процитовано 06.09.2015.
  2. Google Maps for Android. Google. Архів оригіналу за 19 червня 2009. Процитовано 21 жовтня 2013.
  3. Publications and Standards from the National Marine Electronics Association (NMEA) / NMEA 0183. NMEA. November 2008. Архів оригіналу за 15 серпня 2020. Процитовано 16.09.2015.
  4. Проект gpsd
  5. Dale DePriest. Дані протоколу NMEA. Архів оригіналу за 20 жовтня 2020. Процитовано 16.09.2015.
  6. ERRATA # 0183 120512 (PDF). NMEA. Архів оригіналу (PDF) за 17 квітня 2016. Процитовано 21 жовтня 2013.

Посилання

[ред. | ред. код]