Часы на GPS модуле и семисегментных индикаторах 0.56′ MAX7219 (LGT8F328)

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 можно сделать простые часы. В часах можно использовать различные семисегментные индикаторы с общим анодом, в данном проекте использованы индикаторы CPS05641 0.56′ на базе драйвера MAX7219.

В качестве микроконтроллера используется плата разработчика LGT8F328P-LQFP32 MiniEVB, которая основана на китайском микроконтроллер LGT8F328p и является клоном популярной AVR ATmega328p (Arduino NANO). Микроконтроллер LGT8F328p практически полностью совместим с микроконтроллером ATmega328p и обладает рядом дополнительных функций и возможностей превышающих ATmega328p.

Дополнительно в часах используется цифровой датчик температуры DS18B20, показания температуры выводится на индикатор каждые 1,5 минуты в течении 5 секунд.

Схема часов

Для правильной работы часов плата LGT8F328P-LQFP32 MiniEVB в Arduino IDE должна иметь следующие параметры:

Скетч:

#define DIN 10
#define CLK 11
#define CS  12

#define RX      2
#define TX      3
#define time_offset   21600  // смещение от UTC 1 час = 3600
#define KORR_T  -4.0   // 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 <SoftwareSerial.h>  
#include <OneWire.h>        // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip                       
  TinyGPSPlus gps;
  SoftwareSerial SoftSerial(TX,RX);   
  OneWire  ds(5); // Вход датчика 18b20
  
  unsigned long times;
  byte last_minute, Second, Minute, Hour, Day, Month;
  int Year;
  int timer,temp;
  bool w=1;
  int min_old;
  int hh,mm,ss;

void setup(){
  Serial.begin(9600);
  SoftSerial.begin(9600);
  pinMode(DIN,OUTPUT);
  pinMode(CLK,OUTPUT);
  pinMode(CS,OUTPUT);
  delay(2);
  digitalWrite(CS,HIGH);digitalWrite(CLK,LOW);digitalWrite(DIN,LOW);
  WriteBit16(0x0F, 0);// тест выкл.
  WriteBit16(0x0C, 1);// вкл. индик.
  WriteBit16(0x0A, 2);// яркость
  WriteBit16(0x09, 0xFF);// дешифраторы вкл.
  WriteBit16(0x0B, 3);// кол-во разрядов
  Serial.println("LED_OK");
  }

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();
        Serial.println("UTC");
        Serial.print(Hour);Serial.print(":");
        Serial.print(Minute);Serial.print(":");
        Serial.println(Second);
      }
      if (gps.date.isValid()){
        Day   = gps.date.day();
        Month = gps.date.month();
        Year  = gps.date.year();
        Serial.print(Day);Serial.print("-");
        Serial.print(Month);Serial.print("-");
        Serial.println(Year);
      }}}
      
      if(last_minute != gps.time.minute()){ w=1;
        last_minute = gps.time.minute();
        setTime(Hour, Minute, Second, Day, Month, Year);
        adjustTime(time_offset);
        Serial.println("UTC+");
        Serial.print(hour());Serial.print(":");
        Serial.print(minute());Serial.print(":");
        Serial.println(second());
        Serial.print(day());Serial.print("-");
        Serial.print(month());Serial.print("-");
        Serial.println(year());
        Serial.println(week_day());
 }

if (millis() > 5000 && gps.charsProcessed() < 10){
    Serial.println("No GPS detected");
    while(true);}
  
  
    
  if(Year>=2023){
 if(millis()-times>=75000){
   temp = int(dsRead(0)*100);delay(200);
   Serial.print("TEMP = ");Serial.println(float(temp)/100.0,1);
   WriteBit16(1, temp/1000%10);
   WriteBit16(2, temp/100%10 + 0xF0);
   WriteBit16(3, temp/10%10);
   WriteBit16(4, 0x0F);
}
 if(millis()-times<75000){
   timer=hour()*100+minute();
   WriteBit16(1, timer/1000%10);
   WriteBit16(2, timer/100%10 + 0xF0);
   WriteBit16(3, timer/10%10);
   WriteBit16(4, timer%10);
   Serial.println("TIMER");
   Serial.print(hour()/10%10);Serial.print(hour()%10);Serial.print(":");
   Serial.print(minute()/10%10);Serial.print(minute()%10);Serial.print(":");
   Serial.print(second()/10%10);Serial.println(second()%10);
   delay(500);
   WriteBit16(1, timer/1000%10);
   WriteBit16(2, timer/100%10);
   WriteBit16(3, timer/10%10);
   WriteBit16(4, timer%10);
   delay(500);
 }
 if(millis()-times>80000){times=millis();}
 }
 else{
   WriteBit16(1, 10);
   WriteBit16(2, 10+0xF0);
   WriteBit16(3, 10);
   WriteBit16(4, 10);
   delay(500);
   WriteBit16(1, 10);
   WriteBit16(2, 10);
   WriteBit16(3, 10);
   WriteBit16(4, 10);
   delay(500);
  }
    
 }  // end loop

byte week_day(){
  byte a = f_div((14 - month()), 12);
  unsigned int y = year() - a;
  byte m = month() + 12 * a - 2;
  unsigned int y4 = f_div(y, 4);
  byte y100 = f_div(y, 100);
  byte y400 = f_div(y, 400);
  byte x = f_div(31 * m, 12);
  byte wd = (day() + y + y4 - y100 + y400 + x) % 7; 
  return wd;
} 

unsigned int f_div(unsigned int x, unsigned int y){
  unsigned int result;
  result = (x - (x % y)) / y;
  return result;
}

void WriteBit16(byte reg, byte data){  
     digitalWrite(CLK,LOW); digitalWrite(CS,LOW);
     for(int i = 7; i >= 0; i--){
        if(((reg >> i) & 1) == 1){digitalWrite(DIN,HIGH);}else{digitalWrite(DIN,LOW);}
        digitalWrite(CLK,HIGH);digitalWrite(CLK,LOW);
        }
     for(int i = 7; i >= 0; i--){
        if(((data >> i) & 1) == 1){digitalWrite(DIN,HIGH);}else{digitalWrite(DIN,LOW);}
        digitalWrite(CLK,HIGH);digitalWrite(CLK,LOW);
        }
     digitalWrite(CS,HIGH);digitalWrite(CLK,LOW);digitalWrite(DIN,LOW);  
  }  

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; // Расчет температуры и вывод
}  

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

  • #define time_offset   21600  // смещение от UTC 1 час = 3600
  • #define KORR_T  -4.0   // DS18B20 коррекция температуры
  • WriteBit16(0x0A, 2)// яркость от 0 до 15

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

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

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

Вывод температуры

Время

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

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

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