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

Часы с будильником состоят из  нескольких компонентов:

  • Arduino Nano(Uno)
  • Индикатор 1602 на базе контроллера HD44780
  • Пьезоизлучатель (пищалка)
  • Три кнопки + 3 резистора на 6,8…10 кОм

Основой программы часов служит библиотека MsTimer2, которая позволяет получить точные интервалы времени.

MsTimer2 это маленькая и простая в использовании библиотека служит «интерфейсом» между timer2 и пользователем. Она позволяет периодически запускать нужную функцию и настраивать, какой будет продолжительность у этого периода. Она называется «MsTimer2», потому что «зашивает» в timer2 разрешение в 1 миллисекунду (ms).

Соберите схему показанную на рисунке:

Пользоваться часами-будильником очень просто, для начала необходимо установить правильное время, для этого надо нажать один раз кнопку «К» для корректировки минут, и при помощи кнопок + или — установить минуты, далее нажмите кнопку «К» второй раз и установите показания часов. Аналогично устанавливается время будильника если продолжить нажимать кнопку «К». При пятом нажатии кнопки «К» можно включить или отключить будильник (on | off). Шестое нажатие кнопки «К» выключит режим корректировки.

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

#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); // кнопка коррекции
  pinMode(5,INPUT); // кнопка +
  pinMode(4,INPUT); // кнопка -
  pinMode(3,OUTPUT); // выход для пъезоизлучателя
}

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

void loop(){
  // читаем состояние входов
  kn=digitalRead(6);
  kn1=digitalRead(5);
  kn2=digitalRead(4);
  // коррекция времени, опрос кнопок
  if(kn==HIGH){
    korr++;
    if(korr>=6){
      korr=0;
    }
  }
  if(kn1==HIGH && korr==1){
    m++;
  }
  if(kn1==HIGH && korr==2){
    h++;
  }
  if(kn2==HIGH && korr==1){
    m--;
    if(m>60){
      m=0;
    }
  }
  if(kn2==HIGH && korr==2){
    h--;
  }
  if(kn1==HIGH && korr==3){
    m1++;
    if(m1>59){
      m1=0;
      h1++;
    }
  }
  if(kn1==HIGH && korr==4){
    h1++;
    if(h1>23){
      h1=0;
    }
  }
  // коррекция будильника
  if(kn2==HIGH && korr==3){
    m1--;
    if(m1>60){
      m1=0;
    }
  }
  if(kn2==HIGH && korr==4){
    h1--;
    if(h1>24){
      h1=0;
    }
  }
  // активация и диактивация будильника
  if(kn1==HIGH && korr==5){
    bud0=1;
  }
  if(kn2==HIGH && 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==HIGH || kn2==HIGH){
      bud=1;
    }
    for(int i=0;i<200;i++){ // пищалка
      digitalWrite(3,HIGH);
      delay(1);
      digitalWrite(3,LOW);
      delay(1);
    }
  }

  // вывод информации на экран 1 строка
  lcd.setCursor(1,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);// секунды
  if(korr==1){
    lcd.print(" kor_m");
  }
  if(korr==2){
    lcd.print(" kor_h");
  }
  // вывод информации на экран 1 строка
  lcd.setCursor(1,1);
  if(h1 < 10){
    lcd.print("0");
  }
  lcd.print(h1); // часы
  lcd.print(":");
  if(m1 < 10 ){
    lcd.print("0");
  }
  lcd.print(m1); // минуты

  if( bud0==1){
    lcd.print(" On  ");
  }
  if( bud0==0){
    lcd.print(" Off ");
  }

  if( bud0==1 && korr==5){
    lcd.print(" kor");
  }
  if( bud0==0 && korr==5){
    lcd.print(" kor ");
  }
  if(korr==3){
    lcd.print("kor_m");
  }
  if(korr==4){
    lcd.print("kor_h");
  }
  delay(200);
  lcd.clear();
}

 

