Работа с GPS-модулем на базе NEO-6M из Arduino
26 июня 2017
Существует немало GPS-модулей и шилдов для Arduino, но многие из них довольно недешевы. Если вам в вашем проекте по каким-то причинам нужен GPS, самым дешевым (не в ущерб качеству!) из известных мне вариантов будет модуль на базе чипа NEO-6M. На AliExpress такие модули продаются за 230 рублей (4 $) с учетом доставки в Россию. Давайте же попробуем разобраться, как с ними работать.
Примечание: Как правило, GPS не работает в доме. Чтобы поймать сигнал от спутников, с модулем нужно выйти на улицу или на балкон, или хотя бы положить его рядом с окном. Кроме того, GPS может плохо ловить в облачную погоду. Учтите также, что даже на открытом воздухе и в хорошую погоду при первом включении модулю может потребоваться несколько минут на инициализацию.
К Arduino модуль подключается не сложно, так как питается он от 5 В, а данные передает по UART на скорости 9600 бод. Когда модуль находит достаточное количество спутников для определения своего местоположения, он начинает мигать синим светодиодом и передавать по UART раз в секунду что-то вроде:
$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 <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;
}
}
Соответствующее устройство в действии:
Работа с использованным здесь экранчиком ранее была подробно описана в заметке Об использовании экранчиков 1602 с I2C-адаптером.
В общем, к обычно, ничего супер сложного. Полную версию исходников к этой заметке вы найдете на GitHub.
Метки: AVR, Беспроводная связь, Электроника.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.