← На главную

Работа с GPS-модулем на базе NEO-6M из Arduino

Существует немало GPS-модулей и шилдов для Arduino, но многие из них довольно недешевы. Если вам в вашем проекте по каким-то причинам нужен GPS, самым дешевым (не в ущерб качеству!) из известных мне вариантов будет модуль на базе чипа NEO-6M. На AliExpress такие модули продаются за 230 рублей (4$) с учетом доставки в Россию. Давайте же попробуем разобраться, как с ними работать.

Примечание: Как правило, GPS не работает в доме. Чтобы поймать сигнал от спутников, с модулем нужно выйти на улицу или на балкон, или хотя бы положить его рядом с окном. Кроме того, GPS может плохо ловить в облачную погоду. Учтите также, что даже на открытом воздухе и в хорошую погоду при первом включении модулю может потребоваться несколько минут на инициализацию.

К Arduino модуль подключается не сложно, так как питается он от 5 В, а данные передает по UART на скорости 9600 бод. Когда модуль находит достаточное количество спутников для определения своего местоположения, он начинает мигать синим светодиодом и передавать по UART раз в секунду что-то вроде:

$GPRMC,160709.00,A,5546.7229,N,03749.47557,E,2.578,228.26,170617,,,A*69 $GPVTG,228.26,T,,M,2.578,N,4.774,K,A*39 $GPGGA,160709.00,5546.792,N,03749.475,E,1,07,4.00,172.3,M,13.3,M,,*5C $GPGSA,A,3,13,20,18,30,21,15,,,,,,,6.45,3.95,5.11*02

Тут на глаз несложно найти текущие координаты (5546.79229,N и 03749.47557,E), а также дату (170617) и время в UTC (160709). Цифры в конце строк после звездочки – это контрольные суммы. Стоит отметить, что если модуль еще не определил свои GPS-координаты, он передает по UART немного другие данные. Подробное описание того, как декодировать все эти данные можно найти в документе под названием U-blox 6 Receiver Description Including Protocol Specification [PDF].

Несмотря на то, что написать свой парсер достаточно просто, их написано и отлажено уже достаточно, чтобы не тратить на это свое время. Лично я воспользовался библиотекой TinyGPSPlus. Код прошивки:

#include <Arduino.h> #include <SoftwareSerial.h> #include "LiquidCrystal_I2C.h" #include "TinyGPS++.h" const int DELAY = 100; const int SWITCH_TIME = 5000; LiquidCrystal_I2C lcd(0x3F, 16, 2); SoftwareSerial gps_serial(A3, A2); /* RX, TX */ TinyGPSPlus gps_parser; void setup() { Serial.begin(9600); gps_serial.begin(9600); lcd.begin(); } String twoDigits(int x) { if(x < 10) return "0" + String(x); else return String(x); } int currentModeTime = 0; bool showLocation = false; void loop() { while(gps_serial.available() > 0) { char temp = gps_serial.read(); Serial.write(temp); gps_parser.encode(temp); } String lat = "Unknown "; String lng = "location "; if(gps_parser.location.isValid()) { lat = "Lat: " + String(gps_parser.location.lat(), 6); lng = "Lng: " + String(gps_parser.location.lng(), 6); } String date = "Unknown date "; if(gps_parser.date.isValid()) { date = twoDigits(gps_parser.date.day()) + "/" + twoDigits(gps_parser.date.month()) + "/" + String(gps_parser.date.year()) + " "; } String time = "Unknown time "; if(gps_parser.time.isValid()) { time = twoDigits(gps_parser.time.hour()) + ":" + twoDigits(gps_parser.time.minute()) + ":" + twoDigits(gps_parser.time.second()) + " UTC "; } if(showLocation) { lcd.setCursor(0, 0); lcd.print(lat); lcd.setCursor(0, 1); lcd.print(lng); } else { // show date and time lcd.setCursor(0, 0); lcd.print(date); lcd.setCursor(0, 1); lcd.print(time); } delay(DELAY); currentModeTime += DELAY; if(currentModeTime >= SWITCH_TIME) { lcd.clear(); showLocation = !showLocation; currentModeTime = 0; } }

Соответствующее устройство в действии:

Использование GPS-модуля NEO-6M из Arduino

Работа с использованным здесь экранчиком ранее была подробно описана в заметке Об использовании экранчиков 1602 с I2C-адаптером.

В общем, к обычно, ничего супер сложного. Полную версию исходников к этой заметке вы найдете на GitHub.