Часы на GPS модуле и семисегментных индикаторах

GPS (Global Positioning System) — это глобальная спутниковая система навигации, разработанная и поддерживаемая правительством США. Она позволяет определять координаты и время в любой точке Земли с помощью спутников, которые находятся на орбите вокруг Земли.

GPS состоит из сети спутников, которые передают сигналы, и приемников, которые принимают эти сигналы и обрабатывают их, чтобы определить свое местоположение. Каждый спутник GPS посылает информацию о своем местоположении и времени синхронизации с наземными станциями, которые обрабатывают эти данные и передают их пользователям.

GPS широко используется в навигации, геодезии, геоинформационных системах, мониторинге транспорта и других областях. Он позволяет точно определять местоположение и перемещение объектов на Земле, что делает его важным инструментом для различных приложений.

Модуль GY-NEO6MV2 — это компактное устройство, которое используется для определения координат и времени с помощью спутниковой системы GPS. Модуль NEO-6M GPS включает в себя высокочувствительный приемник GPS-сигналов, а также микроконтроллер для обработки полученных данных.

Основными характеристиками модуля GY-NEO6MV2 являются:

— Высокая точность определения координат и времени

— Широкий диапазон рабочих температур (-40…+85°C)

— Поддержка нескольких систем спутниковой навигации (GPS, GLONASS, Galileo, BeiDou)

— Низкое энергопотребление (в режиме ожидания — менее 20 мА)

— Интерфейс UART для передачи данных

Для работы с модулем GY-NEO6MV2 необходимо подключить его к микроконтроллеру или компьютеру через интерфейс UART и настроить его на прием данных от спутников. Модуль можно использовать в различных проектах, связанных с навигацией, геолокацией и мониторингом объектов.

Модуль NGY-NEO6MV2 способен отслеживать до 22 спутников на 50 каналах с большим уровнем чувствительности -161 дБ. Рабочее напряжение модуля 3,3 В (или 5 В при наличии стабилизатора на плате модуля). В модуле установлена микросхема HK24C32 (EEPROM) с объемом памяти 4 КБ, в EEPROM хранятся данные часов, последние данные о местоположении (данные об орбите) и конфигурацию модуля. Батарейка автоматически заряжается при включении модуля и сохраняет данные до двух недель. В модуле установлен светодиод который сигнализирует о состоянии определения местоположения, если светодиод горит но не мигает, значит идет поиск спутников, если светодиод мигает, значит спутники найдены и идет определение местоположения.

Так как модуль GY-NEO6MV2 позволяет принимать время UTC, то его можно использовать для установки коррекции времени в часах.

UTC (Coordinated Universal Time) — это мировое координированное время, которое используется в качестве стандарта для согласования времени в разных частях мира. Оно основано на атомных часах и корректируется для согласования со сменой года и сезонов. UTC имеет постоянную длительность суток, которая составляет 24 часа.

UTC используется во всем мире в качестве стандарта времени для многих приложений, таких как навигация, телекоммуникации, астрономия и т.д. Он является основой для определения временных зон и синхронизации времени в компьютерных сетях и других системах.

UTC отличается от GMT (Greenwich Mean Time) тем, что он не зависит от времени в Гринвиче и использует атомные часы вместо звездного времени.

Время UTC не имеет временного сдвига относительно времени в Гринвиче (GMT), так как оно является мировым стандартом времени, который используется во всем мире. Однако, время UTC может отличаться от местного времени в зависимости от того, в какой части мира находится конкретное местоположение.

Для согласования времени в разных частях мира используются различные временные зоны, которые отличаются от UTC на определенное количество часов. Например, время в Нью-Йорке отличается от UTC на 5 часов в зимнее время и на 4 часа в летнее время из-за перехода на летнее время.

Поэтому, чтобы узнать время UTC в определенный момент времени, необходимо знать разницу между местным временем и временной зоной, в которой находится это местоположение.