Во второй версии часов с будильником улучшено управление коррекцией времени и будильника, добавлены дни недели, будильник можно активировать по будням, по выходным, каждый день или отключить.

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

void setup(){ 
  lcd.begin(16, 2);// LCD 16X2
  MsTimer2::set(1000, to_Timer);// задаем период 1с
  MsTimer2::start();// старт таймера
  pinMode(A3,INPUT);// кнопка К
  pinMode(A4,INPUT);// кнопка +
  pinMode(A5,INPUT);// кнопка -
  pinMode(3,OUTPUT); // выход для пъезоизлучателя
  pinMode(4,OUTPUT); // 4 - выход TTL // можно что-то подключить 
}
byte s, m, h, m1, h1, dn0 = 1, dn = 1, korr, korr_time, i, korr_bud, bud;
int kn, kn1, kn2;
unsigned long time0;

void to_Timer(){ if(korr_time == 0){s++;} else{s = 0;}} 

void time() { 
  if(s > 59){s = 0;m++;} // отсчет 1 мин
  if(m > 59){m = 0;h++;} // отсчет 1 час
  if(h > 23){h = 0;dn++;}// отсчет дня недели
  if(dn > 7){dn = 1;}
}

void korr_Time(){  
  kn = analogRead(A3); kn1 = analogRead(A4); kn2 = analogRead(A5); 
  if(kn1 && kn2 > 600){korr_time = 1;korr = 1;}
  if(kn > 600 && korr_time == 1){korr++;if(korr >= 4){korr, korr_time = 0;time0 = millis();}}
  if(time0 - millis() <= 200){kn = 0;}
  if(kn1 > 600 && korr == 1){m++;}
  if(kn1 > 600 && korr == 2){h++;}
  if(kn2 > 600 && korr == 1){m--;if(m > 60){m = 0;}}
  if(kn2 > 600 && korr == 2){h--;if(h >= 24){h = 0;}}
  if(kn1 > 600 && korr == 3){dn++;}
  if(kn2 > 600 && korr == 3){dn--;}
}

void korr_Bud(){
  if(kn > 600 && korr_time == 0){korr_bud++;if(korr_bud >= 4){korr_bud = 0;}}
  if(kn1 > 600 && korr_bud == 1){m1++;if(m1 > 59){m1 = 0;}}
  if(kn2 > 600 && korr_bud == 1){m1--;if(m1 > 60){m1 = 0;}}
  if(kn1 > 600 && korr_bud == 2){h1++;if(h1 > 23){h1 = 0;}}
  if(kn2 > 600 && korr_bud == 2){h1--;if(h1 > 24){h1 = 0;}}  
  if(kn1 > 600 && korr_bud == 3){dn0++;if(dn0 >= 5){dn0 = 1;}}
  if(kn2 > 600 && korr_bud == 3){dn0--;if(dn0 >= 5){dn0 = 4;}}
}

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

