1 (2022-02-16 05:31:53 отредактировано v1ct0r)

Тема: Простые точные часы на LCD 1602

Приветствую всех!
Люблю простые решения.
Мой девиз — «все гениальное просто, чем проще, тем надежнее».
на просторах нета наткнулся на эти часы
http://rcl-radio.ru/?p=43068&cpage=1#comment-5774
решил их повторить и доработать(довести до ума), чтобы это были действительно ЧАСЫ, а не пародия на них(ни в коем случае  не в обиду автору - замечательная заготовка для затравки smile )
Для 1 варианта кода этих часов(мне не нужны лишние «навороты») ввел свои коррективы.
1. Чуть подправил схему, изменив под нее код, убрав резисторы и запитав кнопки от «земли»
2. ввел в программу обнуление секунд, нажатием двух кнопок.
3. внедрил программную коррекцию для компенсации погрешности кварца, добившись точности 1-2(в течении часа)-3(очень редко) секунды в течении суток, в целом за сутки отклонения пока не было.
4. при выключенном будильнике на дисплее только часы и ничего лишнего, отвлекающего внимание. И еще кое какие не существенные мелочи.

доработанная схема (у себя я еще убрал подстроечный резистор R1, соединив V0 с землей)

http://forum.rcl-radio.ru/uploads/images/2022/02/a6a2912c7900b4f5540022f0e3526e3d.jpg

доработанный скетч

#include <LiquidCrystal.h>
#include <MsTimer2.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7

unsigned long time0;
byte bud = 0, bud0 = 1, s, m, h, m1, h1, kn, kn1, kn2, korr;

void setup() {
  lcd.begin(16, 2);// LCD 16X2
  MsTimer2::set(1000, to_Timer); // задаем период 1с
  MsTimer2::start(); // старт таймера
  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
}

void to_Timer() { //функция таймера
  ++s; // отсчет 1 с
}

void loop() {
  // читаем состояние входов
  kn = digitalRead(6);
  kn1 = digitalRead(5);
  kn2 = digitalRead(4);

  // коррекция времени, опрос кнопок

  if (kn1 == LOW && kn2 == LOW) {  //коррекция секунд
    s = 0;
  }


  if (kn == LOW) {
    korr++;
    if (korr >= 6) {
      korr = 0;
    }
  }
  if (kn1 == LOW && korr == 1) {
    m++;
  }
  if (kn1 == LOW && korr == 2) {
    h++;
  }
  if (kn2 == LOW && korr == 1) {
    m--;
    if (m > 60) {
      m = 0;
    }
  }
  if (kn2 == LOW && korr == 2) {
    h--;
  }
  if (kn1 == LOW && korr == 3) {
    m1++;
    if (m1 > 59) {
      m1 = 0;
      h1++;
    }
  }
  if (kn1 == LOW && korr == 4) {
    h1++;
    if (h1 > 23) {
      h1 = 0;
    }
  }
  // коррекция будильника
  if (kn2 == LOW && korr == 3) {
    m1--;
    if (m1 > 60) {
      m1 = 0;
    }
  }
  if (kn2 == LOW && korr == 4) {
    h1--;
    if (h1 > 24) {
      h1 = 0;
    }
  }
  // активация и диактивация будильника
  if (kn1 == LOW && korr == 5) {
    bud0 = 1;
  }
  if (kn2 == LOW && korr == 5) {
    bud0 = 0;
  }

  // Отсчет времени часов
  if (s > 59) {
    s = 0;
    ++m; // отсчет 1 мин
  }
  if (m > 59) {
    m = 0;
    ++h; // отсчет 1 час
  }
  if (h > 23) {
    h = 0;
  }
  // включение будильника
  if (m != m1) {
    bud = 0;
  };
  // запуск будильника
  if (m == m1 && h == h1 && bud == 0 && bud0 == 1) {
    if (kn1 == LOW || kn2 == LOW) {
      bud = 1;
    }
    for (int i = 0; i < 200; i++) { // пищалка
      digitalWrite(3, HIGH);
      delay(1);
      digitalWrite(3, LOW);
      delay(1);
    }
  }

  // вывод информации на экран 1 строка
  lcd.setCursor(2, 0);
  if (h < 10) {
    lcd.print("0");
  }

  lcd.print(h); // часы
  lcd.print(":");
  if (m < 10 ) {
    lcd.print("0");
  }

  lcd.print(m); // минуты
  lcd.print(":");
  if (s < 10) {
    lcd.print("0");
  }
  lcd.print(s);// секунды
  // -------------------------------------------------- -
  //корректировка точности показаний секунд за сутки возможны варианты
  //зависит от точности кварца у меня отставание примерно 8.5 секунд за час
  //ПРИ целом количестве в час корректируемых секунд будет проще

  //коррекция плюс 2 сек каждые 15 мин

  if ( s == 10  &&  m == 59  )
  {
    s = s + 2;
  }

  if ( s == 10 &&  m == 15  )
  {
    s = s + 2;;
  }

  if ( s == 10 &&  m == 30  )
  {
    s = s + 2;
  }

  if ( s == 10 &&  m == 45  )
  {
    s = s + 2;
  }

  // коррекция плюс 3 секунды каждые 6 часов

  if ( s == 10  &&  m == 0  &&  h == 0 )
  {
    s = s + 3;
  }

  if ( s == 10  &&  m == 0  &&  h == 6 )
  {
    s = s + 3;
  }

  if ( s == 10  &&  m == 0  &&  h == 12 )
  {
    s = s + 3;
  }

  if ( s == 10  &&  m == 0  &&  h == 18 )
  {
    s = s + 3;
  }
  //---------------------------------------------------- -

  if (korr == 1) {
    lcd.print(" set_m");
  }
  if (korr == 2) {
    lcd.print(" set_h");
  }
  // вывод информации на экран 2 строка
  lcd.setCursor(0, 1);

  if ( bud0 == 1) {
    lcd.print(" _");
    if (h1 < 10) {
      lcd.print("0");
    }
    lcd.print(h1); // часы
    lcd.print(":");
    if (m1 < 10 ) {
      lcd.print("0");
    }
    lcd.print(m1); // минуты
    lcd.print("_");
  }

  if ( bud0 == 0) {
    // lcd.print("");
  }
  if ( bud0 == 1 && korr == 5) {
    lcd.print("al on/of");
  }
  if ( bud0 == 0 && korr == 5) {
    lcd.print(" set alarm on ");

  }
  if (korr == 3) {
    lcd.print("set al min");
  }
  if (korr == 4) {
    lcd.print("set al h-r");
  }
  delay(200);
  lcd.clear();
} 

2

Re: Простые точные часы на LCD 1602

И так ходють ходики довольно точно, но...
Хочется большего, а именно больших циферок в режиме " только часы", например таких, как здесь
http://rcl-radio.ru/?p=66530
тема форума
http://forum.rcl-radio.ru/viewtopic.php?id=66

и тут я застрял, не хватает пока знаний в написании кода
Вариантов решения может быть 2
1. доработать скетч выше приведенный, наверно нужно будет добавить к 1602 модуль I2C для LCD на PCF8574
2. упростить схему из http://rcl-radio.ru/?p=66530
удалив модуль DS3231  и запустить часы при помощи таймера

прошу помощи!

3

Re: Простые точные часы на LCD 1602

Тестируйте, схема без изменений

Если не нажимать D6, то кнопки D4 D5 активируют и деактивируют будильник

При нажатии D6
1 нажатие  - корр часов
2 - корр минут
3 корр часов буд
4 корр мин буд

Время будильника заносится в память

Часы работаю от таймера 1, он 16 -битный, если есть погрешность хода меняйте параметр регистра OCR1A:

// (16000000/((15624+1)x1024))=1 Hz
  OCR1A = 15624;

#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7

byte v1[8] = {0b00111,0b00111,0b00111,0b00111,0b00111,0b00111,0b00111,0b00111};
byte v2[8] = {0b00111,0b00111,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000};      
byte v3[8] = {0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b11111,0b11111};
byte v4[8] = {0b11111,0b11111,0b00000,0b00000,0b00000,0b00000,0b11111,0b11111};
byte v5[8] = {0b11100,0b11100,0b00000,0b00000,0b00000,0b00000,0b11100,0b11100};
byte v6[8] = {0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100};
byte v7[8] = {0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b00111,0b00111};
byte v8[8] = {0b11111,0b11111,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000}; 

unsigned long times,times0;
int sec,min,hour;
int min_alarm,hour_alarm;
int menu;
byte a[6],d1,d2,d3,d4,d5,d6,e1,e2,e3,x;
bool w,alarm;


void setup() {
  lcd.begin(16, 2);// LCD 16X2
  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
  lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);
  lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
    cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
// (16000000/((15624+1)x1024))=1 Hz
  OCR1A = 15624;
  TCCR1B |= (1 << WGM12);
// Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  hour_alarm = EEPROM.read(0);min_alarm = EEPROM.read(1);alarm = EEPROM.read(2);
}

void loop(){
  if(millis()-times<500){w=1;}
  if(millis()-times>=500&&millis()-times<600){w=0;}
  if(millis()-times>600){times=millis();}
  if(digitalRead(6)==LOW){menu++;lcd.clear();if(menu>4){menu=0;}delay(300);}
  if((digitalRead(5)==LOW||digitalRead(4)==LOW)&&menu==0&&alarm==0){lcd.clear();alarm=1;times=millis();w=1;lcd.setCursor(0,0);lcd.print("   ALARM ON ");delay(1500);}
  if((digitalRead(5)==LOW||digitalRead(4)==LOW)&&menu==0&&alarm==1){lcd.clear();alarm=0;times=millis();w=1;lcd.setCursor(0,0);lcd.print("   ALARM OFF");delay(1500);}
  
/////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
if(menu==0){
     a[0]=hour/10;
     a[1]=hour%10;
     a[2]=min/10;
     a[3]=min%10;
     a[4]=sec/10;
     a[5]=sec%10;
   for(x=0;x<4;x++){
    switch(x){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
   }digit();}
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");
   lcd.setCursor(14,1);lcd.print(a[4]);lcd.setCursor(15,1);lcd.print(a[5]);  
  if(alarm==0){lcd.setCursor(13,0);lcd.print("OFF");}
  if(alarm==1){lcd.setCursor(13,0);lcd.print(" ON");} 
} 
///////////////////////////////////////////////////////////////////////////////////////////////
///// korr hour
if(menu==1){
  if(digitalRead(5)==LOW){hour++;if(hour>23){hour=23;}delay(500);}
  if(digitalRead(4)==LOW){hour--;if(hour<0){hour=0;}delay(500);}
  if(w==1){
     a[0]=hour/10;
     a[1]=hour%10;
     a[2]=min/10;
     a[3]=min%10;
     a[4]=sec/10;
     a[5]=sec%10;
  }
  else{
     a[0]=10;
     a[1]=10;
     a[2]=min/10;
     a[3]=min%10;
     a[4]=sec/10;
     a[5]=sec%10;
    }
   for(x=0;x<4;x++){
    switch(x){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
   }digit();}
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");
   lcd.setCursor(14,1);lcd.print(a[4]);lcd.setCursor(15,1);lcd.print(a[5]);
}
///// korr min
if(menu==2){
  if(digitalRead(5)==LOW){min++;if(min>59){min=59;}delay(500);}
  if(digitalRead(4)==LOW){min--;if(min<0){min=0;}delay(500);}
  if(w==1){
     a[0]=hour/10;
     a[1]=hour%10;
     a[2]=min/10;
     a[3]=min%10;
     a[4]=sec/10;
     a[5]=sec%10;
  }
  else{
     a[0]=hour/10;
     a[1]=hour%10;
     a[2]=10;
     a[3]=10;
     a[4]=sec/10;
     a[5]=sec%10;
    }
   for(x=0;x<4;x++){
    switch(x){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
   }digit();}
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");
   lcd.setCursor(14,1);lcd.print(a[4]);lcd.setCursor(15,1);lcd.print(a[5]);
}

///// korr hour alarm
if(menu==3){
  if(digitalRead(5)==LOW){hour_alarm++;times=millis();w=1;if(hour_alarm>23){hour_alarm=23;}delay(500);}
  if(digitalRead(4)==LOW){hour_alarm--;times=millis();w=1;if(hour_alarm<0){hour_alarm=0;}delay(500);}
  if(w==1){
     a[0]=hour_alarm/10;
     a[1]=hour_alarm%10;
     a[2]=min_alarm/10;
     a[3]=min_alarm%10;
  }
  else{
     a[0]=10;
     a[1]=10;
     a[2]=min_alarm/10;
     a[3]=min_alarm%10;
    }
   for(x=0;x<4;x++){
    switch(x){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
   }digit();}
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");
   lcd.setCursor(13,0);lcd.print("KOR");lcd.setCursor(13,1);lcd.print("ALR");
}

///// korr min alarm
if(menu==4){
  if(digitalRead(5)==LOW){min_alarm++;times=millis();w=1;if(min_alarm>59){min_alarm=59;}delay(500);}
  if(digitalRead(4)==LOW){min_alarm--;times=millis();w=1;if(min_alarm<0){min_alarm=0;}delay(500);}
  if(w==1){
     a[0]=hour_alarm/10;
     a[1]=hour_alarm%10;
     a[2]=min_alarm/10;
     a[3]=min_alarm%10;
  }
  else{
     a[0]=hour_alarm/10;
     a[1]=hour_alarm%10;
     a[2]=10;
     a[3]=10;
    }
   for(x=0;x<4;x++){
    switch(x){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
   }digit();}
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");
   lcd.setCursor(13,0);lcd.print("KOR");lcd.setCursor(13,1);lcd.print("ALR");
}


/// BUZZER
if(alarm==1 && (hour*100+min==hour_alarm*100+min_alarm)){buzzer();}

if(millis()-times>10000 && w==1){EEPROM.update(0,hour_alarm);EEPROM.update(1,min_alarm);EEPROM.update(2,alarm);menu=0;w=0;} 
delay(100);
}// loop