Используя модуль NGY-NEO6MV2 можно сделать простые часы. В часах можно использовать различные семисегментные индикаторы с общим анодом, в данном проекте использованы индикаторы DA56-11EWA. При использовании других индикаторов необходимо подобрать ток сегментов таким, чтобы он не превышал 20 мА. Так же можно использовать индикаторы с общим катодом при небольшой изменении схемы подключения и небольшой правки скетча.

В проекте используется плата разработчика на базе микроконтроллера LGT8F328.

Дополнительно в часах используется датчик температуры DS18B20 для вывода показаний температуры с 55 по 59 секунду отсчета часов.

#define SEG_A  2
#define SEG_B  3
#define SEG_C  4
#define SEG_D  5
#define SEG_E  6
#define SEG_F  7
#define SEG_G  8
#define SEG_DP 9

#define LED_0  A0
#define LED_1  A1
#define LED_2  A2
#define LED_3  A3

#define time_offset   21600  // смещение от UTC 1 час = 3600
#define KORR_T  -2.7   // DS18B20 коррекция температуры

#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 <OneWire.h>        // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip             
 TinyGPSPlus gps;
 OneWire  ds(13); // Вход датчика 18b20

byte an,segm,a[4],i,dpp;
int br=1;
unsigned long times;
byte last_minute, Second, Minute, Hour, Day, Month;
int Year;
int timer;
bool w=1,w1;

void setup() {
  Serial.begin(9600);   
  cli();
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  OCR2A = 155;
  TCCR2A |= (1 << WGM21);
  TCCR2B |= (1 << CS22) | (1 << CS21);
  TIMSK2 |= (1 << OCIE2A);
  sei();
  pinMode(SEG_A,OUTPUT);
  pinMode(SEG_B,OUTPUT);
  pinMode(SEG_C,OUTPUT);
  pinMode(SEG_D,OUTPUT);
  pinMode(SEG_E,OUTPUT);
  pinMode(SEG_F,OUTPUT);
  pinMode(SEG_G,OUTPUT);
  pinMode(SEG_DP,OUTPUT);
  pinMode(LED_0,OUTPUT);
  pinMode(LED_1,OUTPUT);
  pinMode(LED_2,OUTPUT);
  pinMode(LED_3,OUTPUT);
}

void loop() {
 
 while (Serial.available() > 0){ 
    if (gps.encode(Serial.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_minute != gps.time.minute()){
        last_minute = gps.time.minute();
        setTime(Hour, Minute, Second, Day, Month, Year);
        adjustTime(time_offset);
 }

if (millis() > 5000 && gps.charsProcessed() < 10){while(true);}

 if(Year==2000){
    a[0]=11;
    a[1]=11;
    a[2]=11;
    a[3]=11;
      }
 else{    
   timer=hour()*100+minute();
   if(second()>=55){timer = dsRead(0)*100; delay(200);}
  
    
    a[0]=timer/1000%10;
    a[1]=timer/100%10;
    a[2]=timer/10%10;
   if(second()>=55){a[3]=12;}else{a[3]=timer%10;}
 }
}


ISR(TIMER2_COMPA_vect){
   switch (i) {
    case 0: segm = 10; segment();an = 10;anod();delayMicroseconds(br);segm = a[0];segment();an = 0;ch(SEG_DP, 1);anod();break;
    case 1: segm = 10; segment();an = 10;anod();delayMicroseconds(br);segm = a[1];segment();an = 1;ch(SEG_DP, dpp);anod();break;
    case 2: segm = 10; segment();an = 10;anod();delayMicroseconds(br);segm = a[2];segment();an = 2;ch(SEG_DP, 1);anod();break;
    case 3: segm = 10; segment();an = 10;anod();delayMicroseconds(br);segm = a[3];segment();an = 3;ch(SEG_DP, 1);anod();break;
  }
  i++;if (i > 3) {i = 0;}
  if(millis()-times<500){dpp=1;}
  if(millis()-times>=500 || (second()>=55)){dpp=0;}
  if(millis()-times>1000){times=millis();}
  }

void segment() {
  switch (segm) {
            //  A          B             C              D             E            F            G
    case 0: ch(SEG_A, 0); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 0); ch(SEG_G, 1); break; // 0
    case 1: ch(SEG_A, 1); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 1); ch(SEG_G, 1); break; // 1
    case 2: ch(SEG_A, 0); ch(SEG_B, 0); ch(SEG_C, 1); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 1); ch(SEG_G, 0); break; // 2
    case 3: ch(SEG_A, 0); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 0); ch(SEG_E, 1); ch(SEG_F, 1); ch(SEG_G, 0); break; // 3
    case 4: ch(SEG_A, 1); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 0); ch(SEG_G, 0); break; // 4
    case 5: ch(SEG_A, 0); ch(SEG_B, 1); ch(SEG_C, 0); ch(SEG_D, 0); ch(SEG_E, 1); ch(SEG_F, 0); ch(SEG_G, 0); break; // 5
    case 6: ch(SEG_A, 0); ch(SEG_B, 1); ch(SEG_C, 0); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 0); ch(SEG_G, 0); break; // 6
    case 7: ch(SEG_A, 0); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 1); ch(SEG_G, 1); break; // 7
    case 8: ch(SEG_A, 0); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 0); ch(SEG_G, 0); break; // 8
    case 9: ch(SEG_A, 0); ch(SEG_B, 0); ch(SEG_C, 0); ch(SEG_D, 0); ch(SEG_E, 1); ch(SEG_F, 0); ch(SEG_G, 0); break; // 9
   case 11: ch(SEG_A, 1); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 1); ch(SEG_G, 0); break; // -
   case 10: ch(SEG_A, 1); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 1); ch(SEG_G, 1); break; // пусто
   case 12: ch(SEG_A, 0); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 0); ch(SEG_G, 1); break; // C
  }
}

