Общие сведения:
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 | GGA | GLL | RMC | - | - | - | - | - | - |
altitude | GGA | - | - | - | - | - | - | - | - |
satellites | GGA | - | - | - | - | - | - | - | - |
speed course | - | - | RMC | VTG | - | - | - | - | - |
PDOP VDOP | - | - | - | - | - | GSA | - | - | - |
HDOP | GGA | - | - | - | - | GSA | - | - | - |
Hours hours minutes seconds midday | GGA | GLL | RMC | - | ZDA | - | - | DHV | GST |
day weekday month year Year | - | - | RMC | - | ZDA | - | - | - | - |
Unix | (GGA || GLL || RMC || ZDA || DHV || GST ) && ( RMC || ZDA ) | ||||||||
Массив | - | - | - | - | - | GSA | GSV | - | - |
Наличие в составе сообщения 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("сообщение прочитано частично"); }
Обсуждение