КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Парсер протокола NMEA

Исходники изображение:
Библиотеки:

Общие сведения:

GPS-модули отправляют данные по шине UART в виде текстовых сообщений.

Текстовые сообщения формируются в соответствии с протоколом NMEA 0183 (от «National Marine Electronics Association») - это стандарт определяющий текстовый протокол связи навигационного оборудования.

Сообщения NMEA передаваемые GPS-модулем могут состоять из одной или нескольких строк.

Описание состава строк протокола NMEA 0183:

Каждая строка начинается символом '$' и заканчивается двумя символами контрольной суммы.

После символа '$' следуют два символа определяющие источник получения данных:

  • "GP" - информация получена от спутников GPS (США).
  • "GL" - информация получена от спутников Глонасс (Россия).
  • "GA" - информация получена от спутников Galileo (Европа).
  • "BD" - информация получена от спутников Beidou (Китай).
  • "GQ" - информация получена от спутников QZSS (Япония).
  • "GN" - информация получена от спутников разных навигационных систем.

После двух символов источника получения данных следуют три символа идентификатора строки определяющего её состав (ниже перечислены только те идентификаторы которые определяются парсером iarduino_GPS_NMEA):

  • "GGA" - Данные о последнем зафиксированном местоположении.
  • "GLL" - Географические координаты.
  • "GSA" - Информация об активных спутниках (участвующих в позиционировании).
  • "GSV" - Информация о всех наблюдаемых спутниках.
  • "RMC" - Рекомендуемый минимум навигационных данных.
  • "VTG" - Скорость и курс относительно земли.
  • "ZDA" - Дата и время.
  • "DHV" - Информация о скорости движения GNSS приемника.
  • "GST" - Статистика ошибок позиционирования.
  • "TXT" - Текстовое сообщение.

После идентификатора следуют данные состоящие из параметров, разделённые запятыми. Количество и состав параметров зависят от идентификатора.

После данных следует символ '*', а за ним два символа контрольной суммы. Контрольная сумма представляет из себя шестнадцатиричное представление результата операции XOR всех байтов символов строки, находящихся между символами '$' и '*' не включая их.

Завершают строку символы '\r' и '\n'.

Пример сообщения NMEA 0183:

$GNGGA,094810.000,5547.94084,N,03730.27293,E,1,04,4.5,180.0,M,0.0,M,,*72
$GNGLL,5547.94084,N,03730.27293,E,094810.000,A,A*4B
$GNGSA,A,3,12,24,25,32,,,,,,,,,6.3,4.5,4.4,1*36
$GNGSA,A,3,  ,  ,  ,  ,,,,,,,,,6.3,4.5,4.4,2*36
$GPGSV,3,1,11,02,29,150,13,03,08,029,,06,40,116,,12,62,276,22,0*68
$GPGSV,3,2,11,14,15,330,15,17,29,056,,19,50,064,,22,05,006,,0*63
$GPGSV,3,3,11,24,57,200,26,25,29,278,37,32,23,308,17,0*5F
$BDGSV,1,1,00,0*74
$GLGSV,3,1,09,74,55,310,35,66,10,014,,82,28,035,,73,80,117,,0*7C
$GLGSV,3,2,09,80,15,126,,65,18,314,27,84,32,185,,83,69,089,,0*75
$GLGSV,3,3,09,72,07,273,,0*44
$GNRMC,094810.000,A,5547.94084,N,03730.27293,E,0.25,50.34,260420,,,A,V*31
$GNVTG,50.34,T,,M,0.25,N,0.46,K,A*14
$GNZDA,094810.000,26,04,2020,00,00*4C
$GPTXT,01,01,01,ANTENNA OK*35

Состав сообщения NMEA 0183 зависит от настроек GPS-модуля.

С подробным описанием протокола NMEA 0183 можно ознакомиться на странице Wiki - Описание протокола NMEA 0183.

Примеры:

Для получения данных из сообщений NMEA 0183 отправляемых GPS-модулями, нами разработана библиотека iarduino_GPS_NMEA, которая позволяет преобразовать текстовую информацию поступающую по шине UART в числа определяющие координаты, дату, время, скорость, курс и информацию о спутниках.

Библиотека iarduino_GPS_NMEA только парсит данные получаемые по шине UART, но не работает с конкретным GPS-модулем, как это делает библиотека iarduino_GPS_ATGM336 для настройки работы Trema GPS модуля ATGM336. По этому примеры ниже являются универсальными для всех GPS-модулей передающих информацию по шине UART используя протокол NMEA 0183.

Инициализация получения данных по протоколу NMEA 0183:

Пример инициализации получения и расшифровки данных от GPS-модуля подключённого по аппаратной шине UART (в примере используются шина UART-1 Arduino:

#include <iarduino_GPS_NMEA.h>                    //  Подключаем библиотеку для расшифровки строк протокола NMEA получаемых по UART.
iarduino_GPS_NMEA gps;                            //  Объявляем объект gps для работы с функциями и методами библиотеки iarduino_GPS_NMEA.
                                                  //
void setup(){                                     //
     Serial.begin(9600);                          //  Инициируем работу с аппаратной шиной UART для вывода данных в монитор последовательного порта на скорости 9600 бит/сек.
     Serial1.begin(9600);                         //  Инициируем работу с аппаратной шиной UART для получения данных от GPS модуля на скорости 9600 бит/сек.
     gps.begin(Serial1);                          //  Инициируем расшифровку строк NMEA указав объект используемой шины UART.
}                                                 //
                                                  //
// Место для кода функции loop() из примеров ниже //

Пример инициализации получения и расшифровки данных от GPS-модуля подключённого по программной шине UART (в примере используются выводы D5 и D6 Arduino:

const uint8_t pinRX = 5;                          //  Определяем вывод RX (программного UART) на плате Arduino к которому подключён вывод TX модуля. Номер вывода можно изменить.
const uint8_t pinTX = 6;                          //  Определяем вывод TX (программного UART) на плате Arduino к которому подключён вывод RX модуля. Номер вывода можно изменить.
                                                  //
#include <SoftwareSerial.h>                       //  Подключаем библиотеку для работы с программным UART, до подключения библиотеки iarduino_GPS_NMEA.
#include <iarduino_GPS_NMEA.h>                    //  Подключаем библиотеку для расшифровки строк протокола NMEA получаемых по UART.
                                                  //
SoftwareSerial    SerialGPS(pinRX, pinTX);        //  Объявляем объект SerialGPS для работы с функциями и методами библиотеки SoftwareSerial, указав выводы RX и TX Arduino.
iarduino_GPS_NMEA gps;                            //  Объявляем объект gps для работы с функциями и методами библиотеки iarduino_GPS_NMEA.
                                                  //
void setup(){                                     //
     Serial.begin(9600);                          //  Инициируем работу с аппаратной шиной UART для вывода данных в монитор последовательного порта на скорости 9600 бит/сек.
     SerialGPS.begin(9600);                       //  Инициируем работу с программной шиной UART для получения данных от GPS модуля на скорости 9600 бит/сек.
     gps.begin(SerialGPS);                        //  Инициируем расшифровку строк NMEA указав объект используемой шины UART.
}                                                 //
                                                  //
// Место для кода функции loop() из примеров ниже //

Получение координат:

Пример выводит координаты широты и долготы в градусах.

// Место для кода инициализации из примеров выше  //  Для аппаратной или программной шины UART.
                                                  //
void loop(){                                      //
//   Читаем данные:                               //  Чтение может занимать больше 1 секунды.
     gps.read();                                  //  Функцию можно вызвать с указанием массива для получения данных о спутниках.
//   Проверяем достоверность координат:           //
     if(gps.errPos){                              //  Если данные не прочитаны (gps.errPos=1) или координаты недостоверны (gps.errPos=2), то ...
       Serial.println("Координаты недостоверны"); //  Выводим сообщение об ошибке.
       delay(2000); return;                       //  Ждём 2 секунды и выполняем функцию loop() с начала.
     }                                            //
//   Выводим текущие координаты:                  //
     Serial.print("Ш: "); Serial.print(gps.latitude ,5); Serial.print("°, ");
     Serial.print("Д: "); Serial.print(gps.longitude,5); Serial.print("°.\r\n");
}                                                 //

До кода функции loop() необходимо указать код инициализации GPS-модуля, для аппаратной или программной шины UATR, по которой подключён GPS-модуль.

Для работы примера, в сообщениях NMEA 0183, отправляемых GPS модулем, должна присутствовать строка с идентификатором GGA, или GLL, или RMC.

Получение скорости и курса:

Пример выводит скорость в км/ч и курс в градусах.

// Место для кода инициализации из примеров выше  //  Для аппаратной или программной шины UART.
                                                  //
void loop(){                                      //
//   Читаем данные:                               //  Чтение может занимать больше 1 секунды.
     gps.read();                                  //  Функцию можно вызвать с указанием массива для получения данных о спутниках.
//   Проверяем достоверность скорости и курса:    //
     if(gps.errCrs){                              //  Если данные не прочитаны (gps.errCrs=1) или скорость и курс недостоверны (gps.errCrs=2), то ...
       Serial.println("Скорость недостоверна");   //  Выводим сообщение об ошибке.
       delay(2000); return;                       //  Ждём 2 секунды и выполняем функцию loop() с начала.
     }                                            //
//   Выводим текущие скорость и курс:             //
     Serial.print("Скорость: "); Serial.print(gps.speed ); Serial.print("км/ч. ");
     Serial.print("Курс: "    ); Serial.print(gps.course); Serial.print("°.\r\n");
}                                                 //

До кода функции loop() необходимо указать код инициализации GPS-модуля, для аппаратной или программной шины UATR, по которой подключён GPS-модуль.

Для работы примера, в сообщениях NMEA 0183, отправляемых GPS модулем, должна присутствовать строка с идентификатором RMC, или VTG.

Получение ссылки с точкой на карте Yandex:

// Место для кода инициализации из примеров выше  //  Для аппаратной или программной шины UART.
                                                  //
void loop(){                                      //
//   Читаем данные:                               //  Чтение может занимать больше 1 секунды.
     gps.read();                                  //  Функцию можно вызвать с указанием массива для получения данных о спутниках.
//   Проверяем достоверность координат:           //
     if(gps.errPos){                              //  Если данные не прочитаны (gps.errPos=1) или координаты недостоверны (gps.errPos=2), то ...
       Serial.println("Координаты недостоверны"); //  Выводим сообщение об ошибке.
       delay(2000); return;                       //  Ждём 2 секунды и выполняем функцию loop() с начала.
     }                                            //
//   Выводим ссылку на Yandex карты:              //
     Serial.print("http://maps.yandex.ru/");      //
//   Координаты центра экрана:                    //
     Serial.print("?ll=");                        //
     Serial.print(gps.longitude,5);               //  Долгота.
     Serial.print(",");                           //  ,
     Serial.print(gps.latitude,5);                //  Широта.
//   Координаты точки на карте:                   //
     Serial.print("&pt=");                        //
     Serial.print(gps.longitude,5);               //  Долгота.
     Serial.print(",");                           //  ,
     Serial.print(gps.latitude,5);                //  Широта.
//   Тип карты:                                   //
     Serial.print("&l=");                         //
     Serial.print("map");                         //  "map"-схема (по умолчанию), "sat"-спутник, "skl"-гибрид.
//   Масштаб карты:                               //
     Serial.print("&z=");                         //
     Serial.print("18");                          //  от 2-мир, до 19-дом, по умолчанию 10-город.
//   Завершаем строку ссылки:                     //
     Serial.print("\r\n");                        //
}                                                 //

До кода функции loop() необходимо указать код инициализации GPS-модуля, для аппаратной или программной шины UATR, по которой подключён GPS-модуль.

Для работы примера, в сообщениях NMEA 0183, отправляемых GPS модулем, должна присутствовать строка с идентификатором GGA, или GLL, или RMC.

Получение ссылки с точкой на карте Google:

// Место для кода инициализации из примеров выше  //  Для аппаратной или программной шины UART.
                                                  //
void loop(){                                      //
//   Читаем данные:                               //  Чтение может занимать больше 1 секунды.
     gps.read();                                  //  Функцию можно вызвать с указанием массива для получения данных о спутниках.
//   Проверяем достоверность координат:           //
     if(gps.errPos){                              //  Если данные не прочитаны (gps.errPos=1) или координаты недостоверны (gps.errPos=2), то ...
       Serial.println("Координаты недостоверны"); //  Выводим сообщение об ошибке.
       delay(2000); return;                       //  Ждём 2 секунды и выполняем функцию loop() с начала.
     }                                            //
//   Выводим ссылку на Google карты:              //
     Serial.print("https://www.google.ru/maps/"); //
//   Координаты точки на карте:                   //
     Serial.print("place/");                      //
     Serial.print(gps.latitude,5);                //  Широта.
     Serial.print(",");                           //  ,
     Serial.print(gps.longitude,5);               //  Долгота.
//   Язык:                                        //
      Serial.print("?hl=");                       //
      Serial.print("ru");                         //  Русский
//   Завершаем строку ссылки:                     //
     Serial.print("\r\n");                        //
}                                                 //

До кода функции loop() необходимо указать код инициализации GPS-модуля, для аппаратной или программной шины UATR, по которой подключён GPS-модуль.

Для работы примера, в сообщениях NMEA 0183, отправляемых GPS модулем, должна присутствовать строка с идентификатором GGA, или GLL, или RMC.

Получение текущей даты и времени:

Пример выводит время, дату, день недели и UnixTime.

char* wd[]={"Вс","Пн","Вт","Ср","Чт","Пт","Сб"};   //  Определяем массив строк содержащих по две первых буквы из названий дня недели.
                                                   //
// Место для кода инициализации из примеров выше   //  Для аппаратной или программной шины UART.
                                                   //
void loop(){                                       //
//   Читаем данные:                                //  Чтение может занимать больше 1 секунды.
     gps.read();                                   //  Функцию можно вызвать с указанием массива для получения данных о спутниках.
//   Проверяем достоверность координат:            //
   if(!gps.errTim){                                //  Если время прочитано и достоверно, то ...
     Serial.print(gps.Hours  ); Serial.print(":"); //  Час.
     Serial.print(gps.minutes); Serial.print(":"); //  Минуты.
     Serial.print(gps.seconds); Serial.print(" "); //  Секунды.
   }                                               //
   if(!gps.errDat){                                //  Если дата прочитана и достоверна, то ...
     Serial.print(gps.day  ); Serial.print(".");   //  День.
     Serial.print(gps.month); Serial.print(".");   //  Месяц.
     Serial.print(gps.year ); Serial.print("г. "); //  Год.
//   Выводим название дня недели:                  //
     Serial.print("(");                            //
     Serial.print(wd[ gps.weekday ]);              //
     Serial.print(") ");                           //
//   Выводим UnixTime:                             //
     Serial.print("UnixTime: ");                   //
     Serial.print(gps.Unix);                       //
   }                                               //
//   Завершаем строку:                             //
     Serial.print("\r\n");                         //
}                                                  //

До кода функции loop() необходимо указать код инициализации GPS-модуля, для аппаратной или программной шины UATR, по которой подключён GPS-модуль.

По умолчанию используется временная зона +3. Если в вашем регионе другая временная зона, укажите её функцией gps.timeZone( ±ЧАС );.

Для работы примера, в сообщениях NMEA 0183, отправляемых GPS модулем, должна присутствовать строка с идентификатором RMC, или ZDA. Если вместо указанных строк будут присутствовать строки с идентификаторами GGA, или GLL, или DHV, или GST, то пример будет выводить только время без даты и UnixTime.

Получение данных о спутниках:

Пример выводит ID спутника, уровень приёма, положение относительно GPS-модуля, тип навигационной системы и флаг участия спутника в позиционировании.

uint8_t i[20][7];                                 //  Объявляем массив для получения данных о 20 спутниках в формате: {ID спутника, Уровень приёма, Тип, Флаг активности, Угол возвышения, Азимут, Азимут }.
char* sa[]={"NoName","GPS","Глонасс","Galileo","Beidou","QZSS"}; // Определяем массив строк содержащих названия навигационных систем спутников.
                                                  //
// Место для кода инициализации из примеров выше  //  Для аппаратной или программной шины UART.
                                                  //
void loop(){                                      //
//   Читаем данные:                               //  Чтение может занимать больше 1 секунды.
     gps.read(i);                                 //  Указанием функции массив для получения данных о спутниках.
     for(uint8_t j=0; j<20; j++){                 //  Проходим по всем элементам массива «i».
     if( i[j][0] ){                               //  Если у спутника есть ID, то выводим информацию о нём:
         Serial.print(j+1);                       //  Номер п/п.
         Serial.print(")");                       //
         Serial.print(" Спутник ");               //
         Serial.print(sa[ i[j][2] ]);             //  Название навигационной системы спутника (0-неизвестно/1-GPS/2-Глонасс/3-Galileo/4-Beidou/5-QZSS).
         Serial.print(" ID: ");                   //
         Serial.print( i[j][0] );                 //  ID спутника (1...255).
         Serial.print(". Уровень: ");             //
         Serial.print( i[j][1] );                 //  Уровень приема в дБ.
         Serial.print("дБ. Возвышение: ");        //
         Serial.print( i[j][4] );                 //  Возвышение спутника над модулем (0°-горизонт ... 90°-зенит)
         Serial.print("°. Азимут: ");             //
         Serial.print( i[j][5]+i[j][6] );         //  Азимут положения спутника (0°...360°).
         Serial.print("°. " );                    //
         if(i[j][3]){Serial.print("Участвует в позиционировании.");}
         Serial.print("\r\n");                    //
    }                                             //
    }                                             //
}                                                 //

До кода функции loop() необходимо указать код инициализации GPS-модуля, для аппаратной или программной шины UATR, по которой подключён GPS-модуль.

Для работы примера, в сообщениях NMEA 0183, отправляемых GPS модулем, должны присутствовать строки с идентификаторами GSA и GSV.

Описание функций библиотеки:

В данном разделе описаны функции библиотеки iarduino_GPS_NMEA позволяющей получать данные из текстовых сообщений NMEA 0183 отправляемых GPS-модулем по шине UART.

Библиотека iarduino_GPS_NMEA может использовать как аппаратную, так и программную реализацию шины UART для получения данных от GPS-модуля.

Подключение библиотеки:

  • Если GPS-модуль подключён по аппаратной шине UART (в примере используется UART-1):
#include <iarduino_GPS_NMEA.h>   // Подключаем библиотеку для расшифровки строк протокола NMEA получаемых по UART.
iarduino_GPS_NMEA gps;           // Создаём объект gps для работы с функциями и методами библиотеки iarduino_GPS_NMEA.
                                 //
void setup(){                    //
     Serial1.begin(9600);        //  Инициируем работу с аппаратной шиной UART-1 для получения данных от GPS модуля на скорости 9600 бит/сек.
     gps.begin(Serial1);         //  Инициируем расшифровку строк NMEA указав объект используемой шины UART.
}                                //
  • Если GPS-модуль подключён по программной шине UART (в примере используются выводы D5 и D6 для подключения модуля к Arduino):
#include <SoftwareSerial.h>      // Подключаем библиотеку для работы с программным UART, до подключения библиотеки iarduino_GPS_NMEA.
#include <iarduino_GPS_NMEA.h>   // Подключаем библиотеку для расшифровки строк протокола NMEA получаемых по UART.
SoftwareSerial SerialGPS(5, 6);  // Создаём объект SerialGPS для работы с функциями и методами библиотеки SoftwareSerial, указав выводы RX,TX Arduino соответственно.
iarduino_GPS_NMEA gps;           // Создаём объект gps для работы с функциями и методами библиотеки iarduino_GPS_NMEA.
                                 //
void setup(){                    //
     SerialGPS.begin(9600);      //  Инициируем работу с программной шиной UART для получения данных от GPS модуля на скорости 9600 бит/сек.
     gps.begin(SerialGPS);       //  Инициируем расшифровку строк NMEA указав объект используемой шины UART.
}                                //
  • Вывод TX Arduino подключается к выводу RX модуля, а вывод RX Arduino подключается к выводу TX модуля.

Функция begin();

  • Назначение: Инициализация расшифровки строк NMEA 0183 отправляемых GPS-модулем.
  • Синтаксис: begin( SERIAL [, ФЛАГ ] );
  • Параметры:
    • SERIAL - объект или класс для работы с шиной UART по которой приходят текстовые сообщения NMEA 0183 от GPS-модуля.
    • bool ФЛАГ - true / false. Флаг указывает выводить предыдущие данные при потере связи со спутниками или недостоверными результатами вычислений. Значение по умолчанию - true.
  • Возвращаемое значение: bool - результат инициализации (true или false).
  • Примечание:
    • Функция должна быть вызвана только после инициализации работы с шиной UART, объект или класс которой будет указан в качестве первого параметра функции.
    • Второй параметр функции (ФЛАГ) является не обязательным. Если указать true, или не указывать этот параметр вообще, то при потере связи со спутниками будут выводиться последние корректные координаты, дата, время и т.д. Если указать false, то при потере связи будут выводиться 0.
  • Пример:
Serial1.begin(9600); // Инициируем работу с аппаратной шиной UART-1 для получения данных от GPS модуля на скорости 9600 бит/сек.
gps.begin(Serial1)   // Инициируем расшифровку строк NMEA указав объект используемой шины UART.

Функция read();

  • Назначение: Чтение данных из сообщения NMEA отправленного GPS-модулем по шине UART.
  • Синтаксис: read( [ МАССИВ [, ФЛАГ ]] );
  • Параметры:
    • uint8_t МАССИВ - двумерный массив для получения данных о спутниках (см. пример).
    • bool ФЛАГ - true / false. Флаг указывает заполнять массив только данными о тех спутниках которые участвуют в позиционировании. Значение по умолчанию - false.
  • Возвращаемое значение: bool - результат чтения сообщения NMEA (true или false).
  • После выполнения функции (вне зависимости от наличия параметров), данные прочитанные из сообщения NMEA 0183 будут доступны в следующих переменных:
    • latitude - широта, longitude - долгота, altitude - высота над уровнем моря.
    • speed - скорость, course - курс на истинный полюс.
    • satellites[ GPS_ACTIVE ] - количество спутников участвующих в позиционировании.
    • satellites[ GPS_VISIBLE ] - количество наблюдаемых спутников.
    • PDOP, HDOP, VDOP - геометрические факторы ухудшения точности.
    • seconds - секунды, minutes - минуты, hours и Hours - часы, midday - полдень (0-am, 1-pm).
    • day - день месяца, weekday - день недели, month - месяц, year и Year - год.
    • Unix - Unix время (секунды прошедшие с начала эпохи Unix 01.01.1970 00:00:00).
    • errTim - ошибка врем, errDat - ошибка даты, errPos - ошибка коорд, errCrs - ошибка курса.
    • status - строка статусных символов, available - флаги обнаружения идентификаторов.
  • Примечание:
    • Заполнение переменных зависит от идентификаторов строк сообщения NMEA 0183.
    • Функция не знает какое количество строк включено в сообщение NMEA, по этому читает данные до получения идентификатора уже прочитанной строки, или до истечения времени установленного функцией timeOut().
    • Если в качестве параметра указан двухмерный массив для получения данных о спутниках, то каждый элемент массива, являющийся подмассивом, заполняется параметрами одного из спутников.
      • 0 элемент - ID спутника (1...255).
      • 1 элемент - Уровень приёма (отношение сигнал/шум) SNR в дБ.
      • 2 элемент - Тип навигационной системы (1-GPS, 2-Глонасс, 3-Galileo, 4-Beidou, 5-QZSS).
      • 3 элемент - Флаг участия спутника в позиционировании (1-да, 0-нет).
      • 4 элемент - Угол возвышения спутника (0°-горизонт ... 90°-зенит).
      • 5 и 6 элемент - В сумме являются азимутом положения спутника (0°...360°).
  • Пример:
uint8_t i[20][7]; // Объявляем массив для получения данных о до 20 спутниках, по 7 параметров о каждом {0-ID, 1-уровень приёма, 2-тип навигационной системы, 3-участие в позиционировании, 4-возвышение, 5и6-азимут}.
uint8_t j[10][3]; // Объявляем массив для получения данных о до 10 спутниках, по 3 параметра о каждом {0-ID, 1-уровень приёма, 2-тип навигационной системы}.
uint8_t k[15][4]; // Объявляем массив для получения данных о до 15 спутниках, по 4 параметра о каждом {0-ID, 1-уровень приёма, 2-тип навигационной системы, 3-участие в позиционировании}.
gps.read(i);      // Прочитать данные из сообщения NMEA заполнив массив i данными о наблюдаемых спутниках.
gps.read(j,true); // Прочитать данные из сообщения NMEA заполнив массив j данными о спутниках участвующих в позиционировании.
gps.read(k);      // Прочитать данные из сообщения NMEA заполнив массив k данными о наблюдаемых спутниках.
X = k[0][0];      // ID 1 спутника (от 1 до 255).
X = k[0][1];      // Уровень приёма (от 0 до 255 дБ) 1 спутника.
X = k[0][2];      // Тип навигационной системы 1 спутника.
X = k[0][3];      // Участие 1 спутника в позиционировании (0-нет/1-да).
X = k[1][0];      // ID 2 спутника (от 1 до 255).
X = k[1][1];      // Уровень приёма (от 0 до 255 дБ) 2 спутника.
X = k[1][2];      // Тип навигационной системы 2 спутника.
X = k[1][3];      // Участие 2 спутника в позиционировании (0-нет/1-да).
X = gps.latitude; // Широта.
X = gps.longitude;// Долгота.
X = gps.altitude; // Высота над уровнем моря.

Функция timeOut();

  • Назначение: Ограничение времени чтения данных.
  • Синтаксис: timeOut( МИЛЛИСЕКУНДЫ );
  • Параметры:
    • uint32_t МИЛЛИСЕКУНДЫ - максимальное время отводимое на чтение данных.
  • Возвращаемое значение: Нет.
  • Примечание:
    • Функция чтения данных read() не знает какое количество строк включено в сообщение NMEA 0183 отправляемое GPS-модулем.
    • Во время чтения переменные заполняются значениями поступающими по мере чтения строк сообщения NMEA 0183 до тех пор, пока не истечет время заданное функцией timeOut() или не будет встречена строка с уже прочитанным идентификатором.
    • Максимальное время отводимое для чтения данных по умолчанию равно 2000 мс.
    • Функцию достаточно вызвать однократно в коде setup().
  • Пример:
gps.timeOut(1500); // Читать данные не дольше 1,5 сек с момента обращения к функции read().

Функция timeZone();

  • Назначение: Установить / получить часовой пояс.
  • Синтаксис: timeZone( [±ЧАС] );
  • Параметры:
    • float ±ЧАС - количество часов на которое нужно сдвинуть время относительно UTC (±12).
  • Возвращаемое значение:
    • float ±ЧАС - установленное количество часов на которое сдвинуто время относительно UTC.
  • Примечание:
    • Если функция вызвана без параметров, то она только возвращает текущий часовой пояс.
    • Если функция вызвана с указанием количества часов (±12), то прочитанные дата и время будут сдвигаться на указанное количество часов, пока временная зона не будет изменена.
    • Если функция вызвана с параметром GPS_AutoDetectZone, то часовой пояс будет вычисляться автоматически, по координатам долготы. Стоит учесть, что часовой пояс будет вычисляться только по долготе, не учитывая политической карты и летнего времени. Например, долгота 37.5° проходит через г. Москва и делит его на 2 часовые зоны: +2 и +3.
    • Функцию достаточно вызвать однократно в коде setup().
    • По умолчанию установлен часовой пояс UTC+3.
  • Пример:
gps.timeZone(7);                   // Установить часовой пояс UTC+7:00.
gps.timeZone(-1.5);                // Установить часовой пояс UTC-1:30.
gps.timeZone(GPS_AutoDetectZone);  // Установить автоопределение часового пояса.

Данные читаемые из сообщения NMEA 0183:

Обращение к функции read() приводит к чтению данных из текстового сообщения NMEA 0183 отправляемого GPS-модулем по шине UART в следующие переменные:

  • float latitude - Широта (±90.0°).
  • float longitude - Долгота (±180.0°).
  • uint16_t altitude - Высота над уровнем моря (±32767м).
  • uint8_t speed - Скорость (0-255 км/ч).
  • float course - Курс (±180.0°).
  • uint8_t satellites[GPS_ACTIVE] - Количество активных спутников (0-12).
  • uint8_t satellites[GPS_VISIBLE] - Количество наблюдаемых спутников.
  • float PDOP - Пространственный геометрический фактор ухудшения точности (0-25.5).
  • float HDOP - Горизонтальный геометрический фактор ухудшения точности (0-25.5).
  • float VDOP - Вертикальный геометрический фактор ухудшения точности (0-25.5).
  • uint8_t seconds - Секунды (0-59).
  • uint8_t minutes - Минуты (0-59).
  • uint8_t hours - Часы (1-12).
  • uint8_t Hours - Часы (0-23).
  • uint8_t midday - Полдень (0-am, 1-pm).
  • uint8_t day - День месяца (1-31).
  • uint8_t weekday - День недели (0-воскресенье, 1-понедельник, ... , 6-суббота).
  • uint8_t month - Месяц (1-12).
  • uint8_t year - Год (0-99).
  • uint16_t Year - Год (0-65'535).
  • uint32_t Unix - Unix время (0-‭4'294'967'296 сек).
gps.read();              // Прочитать данные из сообщения NMEA.
float X = gps.latitude;  // Получить широту.
float Y = gps.longitude; // Получить долготу.
float Z = gps.altitude;  // Получить высоту над уровнем моря.

Переменные PDOP, HDOP и VDOP указывают как сильно снижается точность вычисления координат от текущего положения спутников в пространстве: 0-1 идеальная точность, 2-3 отличная точность, 4-6 хорошая точность, 7-8 средняя точность, 9-20 точность ниже среднего, больше 21 - плохая точность.

Содержание данных в строках сообщения NMEA 0183:

Переменные:Идентификаторы строк сообщения NMEA 0183 отправляемого модулем:
latitude
longitude
GGAGLLRMC------
altitudeGGA--------
satellitesGGA--------
speed
course
--RMCVTG-----
PDOP
VDOP
-----GSA---
HDOPGGA----GSA---
Hours
hours
minutes
seconds
midday
GGAGLLRMC-ZDA--DHVGST
day
weekday
month
year
Year
--RMC-ZDA----
Unix(GGA || GLL || RMC || ZDA || DHV || GST ) && ( RMC || ZDA )
Массив-----GSAGSV--

Наличие в составе сообщения NMEA 0183, отправленного модулем, строки с любым из указанных в таблице идентификатором, приводит к заполнению данными соответствующей переменной.

Проверка достоверности полученных данных:

Проверить достоверность полученных данных можно при помощи следующих переменных:

  • uint8_t errTim - Ошибка времени. Переменная может принимать следующие значения:
    0 - нет ошибок, 1 - сообщение NMEA 0183 не прочитано, 2 - время недостоверно.
  • uint8_t errDat - Ошибка даты. Переменная может принимать следующие значения:
    0 - нет ошибок, 1 - сообщение NMEA 0183 не прочитано, 2 - дата недостоверна.
  • uint8_t errPos - Ошибка координат. Переменная может принимать следующие значения:
    0 - нет ошибок, 1 - сообщение NMEA 0183 не прочитано, 2 - координаты недостоверны.
  • uint8_t errCrs - Ошибка скорости и курса. Переменная может принимать следующие значения:
    0 - нет ошибок, 1 - сообщение NMEA 0183 не прочитано, 2 - скорость и курс недостоверны.
gps.read();                  // Прочитать данные из сообщения NMEA.
if(errPos==0){               // Если координаты прочитаны без ошибок.
    float X = gps.latitude;  // Получить широту.
    float Y = gps.longitude; // Получить долготу.
    float Z = gps.altitude;  // Получить высоту над уровнем моря.
}                            //

Дополнительные переменные:

  • char* status - Строка содержащая статусные символы.
    • status[0] - Символ указывающий на способ вычисления координат указанных в строке GGA.
    • status[1] - Символ указывающий на способ вычисления координат указанных в строке GLL.
      • '0' - недоступно.
      • '1' - автономно.
      • '2' - дифференциально.
      • '3' - PPS.
      • '4' - фиксированный RTK.
      • '5' - не фиксированный RTK.
      • '6' - экстраполяция.
      • '7' - фиксированные координаты.
      • '8' - режим симуляции.
      • '*' - строка с указанным идентификатором не прочитана.
    • status[2] - Символ указывающий на достоверность координат указанных в строке GLL.
    • status[3] - Символ указывающий на достоверность координат указанных в строке RMC.
      • 'A' - координаты достоверны.
      • 'V' - ошибочные координаты.
      • '*' - строка с указанным идентификатором не прочитана.
    • status[4] - Символ указывающий на способ вычисления курса указанного в строке RMC.
    • status[5] - Символ указывающий на способ вычисления курса указанного в строке VTG.
      • 'A' - автономный.
      • 'D' - дифференциальный.
      • 'E' - аппроксимация.
      • 'M' - фиксированные данные.
      • 'N' - недостоверные данные.
      • '*' - строка с указанным идентификатором не прочитана.
    • status[6] - Символ указывающий на достоверность полученной даты.
      • 'A' - дата и время достоверны.
      • 'D' - дата достоверна.
      • 'T' - время достоверно.
      • 'V' - дата или время прочитано.
      • '*' - дата и время не прочитаны.
    • status[7] - Символ указывающий на статус навигации указанный в строке RMC.
      • '*' - строка с указанным идентификатором не прочитана.
  • uint16_t available - флаги обнаружения идентификаторов строк в сообщении NMEA 0183.
    Установленные биты переменной указывают на прочтение: 0-GGA, 1-GLL, 2-RMC, 3-VTG, 4-ZDA, 5-DHV, 6-GST, 7-9-GSA, 10-GSV, 11-TXT, 15 - сообщение NMEA 0183 прочитано до конца.
gps.read();                                                 // Прочитать данные из сообщения NMEA.
Serial.print("Сообщение NMEA содержит следующие строки: "); //
if( gps.available & bit(0)  ){ Serial.print("GGA, "); }     // установленный  0 бит переменной available указывает на наличие строки GGA в прочитанном сообщении NMEA.
if( gps.available & bit(1)  ){ Serial.print("GLL, "); }     // установленный  1 бит переменной available указывает на наличие строки GLL в прочитанном сообщении NMEA.
if( gps.available & bit(2)  ){ Serial.print("RMC, "); }     // установленный  2 бит переменной available указывает на наличие строки RMC в прочитанном сообщении NMEA.
if( gps.available & bit(3)  ){ Serial.print("VTG, "); }     // установленный  3 бит переменной available указывает на наличие строки VTG в прочитанном сообщении NMEA.
if( gps.available & bit(4)  ){ Serial.print("ZDA, "); }     // установленный  4 бит переменной available указывает на наличие строки ZDA в прочитанном сообщении NMEA.
if( gps.available & bit(5)  ){ Serial.print("DHV, "); }     // установленный  5 бит переменной available указывает на наличие строки DHV в прочитанном сообщении NMEA.
if( gps.available & bit(6)  ){ Serial.print("GST, "); }     // установленный  6 бит переменной available указывает на наличие строки GST в прочитанном сообщении NMEA.
if( gps.available & bit(7)  ){ Serial.print("GSA, "); }     // установленный  7 бит переменной available указывает на наличие строки GSA в прочитанном сообщении NMEA.
if( gps.available & bit(8)  ){ Serial.print("GSA, "); }     // установленный  8 бит переменной available указывает на наличие строки GSA в прочитанном сообщении NMEA.
if( gps.available & bit(9)  ){ Serial.print("GSA, "); }     // установленный  9 бит переменной available указывает на наличие строки GSA в прочитанном сообщении NMEA.
if( gps.available & bit(10) ){ Serial.print("GSV, "); }     // установленный 10 бит переменной available указывает на наличие строки GSV в прочитанном сообщении NMEA
if( gps.available & bit(11) ){ Serial.print("TXT, "); }     // установленный 11 бит переменной available указывает на наличие строки TXT в прочитанном сообщении NMEA.
if( gps.available & bit(15) ){ Serial.println("сообщение прочитано полностью"); }else{ Serial.println("сообщение прочитано частично"); }

Ссылки:




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями