Системы глобального позиционирования (GPS) состоят из набора спутников средней высоты, управляемых с нескольких наземных станций.
Каждый спутник имеет чрезвычайно точные часы и шлет данные и синхронизирующий сигнал на Землю. Приемники GPS используют эти сигналы для определения своего местоположения в любой точке мира в виде широты, долготы и высоты.
Чтобы вычислить ваше двумерное положение (широта и долгота) и направление движения, GPS-приемник должен быть зафиксирован на сигнал от не менее 3 спутников. При наличии 4 или более спутников приемник может определить ваше трехмерное положение (широта, долгота и высота).
Модуль NEO-6M GPS способен отслеживать до 22 спутников на 50 каналах с большим уровнем чувствительности -161 дБ при токе питания всего 45 мА. Рабочее напряжение модуля 3,3 В. В модуле установлена микросхема HK24C32 (EEPROM) с объемом памяти 4 КБ, в EEPROM хранятся данные часов, последние данные о местоположении (данные об орбите) и конфигурацию модуля. Батарейка автоматически заряжается при включении модуля и сохраняет данные до двух недель. В модуле установлен светодиод который сигнализирует о состоянии определения местоположения, если светодиод горит но не мигает, значит идет поиск спутников, если светодиод мигает, значит спутники найдены и идет определение местоположения.
Назначение контактов модуля NEO-6M:
- GND — заземляющий вывод питания
- TxD — вывод для передачи данных
- RxD — вывод для получения данных
- VCC — вывод питания 3,3 В
При подключении модуля NEO-6M к плате Arduino Nano выводы Tx и Rx на NEO-6М к выводам 2 и 3 на Arduino, при подключении будет использован программный последовательный порт.
Скетч показанный ниже вывод информацию о местоположении и время в монитор порта. Для поиска спутников модулю NEO-6M может понадобится время от 5 до 30 минут.
#define RX 2 #define TX 3 #include <TinyGPS++.h> // https://github.com/mikalhart/TinyGPSPlus/archive/refs/heads/master.zip #include <SoftwareSerial.h> TinyGPSPlus gps; SoftwareSerial gpsSerial(RX, TX); void setup(){ Serial.begin(9600); gpsSerial.begin(9600); } void loop(){ while (gpsSerial.available() > 0) if (gps.encode(gpsSerial.read())) displayInfo(); if (millis() > 5000 && gps.charsProcessed() < 10){ Serial.println("No GPS detected"); while(true); } } void displayInfo(){ if (gps.location.isValid()){ Serial.print("Latitude: "); Serial.println(gps.location.lat(), 6); Serial.print("Longitude: "); Serial.println(gps.location.lng(), 6); Serial.print("Altitude: "); Serial.println(gps.altitude.meters()); Serial.print("Satellites: "); Serial.println(gps.satellites.value()); } else{Serial.println("Location: Not Available");} Serial.print("Date: "); if (gps.date.isValid()){ Serial.print(gps.date.month()); Serial.print("/"); Serial.print(gps.date.day()); Serial.print("/"); Serial.println(gps.date.year()); } else{Serial.println("Not Available");} Serial.print("Time: "); if (gps.time.isValid()){ if (gps.time.hour() < 10) Serial.print(F("0")); Serial.print(gps.time.hour()); Serial.print(":"); if (gps.time.minute() < 10) Serial.print(F("0")); Serial.print(gps.time.minute()); Serial.print(":"); if (gps.time.second() < 10) Serial.print(F("0")); Serial.print(gps.time.second()); Serial.print("."); if (gps.time.centisecond() < 10) Serial.print(F("0")); Serial.println(gps.time.centisecond()); } else{Serial.println("Not Available"); } Serial.println(); Serial.println(); delay(5000); }
Показания модуля опрашиваются один раз в 5 секунд, как видно на скриншоте, модуль определил долготу, широту, кол-во спутников, дату и время, высоту модуль GPS определить не смог, возможно для этого необходимо больше спутников и время.
Мне был интересен данный модуль не для определения точного местоположения, а для определения сверхточного времени. Ниже показан простой пример создания часов с использованием дисплея LCD0802, на первую строку которого выводится время, а на вторую день, месяц и год.
В часах предусмотрена коррекция времени от UTC, например для сдвига в 6 часов в скетче необходимо прописать следующее:
#define time_offset 21600 // смещение от UTC 1 час = 3600
Как подключать дисплей LCD0802 рассказано в http://rcl-radio.ru/?p=129068
Показания текущего времени так же дублируется в мониторе порта.
#define RX 2 // RX pin #define TX 3 // TX pin #define time_offset 21600 // смещение от UTC 1 час = 3600 #include <TinyGPS++.h> // https://github.com/mikalhart/TinyGPSPlus/archive/refs/heads/master.zip #include <TimeLib.h> // https://github.com/PaulStoffregen/Time/archive/master.zip #include <SoftwareSerial.h> // Входит в состав Arduino IDE #include <LiquidCrystal.h> // Входит в состав Arduino IDE TinyGPSPlus gps; SoftwareSerial SoftSerial(RX, TX); LiquidCrystal lcd(12, 11, 5, 6, 7, 8); // номер вывода дисплея(вывод Arduino): RS(12),E(11),D4(5),D5(6),D6(7),D7(8) byte last_second, Second, Minute, Hour, Day, Month; int Year; void setup(){ SoftSerial.begin(9600);Serial.begin(9600); lcd.begin(8, 2); } void loop(){ while (SoftSerial.available() > 0){ if (gps.encode(SoftSerial.read())){ if (gps.time.isValid()){ Minute = gps.time.minute(); Second = gps.time.second(); Hour = gps.time.hour(); } if (gps.date.isValid()){ Day = gps.date.day(); Month = gps.date.month(); Year = gps.date.year(); } if(last_second != gps.time.second()){ last_second = gps.time.second(); setTime(Hour, Minute, Second, Day, Month, Year); adjustTime(time_offset); lcd.setCursor(0, 0); lcd.print(hour()/10);lcd.print(hour()%10); lcd.print(":"); lcd.print(minute()/10);lcd.print(minute()%10); lcd.print(":"); lcd.print(second()/10);lcd.print(second()%10); lcd.setCursor(0, 1); lcd.print(day()/10);lcd.print(day()%10); lcd.print("-"); lcd.print(month()/10);lcd.print(month()%10); lcd.print("-"); lcd.print((year()-2000)/10);lcd.print((year()-2000)%10); Serial.print(hour()/10);Serial.print(hour()%10);Serial.print(":"); Serial.print(minute()/10);Serial.print(minute()%10);Serial.print(":"); Serial.print(second()/10);Serial.println(second()%10); Serial.print(day()/10);Serial.print(day()%10);Serial.print("-"); Serial.print(month()/10);Serial.print(month()%10);Serial.print("-"); Serial.println(year()); }}}}