Часы с будильником (Arduino)

Часы с будильником состоят из платы Arduino Nano (Uno), LCD индикатора 1602 с I2C модулем на базе микросхемы PCF8574 и модуля часов реального времени DS3231 (ZS-042). На индикатор LCD 1602 крупными цифрами выводятся часы и минуты, обычными цифрами секунды. Будильник в часах один, он позволяет выставить время срабатывания в минутах и часах, предусмотрено его отключение, а так же работа каждый день, в будние дни и по выходным. Установка времени срабатывания будильника осуществляется кнопками «REG», «+» и «-«. Сигнал будильника звучит в течении одной минуты, но если нажать на кнопку «LED»  сигнал будильника можно прервать. Время срабатывания будильника и режим его работы сохраняются в энергонезависимой памяти. Кнопкой «LED» можно включать и отключать подсветку дисплея.

Устанавливать время на часах не нужно, так как предусмотрена коррекция времени при прошивке микроконтроллера. Для этого необходимо раскомментировать строчку:

// clock.setDateTime(__DATE__, __TIME__);

Далее залейте скетч в плату, закомментируйте строчку и залейте скетч повторно.

  #include <Wire.h> 
  #include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
  #include <DS3231.h>//https://github.com/jarzebski/Arduino-DS3231/archive/master.zip // DS3231.zip
  #include <EEPROM.h> 
      DS3231 clock;RTCDateTime DateTime;
      LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей    
      byte v1[8] = {31,31,31,31,31,31,31,31};
      byte v2[8] = {31,31,31, 0, 0, 0, 0, 0};      
      byte v3[8] = { 0, 0, 0, 0, 0,31,31,31};
      byte v4[8] = {31,31, 0, 0, 0, 0,31,31};
      byte v5[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
      byte v6[8] = { 0, 0,14,31,31,14, 0, 0}; //*
      byte v7[8] = { 0, 0, 0, 0, 0, 0,31,31};
      byte v8[8] = { 0, 4,14,14,14,31, 4, 0};// alarm
      int a[4],time,k,reg,m,h,w,i0,led,ton,w1;
      byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
      unsigned long eeprom;
      byte rom0,rom1,rom2;
 
   void setup(){ Wire.begin(); clock.begin(); 
     pinMode(2,INPUT);pinMode(3,INPUT);pinMode(4,INPUT);pinMode(5,INPUT); // кнопки
     pinMode(13,INPUT); // ds3231 SQW
    //clock.setDateTime(__DATE__, __TIME__);
    lcd.init();lcd.backlight();// Включаем подсветку дисплея
    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);
  rom0 = EEPROM.read(0);if(rom0>59){EEPROM.update(0,0);}
  rom1 = EEPROM.read(1);if(rom1>23){EEPROM.update(1,0);}
  rom2 = EEPROM.read(2);if(rom2>3){EEPROM.update(2,0);}
  m=rom0;h=rom1;w=rom2;
  clock.setOutput(DS3231_1HZ);
   }
 
   void loop(){   if(digitalRead(5)==HIGH&&led==0&&w1==0){led=1;lcd.noBacklight();delay(500);}
                  if(digitalRead(5)==HIGH&&led==1&&w1==0){led=0;lcd.backlight();delay(500);}
 
 
                i0++;if(i0>4){i0=0;}
     if(digitalRead(2)==HIGH){k++;reg=1;lcd.clear();delay(300);}if(k>3){k=0;reg=0;}
      if(reg==1) {
          if(k==1){
              if(digitalRead(3)==HIGH){m++;}if(m>59){m=0;}
              if(digitalRead(4)==HIGH){m--;}if(m<0){m=0;}}
          if(k==2){
              if(digitalRead(3)==HIGH){h++;}if(h>23){h=0;}
              if(digitalRead(4)==HIGH){h--;}if(h<0){h=0;}}
          if(k==3){
              if(digitalRead(3)==HIGH){w++;delay(300);}if(w>3){w=0;}
              if(digitalRead(4)==HIGH){w--;delay(300);}if(w<0){w=3;}
 }
  lcd.setCursor(0,0);lcd.print("Alarm ");
 if(i0==1&&k==2){lcd.print("  ");}else{if(h < 10 ){lcd.print("0");}lcd.print(h);} lcd.print(":");
 if(i0==1&&k==1){lcd.print("  ");}else{if(m < 10 ){lcd.print("0");}lcd.print(m);} 
  lcd.setCursor(0,1);
 if(i0==1&&k==3){lcd.print("                 ");}
 if(w==0){lcd.print("every day");}  //каждый день 1234567
 if(w==1){lcd.print("on weekdays");}//по будням 12345
 if(w==2){lcd.print("on weekends");}//по выходным 67
 if(w==3){lcd.print("off");}
 rom0=m;rom1=h;rom2=w;
 eeprom=0;
 } 
 
 if(reg==0){  if(eeprom==1){EEPROM.update(0,rom0);EEPROM.update(1,rom1);EEPROM.update(2,rom2);}
    DateTime=clock.getDateTime();  
    time = DateTime.hour*100+DateTime.minute;
     a[0]=time/1000;
     a[1]=time/100%10;
     a[2]=time/10%10;
     a[3]=time%10%10;
 
 for(i=0;i<4;i++){
      switch(i){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=4,e2=5,e3=6;break;
        case 2: e1=9,e2=10,e3=11;break;
        case 3: e1=13,e2=14,e3=15;break;}
      switch(a[i]){
        case 0: d1=1,d2=2,d3=1,d4=1,d5=3,d6=1;break;
        case 1: d1=2,d2=1,d3=5,d4=7,d5=1,d6=7;break;
        case 2: d1=2,d2=4,d3=1,d4=1,d5=3,d6=3;break;
        case 3: d1=2,d2=4,d3=1,d4=3,d5=3,d6=1;break;
        case 4: d1=1,d2=3,d3=1,d4=5,d5=5,d6=1;break;
        case 5: d1=1,d2=4,d3=2,d4=3,d5=3,d6=1;break;
        case 6: d1=1,d2=4,d3=2,d4=1,d5=3,d6=1;break;
        case 7: d1=2,d2=2,d3=1,d4=5,d5=5,d6=1;break;
        case 8: d1=1,d2=4,d3=1,d4=1,d5=3,d6=1;break;
        case 9: d1=1,d2=4,d3=1,d4=3,d5=3,d6=1;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);
 
 }
   if(digitalRead(13) == HIGH){lcd.setCursor(7,0);lcd.write((uint8_t)6);}else{ lcd.setCursor(7,0);lcd.write((uint8_t)5);}
   //lcd.setCursor(8,0);lcd.write((uint8_t)8);
   lcd.setCursor(7,1);if(DateTime.second<10){lcd.print("0");}lcd.print(DateTime.second);
 
    if(digitalRead(5)==HIGH&&ton==0){lcd.backlight();ton=1;w1=0;delay(300);}
    if(DateTime.hour*60+DateTime.minute!=h*60+m){ton=0;}
 
    if(w==0){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}
    else if(w==1&&(DateTime.dayOfWeek<6)){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}
    else if(w==2&&(DateTime.dayOfWeek>5)){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}
    else {lcd.setCursor(8,0);lcd.write((uint8_t)5);}
   }//reg=0
     eeprom++;
     delay(100);
   }
 
 void pic(){if(ton==0&&(DateTime.hour*60+DateTime.minute==h*60+m)){w1=1;tone(6,1200,500);delay(500);}}