void buzzer(){
      for (int i = 0; i < 200; i++) { // пищалка
      digitalWrite(3, HIGH);delay(1);digitalWrite(3, LOW);delay(1);}
      }

void digit(){switch(a[x]){
case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
case 10: d1=32,d2=32,d3=32,d4=32,d5=32,d6=32;break;
}
lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}

ISR(TIMER1_COMPA_vect){
  sec++;
  if(sec>59){sec=0;min++;}
  if(min>59){min=0;hour++;}
  if(hour>23){hour=0;}
  }  

4

Re: Простые точные часы на LCD 1602

благодарю liman324
скетч грузится, цифры большие, но есть проблема
попробую сначала сам разобраться, если не получится буду просить помощи smile

5

Re: Простые точные часы на LCD 1602

проблему устранил
не возможно было корректировать часы и минуты,
кнопки "+" и "-" всегда работали как, вкл/выкл будильника.
также ввел обнуление секунд.
ну и удалил избыточные, на мой взгляд команды.
было

  if((digitalRead(5)==LOW||digitalRead(4)==LOW)&&digitalRead(6)==HIGH&&alarm==0){lcd.clear();alarm=1;times=millis();w=1;lcd.setCursor(0,0);lcd.print("   ALARM ON ");delay(1500);}
  if((digitalRead(5)==LOW||digitalRead(4)==LOW)&&digitalRead(6)==HIGH&&alarm==1){lcd.clear();alarm=0;times=millis();w=1;lcd.setCursor(0,0);lcd.print("   ALARM OFF");delay(1500);}
  

