На рисунке показана схема простых часов на семисегментных индикаторах. Выполнены часы на базе Arduino Nano. В часах можно использовать практически любые (с током свечения сегмента не более 20 мА) семисегментные индикаторы с общим катодом, в частности в проекте используются индикаторы 5161AS.
В часах используется модуль DS3231 который представляет собой часы реального времени.
Как видно на схеме, один из индикаторов перевернут, так его сегмент-точка служит частью двоеточия, которое отображает такт хода секунд. Так как индикатор перевернут необходимо изменить его распайку его контактов.
Управление часами осуществляется тремя кнопка SET, UP и DW. При нажатии на кнопку SET часы переходят в режим коррекции времени, а кнопки UP и DW увеличиваю или уменьшают значение минут или часов. Если не переходить в режим коррекции времени, то кнопки UP и DW позволяют менять яркость свечения индикаторов.
Дополнительно имеется возможность использовать ночной режим работы индикаторов, в нем устанавливается минимально возможная яркость свечения индикаторов с 23 до 7 часов. Для активации этого режима в параметре NIGHT нужно установить 1.
#define NIGHT 1
Скетч:
#define K3 A3 #define K2 A2 #define K1 A1 #define K0 A0 #define SEG_A 8 #define SEG_B 7 #define SEG_C 4 #define SEG_D 5 #define SEG_E 2 #define SEG_F 6 #define SEG_G 9 #define SEG_DP 3 #define SET 10 #define UP 11 #define DW 12 #define NIGHT 1 #include <EEPROM.h> #include <Wire.h> #include <DS3231.h> // http://rcl-radio.ru/wp-content/uploads/2022/10/DS3231.zip DS3231 clock;RTCDateTime DateTime; byte an,segm,a[4],i,dp; int hour,minut,secon,old_sec,hh,mm,set=0; unsigned long times,times1; int brig,br; void setup(){ Wire.begin(); clock.begin(); Serial.begin(9600); cli(); TCCR2A = 0; TCCR2B = 0; TCNT2 = 0; // (16000000/((155+1)x256))=400.64102564103 Hz OCR2A = 155; TCCR2A |= (1 << WGM21); // Prescaler 256 TCCR2B |= (1 << CS22) | (1 << CS21); TIMSK2 |= (1 << OCIE2A); sei(); pinMode(K3,OUTPUT); pinMode(K2,OUTPUT); pinMode(K1,OUTPUT); pinMode(K0,OUTPUT); 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 (SET,INPUT_PULLUP); pinMode (UP,INPUT_PULLUP); pinMode (DW,INPUT_PULLUP); brig = EEPROM.read(100); if(brig>20){brig=1;EEPROM.update(100,brig);} } void loop(){ DateTime = clock.getDateTime();hour = DateTime.hour;minut = DateTime.minute;secon = DateTime.second; if((hour<7||hour>=22)&&NIGHT==1){br=20;}else{br=brig;} if(digitalRead(SET)==LOW){set++;if(set>2){set=0;}delay(200);} hh=hour;mm=minut; if(set==1 && digitalRead(UP)==LOW){hh++;if(hh>23){hh=0;}clock.setDateTime(2023, 9, 5, hh, minut, 0);delay(200);} if(set==1 && digitalRead(DW)==LOW){hh--;if(hh<0){hh=0;}clock.setDateTime(2023, 9, 5, hh, minut, 0);delay(200);} if(set==2 && digitalRead(UP)==LOW){mm++;if(mm>59){mm=0;}clock.setDateTime(2023, 9, 5, hour, mm, 0);delay(200);} if(set==2 && digitalRead(DW)==LOW){mm--;if(mm<0){mm=0;}clock.setDateTime(2023, 9, 5, hour, mm, 0);delay(200);} if(set==0 && digitalRead(UP)==LOW){brig--;if(brig<1){brig=1;}EEPROM.update(100,brig);delay(200);} if(set==0 && digitalRead(DW)==LOW){brig++;if(brig>20){brig=20;}EEPROM.update(100,brig);delay(200);} if(set==1&&millis()-times<200){a[0]=10;a[1]=10;} else{a[0] = hour/10%10; a[1] = hour%10; } if(set==2&&millis()-times<200){a[2]=10;a[3]=10;} else{a[2] = minut/10%10; a[3] = minut%10; } if(set==0){ a[0]=hour/10%10; a[1]=hour%10; a[2]=minut/10%10; a[3]=minut%10; } if(millis()-times>400){times=millis();} if(millis()-times1<500){dp=1;}else{dp=0;} if(old_sec!=secon){old_sec=secon;times1=millis();} delay(100); } void segment() { switch (segm) { // A B C D E F G case 0: 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; // 0 case 1: 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, 0); break; // 1 case 2: ch(SEG_A, 1); ch(SEG_B, 1); ch(SEG_C, 0); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 0); ch(SEG_G, 1); break; // 2 case 3: ch(SEG_A, 1); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 1); ch(SEG_E, 0); ch(SEG_F, 0); ch(SEG_G, 1); break; // 3 case 4: ch(SEG_A, 0); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 1); ch(SEG_G, 1); break; // 4 case 5: ch(SEG_A, 1); ch(SEG_B, 0); ch(SEG_C, 1); ch(SEG_D, 1); ch(SEG_E, 0); ch(SEG_F, 1); ch(SEG_G, 1); break; // 5 case 6: ch(SEG_A, 1); ch(SEG_B, 0); ch(SEG_C, 1); ch(SEG_D, 1); ch(SEG_E, 1); ch(SEG_F, 1); ch(SEG_G, 1); break; // 6 case 7: ch(SEG_A, 1); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 0); ch(SEG_E, 0); ch(SEG_F, 0); ch(SEG_G, 0); break; // 7 case 8: 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; // 8 case 9: ch(SEG_A, 1); ch(SEG_B, 1); ch(SEG_C, 1); ch(SEG_D, 1); ch(SEG_E, 0); ch(SEG_F, 1); ch(SEG_G, 1); break; // 9 case 10: 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; // пусто } } ISR(TIMER2_COMPA_vect){ switch (i) { case 0: segm = 10; segment();an = 10;kat();delayMicroseconds(br*100);segm = a[0];segment();an = 0;kat();ch(SEG_DP, 0);break; case 1: segm = 10; segment();an = 10;kat();delayMicroseconds(br*100);segm = a[1];segment();an = 1;kat();ch(SEG_DP, dp);break; case 2: segm = 10; segment();an = 10;kat();delayMicroseconds(br*100);segm = a[2];segment();an = 2;kat();ch(SEG_DP, dp);break; case 3: segm = 10; segment();an = 10;kat();delayMicroseconds(br*100);segm = a[3];segment();an = 3;kat();ch(SEG_DP, 0);break; } i++;if (i > 3) {i = 0;} } void kat() { switch (an) { case 0: ch(K3, 1); ch(K2, 0); ch(K1, 0); ch(K0, 0); break; case 1: ch(K3, 0); ch(K2, 1); ch(K1, 0); ch(K0, 0); break; case 2: ch(K3, 0); ch(K2, 0); ch(K1, 1); ch(K0, 0); break; case 3: ch(K3, 0); ch(K2, 0); ch(K1, 0); ch(K0, 1); break; case 10: ch(K3, 0); ch(K2, 0); ch(K1, 0); ch(K0, 0); break; } } void ch(int pin, int logic){digitalWrite(pin, logic);}
При подключении индикаторов к плате Arduino не обязательно точно делать по схеме, Вы можете изменить пины подключения поменяв их назначение в скетче:
#define K3 A3 #define K2 A2 #define K1 A1 #define K0 A0 #define SEG_A 8 #define SEG_B 7 #define SEG_C 4 #define SEG_D 5 #define SEG_E 2 #define SEG_F 6 #define SEG_G 9 #define SEG_DP 3 #define SET 10 #define UP 11 #define DW 12
Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=8531#p8531