void loop(){
  time(); korr_Time(); korr_Bud();

  // вывод информации на экран 1 строка
  lcd.setCursor(1,0);
  if(korr == 2 && i == 1){lcd.print("  ");}else{if(h < 10){lcd.print("0");}lcd.print(h);} // часы
  lcd.print(":");
  if(korr == 1 && i == 1){lcd.print("  ");}else{if(m < 10 ){lcd.print("0");}lcd.print(m);} // минуты
  lcd.print(":");
  if(s < 10){lcd.print("0");}
  lcd.print(s);// секунды
  lcd.print("  ");
  if(korr == 3 && i == 1){lcd.print("   ");}else{
    switch(dn){ // если lcd руссифицирован, указать русские названия дней недели
    case 1: lcd.print("Mon");break;
    case 2: lcd.print("Tue");break;
    case 3: lcd.print("Wed");break;
    case 4: lcd.print("Thu");break;
    case 5: lcd.print("Fri");break;
    case 6: lcd.print("Sat");break;
    case 7: lcd.print("Sun");break;
    }}

  // вывод информации на экран 2 строка
  lcd.setCursor(1,1);
  if(korr_bud == 2 && i == 1){lcd.print("  ");}else{if(h1 < 10){lcd.print("0");}lcd.print(h1);} // часы
  lcd.print(":");
  if(korr_bud == 1 && i == 1){lcd.print("  ");}else{if(m1 < 10 ){lcd.print("0");}lcd.print(m1);} // минуты
  if(korr_bud == 3 && i == 1){lcd.print("          ");}else{
    switch(dn0){
    case 4: lcd.print(" OFF       ");break;// откл
    case 3: lcd.print(" *******");break;// каждый день
    case 2: lcd.print(" _____**");break;// по выходным
    case 1: lcd.print(" *****__");break;// по будням
    }}

  // запуск будильника
  if(m == m1 && h == h1 && bud == 0){switch(dn0){
    case 1: if(dn >= 1 && dn <= 5){bip();digitalWrite(4,HIGH);}break;
    case 2: if(dn >= 6 && dn <= 7){bip();digitalWrite(4,HIGH);}break;
    case 3: bip();digitalWrite(4,HIGH);break;}
    }else{bud=0;digitalWrite(4,LOW);}
  if(kn1 || kn2 > 600){bud = 1;} // нажать + или - для откл. будильника

  i++;
  if(i == 3){i = 0;}
  delay(150);
}

