Создаем GPS часы на Arduino

Добавлено28 июня 2016 в 09:20

Вам необходим источник точного времени от GPS? Данная статья покажет вам, как использовать модуль GPS для получения времени, даты и координат, и как показать их на LCD индикаторе с помощью Arduino.

Что необходимо?

Введение

Создание системы глобального позиционирования, или GPS, началось в начале 1970-х годов. Каждая страна (Россия, США, Китай и т.д.) обладают своей собственной системой, но большинство средств спутниковой навигации в мире используют систему США.

Каждый спутник системы имеет атомные часы, которые непрерывно контролируются и корректируются NORAD (командованием воздушно-космической обороны Северной Америки) каждый день.

По сути, приемник по своим часам измеряет TOA (время получения сигнала, time of arrival) четырех спутниковых сигналов. Исходя из TOA и TOT (времени отправки сигнала, time of transmission), приемник вычисляет четыре значения времени «пролета» сигнала (TOF, time of flight), которые отличаются друг от друга в зависимости от расстояния спутник-приемник. Затем, исходя из четырех значений TOF, приемник вычисляет свое положение в трехмерном пространстве и отклонение своих часов.

Самые недорогие GPS приемники обладают точностью около 20 метров для большинства мест на Земле. Теперь посмотрим, как изготовить свои собственные часы GPS с помощью Arduino.

Аппаратная часть

Мой GPS модуль имеет 6 контактов: GND, Vin, Tx, Rx и снова GND. Шестой вывод никуда не подключен. Контакт GND соединен с корпусом на Arduino, Vin подключаем к шине +5В на Arduino, Tx подключен к выводу 10 на Arduino, а вывод Rx никуда не подключаем, так как не будем посылать на GPS модуль никаких сообщений. Мой модуль передает спутниковые данные, используя интерфейс RS-232, со скоростью 4800 бит/сек, которые принимаются Arduino на выводе 10.

Ниже показана фотография GPS модуля:

gps модуль
GPS модуль EM-411

Модуль отправляет то, что известно как NMEA сообщения. Здесь вы можете увидеть пример одного NMEA сообщения и его разъяснение (выдержка из технического описания):

$GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M,,,,0000*18
Формат данных GGA
Название Пример Единицы Описание
ID сообщения $GPGGA   Заголовок протокола GGA
Время UTC 161229.487   hhmmss.sss (две цифры часы, две цифры минуты, затем секунды с точностью до тысячных)
Широта 3723.2475   ddmm.mmmm (первые две цифры градусы, затем минуты с точностью до десятитысячных)
Флаг N/S N   N – север, S – юг
Долгота 12158.3416   ddmm.mmmm (первые две цифры градусы, затем минуты с точностью до десятитысячных)
Флаг E/W W   E – восток, W – запад
Индикатор местоположения 1  
  • 0 – местоположение недоступно или некорректно;
  • 1 – режим GPS SPS, местоположение корректно;
  • 2 – дифференциальный GPS, режим SPS, местоположение корректно;
  • 3 – режим GPS PPS, местоположение корректно.
Количество используемых спутников 07   В диапазоне от 0 до 12
HDOP 1.0   Ухудшение точности по горизонтали
Высота относительно уровня моря 9.0 метры  
Единицы измерения M метры  
Геоидальное различие     Различие между земным эллипсоидом WGS-84 и уровнем моря (геноидом)
Единицы измерения M метры  
Возраст дифференциальных данных GPS   секунды Нулевые поля, когда DGPS не используется
ID станции, передающей дифференциальные поправки 0000    
Контрольная сумма *18    
<CR><LF>     Конец сообщения

Все эти данные принимаются Arduino через вывод 10. Библиотека TinyGPS читает сообщения GPGGA и GPRMC (для подробной информации о GPRMC смотрите техническое описание).

Arduino на схеме не показан. Подключите периферийные устройства согласно подписанным соединениям.

схема gps часов на arduino
Схема GPS часов на arduino

Программное обеспечение

При подаче питания GPS модуль затрачивает некоторое время, чтобы получить правильное местоположения от спутников. Когда местоположение получено, модуль шлет NMEA сообщения на Arduino. Библиотека TinyGPS содержит функцию для получения времени и даты из GPRMC сообщения. Она называется crack_datetime() и принимает в качестве параметров семь указателей на переменные: год year, месяц month, день месяца day, часы hour, минуты minute, секунды second, и сотые доли секунды hundredths. Вызов функции выглядит так:

gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);

Вызов данной функции возвращает вам в переменных правильные значения до тех пор, пока с железом всё в порядке.

Чтобы получить ваше местоположение, можно вызвать функцию f_get_position(). Данная функция принимает в качестве параметров два указателя на переменные: широта latitude и долгота longitude. Вызов данной функции выглядит так:

gps.f_get_position(&latitude, &longitude);

 Исходный текст программы:

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

#define RXPIN 10
#define TXPIN 9
#define GPSBAUD 4800
#define RS 2
#define EN 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7


TinyGPS gps;
SoftwareSerial uart_gps(RXPIN, TXPIN);
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);

// Переменные
int seconds;
int timeoffset = 1; // Пользователь должен изменить единицу на соответствующий часовой пояс. В примере используем сдвиг на +1 час.

// Объявление функций.
void getgps(TinyGPS &gps);

// Функция настройки - запускается только при включении
void setup()
{
  Serial.begin(115200);     // Запуск последовательного интерфейса для отладки
  uart_gps.begin(GPSBAUD);  // Запуск приемника UART для GPS
  lcd.begin(16,2);          // Объявление LCD 
  lcd.print("   GPS clock");   // Сообщение приветствия
  delay(1000);              // Ждем одну секунду
  lcd.clear();              // Очистить LCD
}

// Цикл главной программы - запущен всегда
void loop()
{
  while(uart_gps.available())
  {
    int c = uart_gps.read();
    if(gps.encode(c))
    {
      getgps(gps);
    }
  }
}

/*
 * Данная функция получает данные от GPS модуля
 * и отображает их на LCD
 */
  
void getgps(TinyGPS &gps)
{
int year;
float latitude, longitude;
byte month, day, hour, minute, second, hundredths;

  gps.f_get_position(&latitude, &longitude);
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
  
  hour = hour + timeoffset;

  lcd.clear();//lcd.setCursor(0, 0);
  lcd.print("Time: ");

  if (hour <= 9)
  {
    lcd.print("0"); lcd.print(hour, DEC);
  }
  else
  {
    lcd.print(hour, DEC);
  }
  lcd.print(":");
  if (minute <=9)
  {
    lcd.print("0"); lcd.print(minute, DEC);
  }
  else
  {
    lcd.print(minute, DEC); 
  }
  lcd.print(":");
  if (second <= 9) 
  {
    lcd.print("0"); lcd.print(second, DEC);
  } 
  else 
  {
    lcd.print(second, DEC);
  }
  lcd.setCursor(0,1);
  lcd.print("Date: ");
  if (day <= 9)
  {
    lcd.print("0"); lcd.print(day, DEC);
  }
  else
  {
    lcd.print(day, DEC);
  }
  lcd.print("-"); 
  if (month <= 9)
  {
    lcd.print(month, DEC); 
  }
  else
  {
    lcd.print(month, DEC);
  }
  lcd.print("-"); lcd.print(year, DEC);
  delay(2000);
  lcd.clear();
  lcd.print("Lat: "); lcd.print(latitude, DEC);
  lcd.setCursor(0,1);
  lcd.print("Lon: "); lcd.print(longitude, DEC);
  delay(2000);

// Debugging purpose only.
Serial.print(latitude, DEC); Serial.print(" - "); Serial.println(longitude, DEC);

}

Загрузки

Здесь все файлы, которые вам могут понадобиться:

Комплектующие: технические описания и ссылки на магазины (aliexpress и пр.)

Фото и видео

На фотографиях и видео я добавил смещение широты и долготы. Чтобы улучшить прием, я подключил GPS модуль через длинный кабель и высунул его в окно.

gps часы на arduino дата и время
Дата и время
gps часы на arduino широта и долгота
Широта и долгота
gps часы на arduino подключение
Подключение

Заключение

В данной статье мы рассмотрели, как получить дату, время и координаты от GPS модуля, а затем как их отобразить на LCD индикаторе. Теперь вы знаете, где находитесь!

Надеюсь статья оказалась полезной. Оставляйте комментарии!

Теги

ArduinoArduino MegaGPS модульLCD дисплейВремя GPS