GPS/GLONASS v1 (Troyka-модуль)

GPS/GLONASS принимает сигналы спутников глобального позиционирования — GPS, GLONASS и Galileo — и рассчитывает свои географические координаты, скорость перемещения, высоту над уровнем моря и точное локальное время.

Данные передаются на управляющую электронику в текстовом формате NMEA по интерфейсу UART.

Видеообзор

Принцип работы систем спутниковой навигации

Спутники непрерывно передают навигационные сигналы на дециметровых волнах. В сигнал входят метки точного времени и координаты самого спутника.

Навигатор, по задержке прохождения сигнала со спутника рассчитывает точное расстояние до него. Затем повторяет эту операцию для остальных известных спутников. Эти данные сводятся вместе — так получается точное значение координат приёмника.

Для работы навигаторов нужно открытое небо с минимум четырьмя спутниками в прямой видимости. Чтобы система работала по всей планете в каждой орбитальной группировке приходится держать более двух десятков спутников.

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

Подключение и настройка

GPS/GLONASS-модуль общается с управляющей платой по протоколу UART. В зависимости от управляющей платформы выберите вариант подключения GPS-модуля.

HardwareSerial

На управляющей плате Iskra JS и Arduino платах с микроконтроллером ATmega32U4 / ATSAMD21G18, данные по USB и общение через пины 0 и 1 осуществляется через два раздельных UART. Это даёт возможность подключить GPS-модуль к аппаратному UART на пинах 0 и 1.

Список поддерживаемых плат:

При подключении удобно использовать Troyka Shield. С Troyka Slot Shield можно обойтись без лишних проводов.

SoftwareSerial

Некоторые платы Arduino, например Arduinio Uno, прошиваются через пины 0 и 1. Это означает невозможность использовать одновременно прошивку/отладку по USB и общение с GPS-модулем. Решение проблемы — программный UART. Подключите пины TX и RX GPS-модуля к другим контактам управляющей платы и используйте библиотеку SoftwareSerial.

Для примера подключим управляющие пины GPS-модуля TX и RX — на 4 и 5 контакты управляющей платы.

При подключении удобно использовать Troyka Shield. С Troyka Slot Shield можно обойтись без лишних проводов.

HardwareSerial Mega

На платах форм-фактора Arduino Mega 2560 аппаратный UART, который отвечает за передачу данных через пины 1 и 0, отвечает также за передачу по USB. Это означает невозможность использовать одновременно UART для коммуникации с GPS-модулем и отладки по USB.

Но на платах такого форм-фактора есть ещё дополнительно 3 аппаратных UART:

  • Serial1: пины 19(RX1) и 18(TX1);
  • Serial2: пины 17(RX2) и 16(TX2);
  • Serial3: пины 15(RX3) и 14(TX3).

Список поддерживаемых плат:

Подключим GPS-модуль к объекту Serial1 на пины 18 и 19 на примере платы Arduino Mega 2560.

Примеры работы

Рассмотрим примеры работы GPS-модуля в зависимости от управляющей платформы.

Пример для Arduino HardwareSerial

В качестве примера выведем в Serial данные с GPS-модуля. Распарсим строки в отдельные переменные и сохраним их. Для этого скачайте и установите библиотеку TroykaGPS.

gpsTestHardwareSerial.ino
// библиотека для работы с GPS устройством
#include <TroykaGPS.h>
// создаём объект класса GPS и передаём в него объект Serial1 
GPS gps(Serial1);
// задаём размер массива для времени, даты, широты и долготы
#define MAX_SIZE_MASS 16
// массив для хранения текущего времени
char time[MAX_SIZE_MASS];
// массив для хранения текущей даты
char date[MAX_SIZE_MASS];
// массив для хранения широты в градусах, минутах и секундах
char latitudeBase60[MAX_SIZE_MASS];
// массив для хранения долготы в градусах, минутах и секундах
char longitudeBase60[MAX_SIZE_MASS];
 
void setup()
{ 
  // открываем последовательный порт для мониторинга действий в программе
  Serial.begin(115200);
  // ждём, пока не откроется монитор последовательного порта
  // для того, чтобы отследить все события в программе
  while (!Serial) {
  }
  Serial.print("Serial init OK\r\n");
  // открываем Serial-соединение с GPS-модулем
  Serial1.begin(115200);
}
 