Форум — http://forum.rcl-radio.ru/viewtopic.php?id=66


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

Comments

  1. ошибка компиляции
    Arduino: 1.8.13 (Windows 7), Плата:»Arduino Uno»

    sketch_jan22a:5:20: error: ‘RTCDateTime’ does not name a type; did you mean ‘DateTime’?

    DS3231 clock;RTCDateTime DateTime;

    ^~~~~~~~~~~

    DateTime

    C:\Users\Aexcey\Desktop\sketch_jan22a\sketch_jan22a.ino: In function ‘void setup()’:

    sketch_jan22a:20:38: error: ‘class DS3231’ has no member named ‘begin’

    void setup(){ Wire.begin(); clock.begin();

    ^~~~~

    sketch_jan22a:30:9: error: ‘class DS3231’ has no member named ‘setOutput’

    clock.setOutput(DS3231_1HZ);

    ^~~~~~~~~

    sketch_jan22a:30:19: error: ‘DS3231_1HZ’ was not declared in this scope

    clock.setOutput(DS3231_1HZ);

    ^~~~~~~~~~

    C:\Users\Aexcey\Desktop\sketch_jan22a\sketch_jan22a.ino:30:19: note: suggested alternative: ‘DS3231_h’

    clock.setOutput(DS3231_1HZ);

    ^~~~~~~~~~

    DS3231_h

    C:\Users\Aexcey\Desktop\sketch_jan22a\sketch_jan22a.ino: In function ‘void loop()’:

    sketch_jan22a:64:13: error: expected unqualified-id before ‘=’ token

    DateTime=clock.getDateTime();

    ^

    sketch_jan22a:65:20: error: expected primary-expression before ‘.’ token

    time = DateTime.hour*100+DateTime.minute;

    ^

    sketch_jan22a:65:38: error: expected primary-expression before ‘.’ token

    time = DateTime.hour*100+DateTime.minute;

    ^

    sketch_jan22a:96:34: error: expected primary-expression before ‘.’ token

    lcd.setCursor(7,1);if(DateTime.second<10){lcd.print("0");}lcd.print(DateTime.second);

    ^

    sketch_jan22a:96:80: error: expected primary-expression before '.' token

    lcd.setCursor(7,1);if(DateTime.second<10){lcd.print("0");}lcd.print(DateTime.second);

    ^

    sketch_jan22a:99:16: error: expected primary-expression before '.' token

    if(DateTime.hour*60+DateTime.minute!=h*60+m){ton=0;}

    ^

    sketch_jan22a:99:33: error: expected primary-expression before '.' token

    if(DateTime.hour*60+DateTime.minute!=h*60+m){ton=0;}

    ^

    sketch_jan22a:101:14: error: 'pic' was not declared in this scope

    if(w==0){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}

    ^~~

    sketch_jan22a:102:28: error: expected primary-expression before '.' token

    else if(w==1&&(DateTime.dayOfWeek<6)){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}

    ^

    sketch_jan22a:102:43: error: 'pic' was not declared in this scope

    else if(w==1&&(DateTime.dayOfWeek5)){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}

    ^

    sketch_jan22a:103:43: error: ‘pic’ was not declared in this scope

    else if(w==2&&(DateTime.dayOfWeek>5)){pic();lcd.setCursor(8,0);lcd.write((uint8_t)8);}

    ^~~

    exit status 1

    ‘RTCDateTime’ does not name a type; did you mean ‘DateTime’?

  2. Есть вопрос: как отобразить температуру от модуля DS? При переборе от кнопки REG есть возможность только регулировать будильник.
    Заменить библиотеку DS на рекомендуемую здесь?
    Какие еще могут быть решения?
    От чего зависит мигание точки секунд? (мигает не ритмично)
    Как повлияет замена подтягивающего резистора с номинала 10к на 100к?

    1. Вывод температуры — clock.readTemperature();
      От чего зависит мигание точки секунд? — clock.setOutput(DS3231_1HZ); задает интервал 1 секунда на выходе SQW ds3231
      Как повлияет замена подтягивающего резистора с номинала 10к на 100к? — ??? не знаю, есть рекомендованное значение 10 К
      Заменить библиотеку DS на рекомендуемую здесь? — если есть ошибки компиляции, если их нет менять библиотеку не нужно.

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

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