Comments

  1. Может кому понадобиться. Есть переходники для этого дисплея с подключением по шине I2C. .меньше проводов.поправил скетч под этот переходник:
    #include
    #include
    LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
    #include

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

    void setup(){
    lcd.init();
    lcd.backlight();// Включаем подсветку дисплея
    MsTimer2::set(1000, to_Timer); // задаем период 1с
    MsTimer2::start(); // старт таймера
    pinMode(6,INPUT); // кнопка коррекции
    pinMode(5,INPUT); // кнопка +
    pinMode(4,INPUT); // кнопка —
    pinMode(3,OUTPUT); // выход для пъезоизлучателя
    }

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

    void loop(){
    // читаем состояние входов
    kn=digitalRead(6);
    kn1=digitalRead(5);
    kn2=digitalRead(4);
    // коррекция времени, опрос кнопок
    if(kn==HIGH){
    korr++;
    if(korr>=6){
    korr=0;
    }
    }
    if(kn1==HIGH && korr==1){
    m++;
    }
    if(kn1==HIGH && korr==2){
    h++;
    }
    if(kn2==HIGH && korr==1){
    m—;
    if(m>60){
    m=0;
    }
    }
    if(kn2==HIGH && korr==2){
    h—;
    }
    if(kn1==HIGH && korr==3){
    m1++;
    if(m1>59){
    m1=0;
    h1++;
    }
    }
    if(kn1==HIGH && korr==4){
    h1++;
    if(h1>23){
    h1=0;
    }
    }
    // коррекция будильника
    if(kn2==HIGH && korr==3){
    m1—;
    if(m1>60){
    m1=0;
    }
    }
    if(kn2==HIGH && korr==4){
    h1—;
    if(h1>24){
    h1=0;
    }
    }
    // активация и диактивация будильника
    if(kn1==HIGH && korr==5){
    bud0=1;
    }
    if(kn2==HIGH && 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==HIGH || kn2==HIGH){
    bud=1;
    }
    for(int i=0;i<200;i++){ // пищалка
    digitalWrite(3,HIGH);
    delay(1);
    digitalWrite(3,LOW);
    delay(1);
    }
    }

    // вывод информации на экран 1 строка
    lcd.setCursor(1,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);// секунды
    if(korr==1){
    lcd.print(" kor_m");
    }
    if(korr==2){
    lcd.print(" kor_h");
    }
    // вывод информации на экран 1 строка
    lcd.setCursor(1,1);
    if(h1 < 10){
    lcd.print("0");
    }
    lcd.print(h1); // часы
    lcd.print(":");
    if(m1 < 10 ){
    lcd.print("0");
    }
    lcd.print(m1); // минуты

    if( bud0==1){
    lcd.print(" On ");
    }
    if( bud0==0){
    lcd.print(" Off ");
    }

    if( bud0==1 && korr==5){
    lcd.print(" kor");
    }
    if( bud0==0 && korr==5){
    lcd.print(" kor ");
    }
    if(korr==3){
    lcd.print("kor_m");
    }
    if(korr==4){
    lcd.print("kor_h");
    }
    delay(200);
    lcd.clear();
    }
    Библиотека по ссылке http://iarduino.ru/file/134.html

    1. Доброго дня Вам Aleksandr ! Слепил часики на arduino nano, модуль DS 3231 и дисплейчик ТМ 1637. Хочу сделать подарок внуку. Внук школьник и решил прикрутить будильник. Все часы с будильником (что я нашел) 1) в основном на дисплеях LCD. 2) Не умею присобачить в скетче мелодию к часам. Помогите по возможности с этой проблемой. Возможно вознаграждение в разумных пределах.
      piter336@gmail.com C ув. Петр

    1. Здравствуйте! Коментарии режут код, есть не совместимые символы. Залейте скетч в виде архива zip на сайт и опубликуйте на него ссылку в комментариях, или разместите статью на сайте с новым кодом скетча.

  2. Доброго дня Вам Aleksandr ! Слепил часики на arduino nano, модуль DS 3231 и дисплейчик ТМ 1637. Хочу сделать подарок внуку. Внук школьник и решил прикрутить будильник. Все часы с будильником (что я нашел) 1) в основном на дисплеях LCD. 2) Не умею присобачить в скетче мелодию к часам. Помогите по возможности с этой проблемой. Возможно вознаграждение в разумных пределах.
    piter336@gmail.com C ув. Петр

  3. Здравствуйте liman28!
    Люблю простые решения.
    Мой девиз — «все гениальное просто, чем проще, тем надежнее».

    Для 1 варианта кода этих часов(мне не нужны лишние «навороты») ввел свои коррективы.
    1. Чуть подправил схему, изменив под нее код, убрав резисторы и запитав кнопки от «земли»
    2. ввел в программу обнуление секунд, нажатием двух кнопок.
    3. внедрил программную коррекцию для компенсации погрешности кварца, добившись точности 1-2 секунды за сутки.
    4. при выключенном будильнике на дисплее только часы и ничего лишнего, отвлекающего внимание. И еще кое какие не существенные мелочи.
    Если есть смысл, то могу выложить то что сделано.

    У меня к вам просьба, подскажите пожалуйста, как здесь реализовать в режиме «только часы» большие цифры, так как это сделано тут
    http://forum.rcl-radio.ru/viewtopic.php?id=66

      1. Благодарю за ответ, т.е. как я понял, это проще сделать по i2c c библиотекой LiquidCrystal_I2C.h. У меня была такая мысль, т.к. обратил внимание при поиске с интернете, что везде где в часах на 1602 реализовывались большие цифры, использовалась эта библиотека.
        Тогда подскажите пожалуйста, что том скетче выкинуть и что вставить?
        Или этот вопрос лучше в форуме задать?

  4. вы не ошиблись, точно в этой теме? он же там будет не «в тему» 🙂
    ведь это совсем другие часы, без i2c и библиотека LiquidCrystal.h
    может в другую тему, где именно эти часы обсуждались? я правда не нашел такой темы на форуме 🙁

  5. возникли проблемы 🙁 и вопросы:
    1.форум требует регистрацию! разве регистрация здесь и на форуме это не одно и тоже?
    2. при попытке зарегистрироваться выдало такое
    «Извините, мы думаем что вы бот. Ваш айпи-адрес найден в базе спамеров StopForumSpam. Вы не можете сейчас зарегистрироваться.»
    3. может это связано с использованием VPN?

    Точно! отключил VPN — получилось зарегистрироваться 🙂
    буду пытаться создать тему.

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

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