void loop()
{
  // если пришли данные с gps-модуля
  if (gps.available()) {
    // считываем данные и парсим
    gps.readParsing();
    // проверяем состояние GPS-модуля
    switch(gps.getState()) {
      // всё OK
      case GPS_OK:
        Serial.println("GPS is OK");
        // выводим координаты широты и долготы
        // 1. в градусах, минутах и секундах
        // 2. градусах в виде десятичной дроби
        Serial.println("GPS Coordinates: ");
        gps.getLatitudeBase60(latitudeBase60, MAX_SIZE_MASS);
        gps.getLongitudeBase60(longitudeBase60, MAX_SIZE_MASS);
        Serial.print("Latitude\t");
        Serial.print(latitudeBase60);
        Serial.print("\t\t");
        Serial.println(gps.getLatitudeBase10(), 6);
        Serial.print("Longitude\t");
        Serial.print(longitudeBase60);
        Serial.print("\t\t");
        Serial.println(gps.getLongitudeBase10(), 6);
        // выводим количество видимых спутников
        Serial.print("Sat: ");
        Serial.println(gps.getSat());
        // выводим текущую скорость
        Serial.print("Speed: ");
        Serial.println(gps.getSpeedKm());
        // выводим высоту над уровнем моря
        Serial.print("Altitude: ");
        Serial.println(gps.getAltitude());
        // выводим текущее время
        Serial.print("Time: ");
        gps.getTime(time, MAX_SIZE_MASS);
        gps.getDate(date, MAX_SIZE_MASS);
        Serial.write(time);
        Serial.println();
        // выводим текущую дату
        Serial.print("Date: ");
        Serial.write(date);
        Serial.println("\r\n");
        // каждую переменную дату и времени можно выводить отдельно
  /*    Serial.print(gps.getHour());
        Serial.print(gps.getMinute());
        Serial.print(gps.getSecond());
        Serial.print(gps.getDay());
        Serial.print(gps.getMonth());
        Serial.print(gps.getYear());
  */   
        break;
      // ошибка данных
      case GPS_ERROR_DATA:
        Serial.println("GPS error data");
        break;
      // нет соединение со спутниками
      case GPS_ERROR_SAT:
        Serial.println("GPS no connect to satellites!!!");
        break;
    }
  }
}

Пример для Arduino SoftwareSerial

В отличии от аппаратного UART (HardwareSerial), за работу программного UART (SoftwareSerial) отвечает микроконтроллер, который назначает другие пины в режим работы RX и TX, соответственно и данные которые приходят от модуля GPS обрабатывает сам микроконтроллер во время программы. По умолчанию скорость общения GPS-модуля равна 115200, что значительно выше чем позволяет библиотека SoftwareSerial. В итоге часть информации которая приходит с GPS-модуля будет утеряна.

Решение понизить скорость общения GPS-модуля с управляющей платой. Из описание команд управления GPS-модулем найдём NMEA-команду понижение скорости до 9600бод.

$PMTK251,9600*17

Данную команду придётся выполнять при каждом новом включении GPS-модуля. В качестве примера выведем в Serial данные с GPS-модуля. Распарсим строки в отдельные переменные и сохраним их. Для этого скачайте и установите библиотеку TroykaGPS

SoftwareSerialGpsTest.ino
// библиотека для работы с GPS устройством
#include <TroykaGPS.h>
 
// библиотека для работы программного Serial
#include <SoftwareSerial.h>
 
// создаём объект для работы с программным Serial
// и передаём ему пины TX и RX
SoftwareSerial mySerial(4, 5);
 
// serial-порт к которому подключён GPS-модуль
#define GPS_SERIAL    mySerial
 
// создаём объект класса GPS и передаём в него объект GPS_SERIAL 
GPS gps(GPS_SERIAL);
 
// задаём размер массива для времени, даты, широты и долготы
#define MAX_SIZE_MASS 16
// массив для хранения текущего времени
char strTime[MAX_SIZE_MASS];
// массив для хранения текущей даты
char strDate[MAX_SIZE_MASS];
// массив для хранения широты в градусах, минутах и секундах
char latitudeBase60[MAX_SIZE_MASS];
// массив для хранения долготы в градусах, минутах и секундах
char longitudeBase60[MAX_SIZE_MASS];
 
void setup()
{ 
  // открываем последовательный порт для мониторинга действий в программе
  // и передаём скорость 9600 бод
  Serial.begin(9600);
  // ждём, пока не откроется монитор последовательного порта
  // для того, чтобы отследить все события в программе
  while (!Serial) {
  }
  Serial.print("Serial init OK\r\n");
  // открываем Serial-соединение с GPS-модулем на скорости 115200 бод
  GPS_SERIAL.begin(115200);
  // печатаем строку
  Serial.println("GPS init is OK on speed 115200");
  // изменяем скорость обещение GPS-модуля с управляющей платой на 9600 бод
  // используем NMEA-команду «$PMTK251,9600*17\r\n»
  GPS_SERIAL.write("$PMTK251,9600*17\r\n");
  // закрываем Serial-соединение с GPS-модулем
  GPS_SERIAL.end();
  // открываем Serial-соединение с GPS-модулем на скорости 9600 бод
  GPS_SERIAL.begin(9600);
  // печатаем строку
  Serial.print("GPS init is OK on speed 9600");
}
 