стало

 if (menu == 0) {
    if (digitalRead(4) == LOW  && alarm == 0) {
      lcd.clear();
      alarm = 1;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM ON ");
      delay(1000);
    }
    if (digitalRead(4) == LOW  && alarm == 1) {
      lcd.clear();
      alarm = 0;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM OFF");
      delay(1000);
    }
    if (digitalRead(5) == LOW) {
      sec = 0;
    }

буду мучить дальше smile

6

Re: Простые точные часы на LCD 1602

liman324 пишет:

Тестируйте, схема без изменений

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

Пытался разобраться как получаются большие цифры, но дальше стартовых "нулей" дело не идет, т.е. каким образом формируются остальные цифры мне пока недоступно sad

Сделал кое какие изменения в коде под свои капризы.

мой вариант скетча:

#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7


byte v1[8] = {0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111};

byte v2[8] = {0b00111, 0b00111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};
byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v4[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v5[8] = {0b11100, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b11100, 0b11100};
byte v6[8] = {0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100};
byte v7[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00111, 0b00111};
byte v8[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};

unsigned long times, times0;
int sec, min, hour;
int min_alarm, hour_alarm;
int menu;
byte a[6], d1, d2, d3, d4, d5, d6, e1, e2, e3, x;
bool w, alarm;


void setup() {
  lcd.begin(16, 2);// LCD 16X2
  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
  lcd.createChar(1, v1); lcd.createChar(2, v2); lcd.createChar(3, v3); lcd.createChar(4, v4);
  lcd.createChar(5, v5); lcd.createChar(6, v6); lcd.createChar(7, v7); lcd.createChar(8, v8);
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // (16000000/((15624+1)x1024))=1 Hz
  //OCR1A = 15624;       // корректировка точности часов
  //OCR1A = 15587; 
  OCR1A = 15570;
  TCCR1B |= (1 << WGM12);
  // Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  if (EEPROM.read(100) != 0) {
    for (int i = 0; i < 101; i++) {
      EEPROM.update(i, 0); // очистка памяти при первом включении
    }
  }
  hour_alarm = EEPROM.read(0); min_alarm = EEPROM.read(1); alarm = EEPROM.read(2);
}

void loop() {
  if (millis() - times < 500) {
    w = 1;
  }
  if (millis() - times >= 500 && millis() - times < 600) {
    w = 0;
  }
  if (millis() - times > 600) {
    times = millis();
  }
  if (digitalRead(6) == LOW) {
    menu++;
    lcd.clear();
    if (menu > 4) {
      menu = 0;
    } delay(300);
  }

  if (menu == 0) {
    if (digitalRead(4) == LOW  && alarm == 0) {
      lcd.clear();
      alarm = 1;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM ON ");
      delay(1000);
    }
    if (digitalRead(4) == LOW  && alarm == 1) {
      lcd.clear();
      alarm = 0;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM OFF");
      delay(1000);
    }
    if (digitalRead(5) == LOW) {
      sec = 0;
    }


  }
  /////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
  if (menu == 0) {
    a[0] = hour / 10;
    a[1] = hour % 10;
    a[2] = min / 10;
    a[3] = min % 10;
    a[4] = sec / 10;
    a[5] = sec % 10;
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
    if (alarm == 0) {
      lcd.setCursor(13, 0);
      //lcd.print("off");
    }
    if (alarm == 1) {
      lcd.setCursor(13, 0);
      lcd.print(" on");
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ///// korr hour
  if (menu == 1) {
    if (digitalRead(5) == LOW) {
      hour++;
      if (hour > 23) {
        hour = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour--;
      if (hour < 0) {
        hour = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }
  ///// korr min
  if (menu == 2) {
    if (digitalRead(5) == LOW) {
      min++;
      if (min > 59) {
        min = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min--;
      if (min < 0) {
        min = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = 10;
      a[3] = 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }

  ///// korr hour alarm
  if (menu == 3) {
    if (digitalRead(5) == LOW) {
      hour_alarm++;
      times = millis();
      w = 1;
      if (hour_alarm > 23) {
        hour_alarm = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour_alarm--;
      times = millis();
      w = 1;
      if (hour_alarm < 0) {
        hour_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }

  ///// korr min alarm
  if (menu == 4) {
    if (digitalRead(5) == LOW) {
      min_alarm++;
      times = millis();
      w = 1;
      if (min_alarm > 59) {
        min_alarm = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min_alarm--;
      times = millis();
      w = 1;
      if (min_alarm < 0) {
        min_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = 10;
      a[3] = 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }


  /// BUZZER
  if (alarm == 1 && (hour * 100 + min == hour_alarm * 100 + min_alarm)) {
    buzzer();
  }

  if (millis() - times > 10000 && w == 1) {
    EEPROM.update(0, hour_alarm);
    EEPROM.update(1, min_alarm);
    EEPROM.update(2, alarm);
    menu = 0;
    w = 0;
  }
  delay(100);
}// loop

void buzzer() {
  for (int i = 0; i < 200; i++) { // пищалка
    digitalWrite(3, HIGH); delay(1); digitalWrite(3, LOW); delay(1);
  }
}

void digit() {
  switch (a[x]) {
    case 0: d1 = 1, d2 = 8, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 1: d1 = 32, d2 = 2, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 2: d1 = 2, d2 = 8, d3 = 6, d4 = 1, d5 = 4, d6 = 5; break; case 3: d1 = 2, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 4: d1 = 1, d2 = 3, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break; case 5: d1 = 1, d2 = 4, d3 = 5, d4 = 7, d5 = 3, d6 = 6; break;
    case 6: d1 = 1, d2 = 4, d3 = 5, d4 = 1, d5 = 3, d6 = 6; break; case 7: d1 = 1, d2 = 8, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 8: d1 = 1, d2 = 4, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 9: d1 = 1, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 10: d1 = 32, d2 = 32, d3 = 32, d4 = 32, d5 = 32, d6 = 32; break;
  }
  lcd.setCursor(e1, 0); lcd.write((uint8_t)d1); lcd.setCursor(e2, 0); lcd.write((uint8_t)d2); lcd.setCursor(e3, 0); lcd.write((uint8_t)d3);
  lcd.setCursor(e1, 1); lcd.write((uint8_t)d4); lcd.setCursor(e2, 1); lcd.write((uint8_t)d5); lcd.setCursor(e3, 1); lcd.write((uint8_t)d6);
}

ISR(TIMER1_COMPA_vect) {
  sec++;
  if (sec > 59) {
    sec = 0;
    min++;
  }
  if (min > 59) {
    min = 0;
    hour++;
  }
  if (hour > 23) {
    hour = 0;
  }
}

7

Re: Простые точные часы на LCD 1602

сделал разделительные точки ":" мигающими

#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7


byte v1[8] = {0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111};

byte v2[8] = {0b00111, 0b00111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};
byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v4[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v5[8] = {0b11100, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b11100, 0b11100};
byte v6[8] = {0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100};
byte v7[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00111, 0b00111};
byte v8[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};

unsigned long times, times0;
int sec, min, hour;
int min_alarm, hour_alarm;
int menu;
byte a[6], d1, d2, d3, d4, d5, d6, e1, e2, e3, x;
bool w, alarm;


void setup() {
  lcd.begin(16, 2);// LCD 16X2
  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
  lcd.createChar(1, v1); lcd.createChar(2, v2); lcd.createChar(3, v3); lcd.createChar(4, v4);
  lcd.createChar(5, v5); lcd.createChar(6, v6); lcd.createChar(7, v7); lcd.createChar(8, v8);
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // (16000000/((15624+1)x1024))=1 Hz
  //OCR1A = 15624;       // корректировка точности часов
  //OCR1A = 15587;
  OCR1A = 15570;
  TCCR1B |= (1 << WGM12);
  // Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  if (EEPROM.read(100) != 0) {
    for (int i = 0; i < 101; i++) {
      EEPROM.update(i, 0); // очистка памяти при первом включении
    }
  }
  hour_alarm = EEPROM.read(0); min_alarm = EEPROM.read(1); alarm = EEPROM.read(2);
}

void loop() {
  if (millis() - times < 500) {
    w = 1;
  }
  if (millis() - times >= 500 && millis() - times < 600) {
    w = 0;
  }
  if (millis() - times > 600) {
    times = millis();
  }
  if (digitalRead(6) == LOW) {
    menu++;
    lcd.clear();
    if (menu > 4) {
      menu = 0;
    } delay(300);
  }

  if (menu == 0) {
    if (digitalRead(4) == LOW  && alarm == 0) {
      lcd.clear();
      alarm = 1;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM ON ");
      delay(1000);
    }
    if (digitalRead(4) == LOW  && alarm == 1) {
      lcd.clear();
      alarm = 0;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM OFF");
      delay(1000);
    }
    if (digitalRead(5) == LOW) {    //сброс секунд
      sec = 0;
    }


  }
  /////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
  if (menu == 0) {
    a[0] = hour / 10;
    a[1] = hour % 10;
    a[2] = min / 10;
    a[3] = min % 10;
    a[4] = sec / 10;
    a[5] = sec % 10;
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print("."); delay(500);
    lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(6, 1); lcd.print(" "); delay(500); // мигание точек в режиме часы
    
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
    if (alarm == 0) {
      lcd.setCursor(13, 0);
      //lcd.print("off");
    }
    if (alarm == 1) {
      lcd.setCursor(13, 0);
      lcd.print(" on");
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ///// korr hour
  if (menu == 1) {
    if (digitalRead(5) == LOW) {
      hour++;
      if (hour > 23) {
        hour = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour--;
      if (hour < 0) {
        hour = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }
  ///// korr min
  if (menu == 2) {
    if (digitalRead(5) == LOW) {
      min++;
      if (min > 59) {
        min = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min--;
      if (min < 0) {
        min = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = 10;
      a[3] = 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }

  ///// korr hour alarm
  if (menu == 3) {
    if (digitalRead(5) == LOW) {
      hour_alarm++;
      times = millis();
      w = 1;
      if (hour_alarm > 23) {
        hour_alarm = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour_alarm--;
      times = millis();
      w = 1;
      if (hour_alarm < 0) {
        hour_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }

  ///// korr min alarm
  if (menu == 4) {
    if (digitalRead(5) == LOW) {
      min_alarm++;
      times = millis();
      w = 1;
      if (min_alarm > 59) {
        min_alarm = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min_alarm--;
      times = millis();
      w = 1;
      if (min_alarm < 0) {
        min_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = 10;
      a[3] = 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }


  /// BUZZER
  if (alarm == 1 && (hour * 100 + min == hour_alarm * 100 + min_alarm)) {
    buzzer();
  }

  if (millis() - times > 10000 && w == 1) {
    EEPROM.update(0, hour_alarm);
    EEPROM.update(1, min_alarm);
    EEPROM.update(2, alarm);
    menu = 0;
    w = 0;
  }
  delay(100);
}// loop

void buzzer() {
  for (int i = 0; i < 200; i++) { // пищалка
    digitalWrite(3, HIGH); delay(1); digitalWrite(3, LOW); delay(1);
  }
}

void digit() {
  switch (a[x]) {
    case 0: d1 = 1, d2 = 8, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 1: d1 = 32, d2 = 2, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 2: d1 = 2, d2 = 8, d3 = 6, d4 = 1, d5 = 4, d6 = 5; break; case 3: d1 = 2, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 4: d1 = 1, d2 = 3, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break; case 5: d1 = 1, d2 = 4, d3 = 5, d4 = 7, d5 = 3, d6 = 6; break;
    case 6: d1 = 1, d2 = 4, d3 = 5, d4 = 1, d5 = 3, d6 = 6; break; case 7: d1 = 1, d2 = 8, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 8: d1 = 1, d2 = 4, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 9: d1 = 1, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 10: d1 = 32, d2 = 32, d3 = 32, d4 = 32, d5 = 32, d6 = 32; break;
  }
  lcd.setCursor(e1, 0); lcd.write((uint8_t)d1); lcd.setCursor(e2, 0); lcd.write((uint8_t)d2); lcd.setCursor(e3, 0); lcd.write((uint8_t)d3);
  lcd.setCursor(e1, 1); lcd.write((uint8_t)d4); lcd.setCursor(e2, 1); lcd.write((uint8_t)d5); lcd.setCursor(e3, 1); lcd.write((uint8_t)d6);
}

ISR(TIMER1_COMPA_vect) {
  sec++;
  if (sec > 59) {
    sec = 0;
    min++;
  }
  if (min > 59) {
    min = 0;
    hour++;
  }
  if (hour > 23) {
    hour = 0;
  }
}

8 (2022-02-19 16:41:47 отредактировано v1ct0r)

Re: Простые точные часы на LCD 1602

v1ct0r пишет:

сделал разделительные точки ":" мигающими

переделал на millis

#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7


byte v1[8] = {0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111};

byte v2[8] = {0b00111, 0b00111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};
byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v4[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v5[8] = {0b11100, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b11100, 0b11100};
byte v6[8] = {0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100};
byte v7[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00111, 0b00111};
byte v8[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};

unsigned long  times, times0, times1;
int sec, min, hour;
int min_alarm, hour_alarm;
int menu;
byte a[6], d1, d2, d3, d4, d5, d6, e1, e2, e3, x;
bool w, alarm;


void setup() {
  lcd.begin(16, 2);// LCD 16X2
  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
  lcd.createChar(1, v1); lcd.createChar(2, v2); lcd.createChar(3, v3); lcd.createChar(4, v4);
  lcd.createChar(5, v5); lcd.createChar(6, v6); lcd.createChar(7, v7); lcd.createChar(8, v8);
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // (16000000/((15624+1)x1024))=1 Hz
  //OCR1A = 15624;       // корректировка точности часов
  //OCR1A = 15587;//предварительный расчет
  
  OCR1A = 15586;

  TCCR1B |= (1 << WGM12);
  // Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  if (EEPROM.read(100) != 0) {
    for (int i = 0; i < 101; i++) {
      EEPROM.update(i, 0); // очистка памяти при первом включении
    }
  }
  hour_alarm = EEPROM.read(0); min_alarm = EEPROM.read(1); alarm = EEPROM.read(2);
}

void loop() {
  if (millis() - times < 500) {
    w = 1;
  }
  if (millis() - times >= 500 && millis() - times < 600) {
    w = 0;
  }
  if (millis() - times > 600) {
    times = millis();
  }
  if (digitalRead(6) == LOW) {
    menu++;
    lcd.clear();
    if (menu > 4) {
      menu = 0;
    } delay(300);
  }

  if (menu == 0) {
    if (digitalRead(4) == LOW  && alarm == 0) {
      lcd.clear();
      alarm = 1;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM ON ");
      delay(1000);
    }
    if (digitalRead(4) == LOW  && alarm == 1) {
      lcd.clear();
      alarm = 0;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM OFF");
      delay(1000);
    }
    if (digitalRead(5) == LOW) {    //сброс секунд
      sec = 0;
    }
  }
  /////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
  if (menu == 0) {
    a[0] = hour / 10;
    a[1] = hour % 10;
    a[2] = min / 10;
    a[3] = min % 10;
    a[4] = sec / 10;
    a[5] = sec % 10;
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    /////////// мигание точек в режиме часы ////////////////////////////////
    if (millis() - times1  > 900) {
      lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(6, 1); lcd.print(" ");
      times1 = millis() ;
      delay(100);
    }
    else {
      lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    }
    ////////////////////////////////////////////////////////////////////////////////////////

    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
    if (alarm == 0) {
      lcd.setCursor(13, 0);
      //lcd.print("off");
    }
    if (alarm == 1) {
      lcd.setCursor(13, 0);
      lcd.print(" on");
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ///// korr hour
  if (menu == 1) {
    if (digitalRead(5) == LOW) {
      hour++;
      if (hour > 23) {
        hour = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour--;
      if (hour < 0) {
        hour = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }
  ///// korr min
  if (menu == 2) {
    if (digitalRead(5) == LOW) {
      min++;
      if (min > 59) {
        min = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min--;
      if (min < 0) {
        min = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = 10;
      a[3] = 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }

  ///// korr hour alarm
  if (menu == 3) {
    if (digitalRead(5) == LOW) {
      hour_alarm++;
      times = millis();
      w = 1;
      if (hour_alarm > 23) {
        hour_alarm = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour_alarm--;
      times = millis();
      w = 1;
      if (hour_alarm < 0) {
        hour_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }

  ///// korr min alarm
  if (menu == 4) {
    if (digitalRead(5) == LOW) {
      min_alarm++;
      times = millis();
      w = 1;
      if (min_alarm > 59) {
        min_alarm = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min_alarm--;
      times = millis();
      w = 1;
      if (min_alarm < 0) {
        min_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = 10;
      a[3] = 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }


  /// BUZZER
  if (alarm == 1 && (hour * 100 + min == hour_alarm * 100 + min_alarm)) {
    buzzer();
  }

  if (millis() - times > 10000 && w == 1) {
    EEPROM.update(0, hour_alarm);
    EEPROM.update(1, min_alarm);
    EEPROM.update(2, alarm);
    menu = 0;
    w = 0;
  }
  delay(100);
}// loop

void buzzer() {
  for (int i = 0; i < 200; i++) { // пищалка
    digitalWrite(3, HIGH); delay(1); digitalWrite(3, LOW); delay(1);
  }
}

void digit() {
  switch (a[x]) {
    case 0: d1 = 1, d2 = 8, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 1: d1 = 32, d2 = 2, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 2: d1 = 2, d2 = 8, d3 = 6, d4 = 1, d5 = 4, d6 = 5; break; case 3: d1 = 2, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 4: d1 = 1, d2 = 3, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break; case 5: d1 = 1, d2 = 4, d3 = 5, d4 = 7, d5 = 3, d6 = 6; break;
    case 6: d1 = 1, d2 = 4, d3 = 5, d4 = 1, d5 = 3, d6 = 6; break; case 7: d1 = 1, d2 = 8, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 8: d1 = 1, d2 = 4, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 9: d1 = 1, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 10: d1 = 32, d2 = 32, d3 = 32, d4 = 32, d5 = 32, d6 = 32; break;
  }
  lcd.setCursor(e1, 0); lcd.write((uint8_t)d1); lcd.setCursor(e2, 0); lcd.write((uint8_t)d2); lcd.setCursor(e3, 0); lcd.write((uint8_t)d3);
  lcd.setCursor(e1, 1); lcd.write((uint8_t)d4); lcd.setCursor(e2, 1); lcd.write((uint8_t)d5); lcd.setCursor(e3, 1); lcd.write((uint8_t)d6);
}

ISR(TIMER1_COMPA_vect) {
  sec++;
  if (sec > 59) {
    sec = 0;
    min++;
  }
  if (min > 59) {
    min = 0;
    hour++;
  }
  if (hour > 23) {
    hour = 0;
  }
}

9 (2022-08-23 18:24:07 отредактировано v1ct0r)

Re: Простые точные часы на LCD 1602

здравствуйте еще раз!
моя новая хотелка, к которой хочется привязать скетч из предыдущего поста

http://forum.rcl-radio.ru/uploads/images/2022/08/536a68c9f7fa301cbd05c8696a277ee2.jpg

исходный скетч

#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7


byte v1[8] = {0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111};

byte v2[8] = {0b00111, 0b00111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};
byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v4[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v5[8] = {0b11100, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b11100, 0b11100};
byte v6[8] = {0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100};
byte v7[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00111, 0b00111};
byte v8[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};

unsigned long  times, times0, times1;
int sec, min, hour;
int min_alarm, hour_alarm;
int menu;
byte a[6], d1, d2, d3, d4, d5, d6, e1, e2, e3, x;
bool w, alarm;


void setup() {
  lcd.begin(16, 2);// LCD 16X2
  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
  lcd.createChar(1, v1); lcd.createChar(2, v2); lcd.createChar(3, v3); lcd.createChar(4, v4);
  lcd.createChar(5, v5); lcd.createChar(6, v6); lcd.createChar(7, v7); lcd.createChar(8, v8);
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // (16000000/((15624+1)x1024))=1 Hz
  //OCR1A = 15624;       // корректировка точности часов
  //OCR1A = 15587;//предварительный расчет
  
  OCR1A = 15587;

  TCCR1B |= (1 << WGM12);
  // Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  if (EEPROM.read(100) != 0) {
    for (int i = 0; i < 101; i++) {
      EEPROM.update(i, 0); // очистка памяти при первом включении
    }
  }
  hour_alarm = EEPROM.read(0); min_alarm = EEPROM.read(1); alarm = EEPROM.read(2);
}

void loop() {
  if (millis() - times < 500) {
    w = 1;
  }
  if (millis() - times >= 500 && millis() - times < 600) {
    w = 0;
  }
  if (millis() - times > 600) {
    times = millis();
  }
  if (digitalRead(6) == LOW) {
    menu++;
    lcd.clear();
    if (menu > 4) {
      menu = 0;
    } delay(300);
  }

  if (menu == 0) {
    if (digitalRead(4) == LOW  && alarm == 0) {
      lcd.clear();
      alarm = 1;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM ON ");
      delay(1000);
    }
    if (digitalRead(4) == LOW  && alarm == 1) {
      lcd.clear();
      alarm = 0;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM OFF");
      delay(1000);
    }
    if (digitalRead(5) == LOW) {    //сброс секунд
      sec = 0;
    }
  }
  /////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
  if (menu == 0) {
    a[0] = hour / 10;
    a[1] = hour % 10;
    a[2] = min / 10;
    a[3] = min % 10;
    a[4] = sec / 10;
    a[5] = sec % 10;
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    /////////// мигание точек в режиме часы ////////////////////////////////
    if (millis() - times1  > 900) {
      lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(6, 1); lcd.print(" ");
      times1 = millis() ;
      delay(100);
    }
    else {
      lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    }
    ////////////////////////////////////////////////////////////////////////////////////////

    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
    if (alarm == 0) {
      lcd.setCursor(13, 0);
      //lcd.print("off");
    }
    if (alarm == 1) {
      lcd.setCursor(13, 0);
      lcd.print(" on");
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ///// korr hour
  if (menu == 1) {
    if (digitalRead(5) == LOW) {
      hour++;
      if (hour > 23) {
        hour = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour--;
      if (hour < 0) {
        hour = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }
  ///// korr min
  if (menu == 2) {
    if (digitalRead(5) == LOW) {
      min++;
      if (min > 59) {
        min = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min--;
      if (min < 0) {
        min = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = 10;
      a[3] = 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }

  ///// korr hour alarm
  if (menu == 3) {
    if (digitalRead(5) == LOW) {
      hour_alarm++;
      times = millis();
      w = 1;
      if (hour_alarm > 23) {
        hour_alarm = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour_alarm--;
      times = millis();
      w = 1;
      if (hour_alarm < 0) {
        hour_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }

  ///// korr min alarm
  if (menu == 4) {
    if (digitalRead(5) == LOW) {
      min_alarm++;
      times = millis();
      w = 1;
      if (min_alarm > 59) {
        min_alarm = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min_alarm--;
      times = millis();
      w = 1;
      if (min_alarm < 0) {
        min_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = 10;
      a[3] = 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }


  /// BUZZER
  if (alarm == 1 && (hour * 100 + min == hour_alarm * 100 + min_alarm)) {
    buzzer();
  }

  if (millis() - times > 10000 && w == 1) {
    EEPROM.update(0, hour_alarm);
    EEPROM.update(1, min_alarm);
    EEPROM.update(2, alarm);
    menu = 0;
    w = 0;
  }
  delay(100);
}// loop

void buzzer() {
  for (int i = 0; i < 200; i++) { // пищалка
    digitalWrite(3, HIGH); delay(1); digitalWrite(3, LOW); delay(1);
  }
}

void digit() {
  switch (a[x]) {
    case 0: d1 = 1, d2 = 8, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 1: d1 = 32, d2 = 2, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 2: d1 = 2, d2 = 8, d3 = 6, d4 = 1, d5 = 4, d6 = 5; break; case 3: d1 = 2, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 4: d1 = 1, d2 = 3, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break; case 5: d1 = 1, d2 = 4, d3 = 5, d4 = 7, d5 = 3, d6 = 6; break;
    case 6: d1 = 1, d2 = 4, d3 = 5, d4 = 1, d5 = 3, d6 = 6; break; case 7: d1 = 1, d2 = 8, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 8: d1 = 1, d2 = 4, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break; case 9: d1 = 1, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 10: d1 = 32, d2 = 32, d3 = 32, d4 = 32, d5 = 32, d6 = 32; break;
  }
  lcd.setCursor(e1, 0); lcd.write((uint8_t)d1); lcd.setCursor(e2, 0); lcd.write((uint8_t)d2); lcd.setCursor(e3, 0); lcd.write((uint8_t)d3);
  lcd.setCursor(e1, 1); lcd.write((uint8_t)d4); lcd.setCursor(e2, 1); lcd.write((uint8_t)d5); lcd.setCursor(e3, 1); lcd.write((uint8_t)d6);
}

ISR(TIMER1_COMPA_vect) {
  sec++;
  if (sec > 59) {
    sec = 0;
    min++;
  }
  if (min > 59) {
    min = 0;
    hour++;
  }
  if (hour > 23) {
    hour = 0;
  }
}

правильно ли я мыслю по поводу изменений в исходном скетче или чего то не хватает?

#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
//Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1

LiquidCrystal_I2C lcd(0x27, 16, 2); // Устанавливаем дисплей
byte v1[8] = {0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111, 0b00111};
byte v2[8] = {0b00111, 0b00111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};
byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v4[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v5[8] = {0b11100, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b11100, 0b11100};
byte v6[8] = {0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100};
byte v7[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00111, 0b00111};
byte v8[8] = {0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};

unsigned long  times, times0, times1;
int sec, min, hour;
int min_alarm, hour_alarm;
int menu;
byte a[6], d1, d2, d3, d4, d5, d6, e1, e2, e3, x;
bool w, alarm;


void setup() {
  Wire.begin();

  lcd.init(); lcd.backlight(); // Включаем подсветку дисплея
  //lcd.noBacklight();// Выключаем подсветку дисплея

  pinMode(6, INPUT_PULLUP); // кнопка коррекции
  pinMode(5, INPUT_PULLUP); // кнопка +
  pinMode(4, INPUT_PULLUP); // кнопка -
  pinMode(3, OUTPUT); // выход для пъезоизлучателя
  lcd.createChar(1, v1); lcd.createChar(2, v2); lcd.createChar(3, v3); lcd.createChar(4, v4);
  lcd.createChar(5, v5); lcd.createChar(6, v6); lcd.createChar(7, v7); lcd.createChar(8, v8);
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  // (16000000/((15624+1)x1024))=1 Hz
  //OCR1A = 15624;       // корректировка точности часов
  //OCR1A = 15587;//предварительный расчет

  OCR1A = 15587;

  TCCR1B |= (1 << WGM12);
  // Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  if (EEPROM.read(100) != 0) {
    for (int i = 0; i < 101; i++) {
      EEPROM.update(i, 0); // очистка памяти при первом включении
    }
  }
  hour_alarm = EEPROM.read(0); min_alarm = EEPROM.read(1); alarm = EEPROM.read(2);
}

void loop() {
  if (millis() - times < 500) {
    w = 1;
  }
  if (millis() - times >= 500 && millis() - times < 600) {
    w = 0;
  }
  if (millis() - times > 600) {
    times = millis();
  }
  if (digitalRead(6) == LOW) {
    menu++;
    lcd.clear();
    if (menu > 4) {
      menu = 0;
    } delay(300);
  }

  if (menu == 0) {
    if (digitalRead(4) == LOW  && alarm == 0) {
      lcd.clear();
      alarm = 1;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM ON ");
      delay(1000);
    }
    if (digitalRead(4) == LOW  && alarm == 1) {
      lcd.clear();
      alarm = 0;
      times = millis();
      w = 1;
      lcd.setCursor(0, 0);
      lcd.print("   ALARM OFF");
      delay(1000);
    }
    if (digitalRead(5) == LOW) {    //сброс секунд
      sec = 0;
    }
  }
  /////////////////// ЧАСЫ /////////////////////////////////////////////////
  if (menu == 0) {
    a[0] = hour / 10;
    a[1] = hour % 10;
    a[2] = min / 10;
    a[3] = min % 10;
    a[4] = sec / 10;
    a[5] = sec % 10;
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    /////////// мигание точек в режиме часы ////////////////////////////////
    if (millis() - times1  > 900) {
      lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(6, 1); lcd.print(" ");
      times1 = millis() ;
      delay(100);
    }
    else {
      lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    }
    ///////////////////////////////////////////////////////////////////////////

    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
    if (alarm == 0) {
      lcd.setCursor(13, 0);
      //lcd.print("off");
    }
    if (alarm == 1) {
      lcd.setCursor(13, 0);
      lcd.print(" on");
    }
  }
  /////////////////////////////////////////////////////////////////////////////////
  ///// korr hour
  if (menu == 1) {
    if (digitalRead(5) == LOW) {
      hour++;
      if (hour > 23) {
        hour = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour--;
      if (hour < 0) {
        hour = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }
  ///// korr min
  if (menu == 2) {
    if (digitalRead(5) == LOW) {
      min++;
      if (min > 59) {
        min = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min--;
      if (min < 0) {
        min = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = min / 10;
      a[3] = min % 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    else {
      a[0] = hour / 10;
      a[1] = hour % 10;
      a[2] = 10;
      a[3] = 10;
      a[4] = sec / 10;
      a[5] = sec % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(14, 1); lcd.print(a[4]); lcd.setCursor(15, 1); lcd.print(a[5]);
  }

  ///// korr hour alarm
  if (menu == 3) {
    if (digitalRead(5) == LOW) {
      hour_alarm++;
      times = millis();
      w = 1;
      if (hour_alarm > 23) {
        hour_alarm = 23;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      hour_alarm--;
      times = millis();
      w = 1;
      if (hour_alarm < 0) {
        hour_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = 10;
      a[1] = 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }

  ///// korr min alarm
  if (menu == 4) {
    if (digitalRead(5) == LOW) {
      min_alarm++;
      times = millis();
      w = 1;
      if (min_alarm > 59) {
        min_alarm = 59;
      } delay(100);
    }
    if (digitalRead(4) == LOW) {
      min_alarm--;
      times = millis();
      w = 1;
      if (min_alarm < 0) {
        min_alarm = 0;
      } delay(100);
    }
    if (w == 1) {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = min_alarm / 10;
      a[3] = min_alarm % 10;
    }
    else {
      a[0] = hour_alarm / 10;
      a[1] = hour_alarm % 10;
      a[2] = 10;
      a[3] = 10;
    }
    for (x = 0; x < 4; x++) {
      switch (x) {
        case 0: e1 = 0, e2 = 1, e3 = 2; break;
        case 1: e1 = 3, e2 = 4, e3 = 5; break;
        case 2: e1 = 7, e2 = 8, e3 = 9; break;
        case 3: e1 = 10, e2 = 11, e3 = 12; break;
      } digit();
    }
    lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print(".");
    lcd.setCursor(13, 0); lcd.print("KOR"); lcd.setCursor(13, 1); lcd.print("ALR");
  }


  /// BUZZER
  if (alarm == 1 && (hour * 100 + min == hour_alarm * 100 + min_alarm)) {
    buzzer();
  }

  if (millis() - times > 10000 && w == 1) {
    EEPROM.update(0, hour_alarm);
    EEPROM.update(1, min_alarm);
    EEPROM.update(2, alarm);
    menu = 0;
    w = 0;
  }
  delay(100);
}// loop

void buzzer() {
  for (int i = 0; i < 200; i++) { // пищалка
    digitalWrite(3, HIGH); delay(1); digitalWrite(3, LOW); delay(1);
  }
}

void digit() {
  switch (a[x]) {
    case 0: d1 = 1, d2 = 8, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break;
    case 1: d1 = 32, d2 = 2, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 2: d1 = 2, d2 = 8, d3 = 6, d4 = 1, d5 = 4, d6 = 5; break;
    case 3: d1 = 2, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 4: d1 = 1, d2 = 3, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 5: d1 = 1, d2 = 4, d3 = 5, d4 = 7, d5 = 3, d6 = 6; break;
    case 6: d1 = 1, d2 = 4, d3 = 5, d4 = 1, d5 = 3, d6 = 6; break;
    case 7: d1 = 1, d2 = 8, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 8: d1 = 1, d2 = 4, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break;
    case 9: d1 = 1, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 10: d1 = 32, d2 = 32, d3 = 32, d4 = 32, d5 = 32, d6 = 32; break;
  }
  lcd.setCursor(e1, 0); lcd.write((uint8_t)d1); lcd.setCursor(e2, 0);
  lcd.write((uint8_t)d2); lcd.setCursor(e3, 0); lcd.write((uint8_t)d3);
  lcd.setCursor(e1, 1); lcd.write((uint8_t)d4); lcd.setCursor(e2, 1);
  lcd.write((uint8_t)d5); lcd.setCursor(e3, 1); lcd.write((uint8_t)d6);
}

ISR(TIMER1_COMPA_vect) {
  sec++;
  if (sec > 59) {
    sec = 0;
    min++;
  }
  if (min > 59) {
    min = 0;
    hour++;
  }
  if (hour > 23) {
    hour = 0;
  }
}

10

Re: Простые точные часы на LCD 1602

Все верно.

11

Re: Простые точные часы на LCD 1602

Благодарю!
буду пробовать.

12

Re: Простые точные часы на LCD 1602

все работает!
изменил форму некоторых цифр под свои предпочтения (1, 4, 7)

void digit() {
  switch (a[x]) {
    case 0: d1 = 1, d2 = 8, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break;
    case 1: d1 = 32, d2 = 32, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 2: d1 = 2, d2 = 8, d3 = 6, d4 = 1, d5 = 4, d6 = 5; break;
    case 3: d1 = 2, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 4: d1 = 1, d2 = 32, d3 = 6, d4 = 2, d5 = 8, d6 = 6; break;
    case 5: d1 = 1, d2 = 4, d3 = 5, d4 = 7, d5 = 3, d6 = 6; break;
    case 6: d1 = 1, d2 = 4, d3 = 5, d4 = 1, d5 = 3, d6 = 6; break;
    case 7: d1 = 2, d2 = 8, d3 = 6, d4 = 32, d5 = 32, d6 = 6; break;
    case 8: d1 = 1, d2 = 4, d3 = 6, d4 = 1, d5 = 3, d6 = 6; break;
    case 9: d1 = 1, d2 = 4, d3 = 6, d4 = 7, d5 = 3, d6 = 6; break;
    case 10: d1 = 32, d2 = 32, d3 = 32, d4 = 32, d5 = 32, d6 = 32; break;
  }