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

26 июня 2017

Существует немало 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.

Метки: , , .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.