void loop()
{
  // если пришли данные с gps-модуля
  if (gps.available()) {
    // считываем данные и парсим
    gps.readParsing();
    // проверяем состояние GPS-модуля
    switch(gps.getState()) {
      // всё OK
      case GPS_OK:
        Serial.println("GPS is OK");
        // выводим координаты широты и долготы
        // 1. в градусах, минутах и секундах
        // 2. градусах в виде десятичной дроби
        Serial.println("GPS Coordinates: ");
        gps.getLatitudeBase60(latitudeBase60, MAX_SIZE_MASS);
        gps.getLongitudeBase60(longitudeBase60, MAX_SIZE_MASS);
        Serial.print("Latitude\t");
        Serial.print(latitudeBase60);
        Serial.print("\t\t");
        Serial.println(gps.getLatitudeBase10(), 6);
        Serial.print("Longitude\t");
        Serial.print(longitudeBase60);
        Serial.print("\t\t");
        Serial.println(gps.getLongitudeBase10(), 6);
        // выводим количество видимых спутников
        Serial.print("Sat: ");
        Serial.println(gps.getSat());
        // выводим текущую скорость
        Serial.print("Speed: ");
        Serial.println(gps.getSpeedKm());
        // выводим высоту над уровнем моря
        Serial.print("Altitude: ");
        Serial.println(gps.getAltitude());
        // выводим текущее время
        Serial.print("Time: ");
        gps.getTime(strTime, MAX_SIZE_MASS);
        gps.getDate(strDate, MAX_SIZE_MASS);
        Serial.write(strTime);
        Serial.println();
        // выводим текущую дату
        Serial.print("Date: ");
        Serial.write(strDate);
        Serial.println("\r\n");
        // каждую переменную дату и времени можно выводить отдельно
  /*    Serial.print(gps.getHour());
        Serial.print(gps.getMinute());
        Serial.print(gps.getSecond());
        Serial.print(gps.getDay());
        Serial.print(gps.getMonth());
        Serial.print(gps.getYear());
  */   
        break;
      // ошибка данных
      case GPS_ERROR_DATA:
        Serial.println("GPS error data");
        break;
      // нет соединение со спутниками
      case GPS_ERROR_SAT:
        Serial.println("GPS no connect to satellites!!!");
        break;
    }
  }
}

Пример кода для Iskra JS

Выведем данные о координатах, высоте над уровнем моря, количестве видимых спутников и точном времени в консоль Web IDE.

testGPS.js
Serial3.setup(115200, {rx: P0, tx: P1});
var gps = require("GPS").connect(Serial3, function(data) {
  console.log(data);
});

Каждую секунду в консоль будет выводится информация от модуля.

{ "time":"16:35:29", "lat":53.068403,"lon":-4.076282,"fix":1,"satellites":7,"altitude":1085.0 }

Элементы платы

Модуль NL3333

NL3333 – навигационный приемник НАВИА, выполненный в оригинальном форм-факторе 8.7×9.5 мм на базе чипсета MediaTek MT3333.

Приемник использует весь спектр GNSS систем: GPS, GLONASS и Galileo. NL3333 отличается высокой чувствительностью, малым энергопотреблением и быстрым временем первой фиксации (TTFF). Связь с модулем осуществляется через UART, данные выводятся по протоколу NMEA.

Контакты подключения трёхпроводных шлейфов

На модуле выведены две группы Troyka-контактов.

Нижняя группа

  • Сигнальный (TX) — цифровой выход GPS-модуля. Подключите к пину RX микроконтроллера.
  • Питание (V) — соедините с рабочим напряжением микроконтроллера.
  • Земля (G) — соедините с землёй микроконтроллера.

Верхняя группа

  • Сигнальный (RX) — цифровой вход GPS-модуля. Подключите к пину TX микроконтроллера.
  • Сигнальный (P) — пин синхронизации GPS-модуля. Подключите к цифровому пину микроконтроллера.

Антенна

Пассивная антенна GPS/GLONAS на керамической подложке необходима для приёма сигнала навигационным приемником GPS/GLONASS.

Преобразователь логических уровней

Необходим для сопряжения устройств с разными напряжениями логических уровней.

В нашем случае это может быть управляющее устройство Arduino с 5 вольтовой логикой и GPS/GLONASS модуль с 3,3 вольтовой логикой.

Светодиодная индикация

Имя светодиода Назначение
RX и TX Мигают при обмене данными между GPS/GLONASS модулем и управляющим устройством.
P Индикатор приёма спутниковых сигналов. Мигает если GPS-модуль «нашёл себя»

Обновление прошивки

Периодически выходят новые версии прошивки для GPS-приёмников с улучшениями и новыми функциями.

Принципиальная и монтажная схемы

Характеристики

  • Чипсет: NL3333
  • Навигационные системы: GPS, GLONASS, BeiDou
  • Рабочие частоты:
    • GPS L1: 1575.42 МГц
    • GLONASS L1: 1598.0625–1605.375 МГц
    • GALILEO E1: 1575.42 МГц
  • Протоколы передачи данных: NMEA
  • Скорость передачи данных по умолчанию: 115200 бод
  • Размеры встроенной антенны: 40×40 мм
  • Поляризация: RHCP (правая круговая поляризация)
  • Погрешность позиционирования: менее 3 м
  • Горячий старт: 1 с
  • Холодный старт: 28 с
  • Рабочее напряжение: 3,3–5 В
  • Потребляемый ток: до 25 мА
  • Габариты: 25,4×25,4 мм

Ресурсы