Тема: часы на gps модуле и семисегментных индикаторах
Основная статья - http://rcl-radio.ru/?p=131064
#define SEG_A 7
#define SEG_B 5
#define SEG_C 10
#define SEG_D 12
#define SEG_E 11
#define SEG_F 6
#define SEG_G 4
#define SEG_DP A4
#define LED_0 A1
#define LED_1 A0
#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);}