void anod() {
  switch (an) {
    case 0: ch(LED_0, 0); ch(LED_1, 1); ch(LED_2, 1); ch(LED_3, 1); break;
    case 1: ch(LED_0, 1); ch(LED_1, 0); ch(LED_2, 1); ch(LED_3, 1); break;
    case 2: ch(LED_0, 1); ch(LED_1, 1); ch(LED_2, 0); ch(LED_3, 1); break;
    case 3: ch(LED_0, 1); ch(LED_1, 1); ch(LED_2, 1); ch(LED_3, 0); break;
   case 10: ch(LED_0, 1); ch(LED_1, 1); ch(LED_2, 1); ch(LED_3, 1); break;
  }
} 

float dsRead(byte x) {
  byte data[2], addr[8][8], kol = 0;
  while (ds.search(addr[kol])) {  // поиск датчиков, определение адреса и кол-ва датчиков
    kol++;
  } 
  ds.reset_search();  // Сброс поиска датчика
  ds.reset();         // Инициализация, выполняется сброс шины
  ds.select(addr[x]); // Обращение к датчику по адресу
  ds.write(0x44, 0);  // Измерение температуры с переносом данных в память
  ds.reset();         // Инициализация, выполняется сброс шины
  ds.select(addr[x]); // Обращение к датчику по адресу
  ds.write(0xBE);     // Обращение памяти
  for (byte i=0; i<9; i++) data[i]=ds.read();
  int raw=(data[1]<<8)|data[0];
  float value = (float)raw *0.0625 + KORR_T; return value; // Расчет температуры и вывод
}

void ch(int pin, int logic){digitalWrite(pin, logic);}  

Скетч часов нуждается в корректировке двух параметров:

  • #define time_offset   21600  // смещение от UTC 1 час = 3600
  • #define KORR_T  -1.5   // DS18B20 коррекция температуры

При прошивке скетча необходимо временно отключить контакты RX TX от GPS модуля.

Первый параметр это сдвиг в секундах от времени UTC, второй параметр это корректировка показаний температуры датчика.

Рекомендуется устанавливать датчик температуры DS18B20 вне корпуса часов, при установке в корпусе возможен дополнительный нагрев датчика от других элементов схемы.

После включения часов модуль GY-NEO6MV2 начнет искать спутники, на это может потребоваться определенное время, при этом на дисплей будет выводится надпись — -.- — .

Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=8764#p8764

Добавить комментарий

Войти с помощью: