Часы с будильником состоят из платы Arduino Nano (Uno), LCD индикатора 1602 и модуля часов реального времени DS3231 (ZS-042). Помимо текущего времени на экране индикатора отображается дата, день недели, месяц, год и температура. Будильник в часах один, он позволяет выставить время срабатывания в минутах и часах, так же предусмотрено его отключение, а так же работа каждый день, в будние дни и по выходным. Установка времени срабатывания будильника осуществляется кнопками «К», «+» и «-«. Сигнал будильника звучит в течении одной минуты, но если нажать на одну из кнопок «+» или «-«. сигнал будильника можно прервать. Время срабатывания будильника и режим его работы сохраняются в энергонезависимой памяти.
Устанавливать время на часах не нужно, так как предусмотрена коррекция времени при прошивке микроконтроллера. Для этого необходимо раскомментировать строчку:
// clock.setDateTime(__DATE__, __TIME__);
Далее залейте скетч в плату, закомментируйте строчку и залейте скетч повторно.
#include <Wire.h> #include <DS3231.h>//https://github.com/jarzebski/Arduino-DS3231/archive/master.zip // DS3231.zip DS3231 clock;RTCDateTime DateTime; #include <LiquidCrystal.h> #include <EEPROM.h> //#include <EEPROMex.h> LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7 int k,m,h,i,w,reg,ton; byte rom0,rom1,rom2; unsigned long eeprom; void setup(){Serial.begin(9600); lcd.begin(16,2);// LCD 16X2 Wire.begin(); clock.begin(); pinMode(2,INPUT);pinMode(3,INPUT);pinMode(4,INPUT); // clock.setDateTime(__DATE__, __TIME__); // Устанавливаем время на часах, основываясь на времени компиляции скетча 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; } void loop(){i++;if(i>4){i=0;} if(digitalRead(2)==HIGH){k++;reg=1;delay(300);}if(k>3){k=0;reg=0;} if(reg==1) { if(k==1){ if(digitalRead(3)==HIGH){m++;}if(m>59){m=59;} if(digitalRead(4)==HIGH){m--;}if(m<0){m=0;}} if(k==2){ if(digitalRead(3)==HIGH){h++;}if(h>23){h=23;} 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(i==1&&k==2){lcd.print(" ");}else{if(h < 10 ){lcd.print("0");}lcd.print(h);} lcd.print(":"); if(i==1&&k==1){lcd.print(" ");}else{if(m < 10 ){lcd.print("0");}lcd.print(m);} lcd.setCursor(0,1); if(i==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(); // Считываем c часов текущие значения даты и времени в сущность DateTime lcd.setCursor(0,0); lcd.print(clock.dateFormat("H:i:s ",DateTime));// выводим часы, минуты и секунды lcd.print(clock.readTemperature(),1);lcd.print((char)223);lcd.print("C");// выводим значение температуры lcd.setCursor(0,1);lcd.print(clock.dateFormat("D d M Y", DateTime));// выводим день недели, дату, месяц и год } if(digitalRead(3)==HIGH||digitalRead(4)==HIGH){ton=1;} if(DateTime.hour*60+DateTime.minute!=h*60+m){ton=0;} if(w==0){pic();} if(w==1&&(DateTime.dayOfWeek<6)){pic();} if(w==2&&(DateTime.dayOfWeek>5)){pic();} eeprom++; delay(200); lcd.clear(); } void pic(){if(ton==0&&(DateTime.hour*60+DateTime.minute==h*60+m)){tone(5,1200,500);delay(500);}} // форум - http://forum.rcl-radio.ru/viewtopic.php?pid=927#p927
Второй вариант часов с будильником выполнен с использованием четырех разрядного семисегментного индикатора на базе драйвера TM1637 (модуль TM1637).
При нажимании кнопки «К» происходит перебор элементов меню, вывод секунд, даты и месяца, температуры, установка времени будильника, включение или отключение будильника, яркость индикатора.
#include <Wire.h> #include <TM1637Display.h> #include <DS3231.h> #include <EEPROM.h> //#include <EEPROMex.h> DS3231 clock; // ПОДКЛЮЧЕНИЕ DS3231 SDA, SCL, SQW / A4, A5, D6 RTCDateTime DateTime; TM1637Display display(4, 5);// ПОДКЛЮЧЕНИЕ TM1637 CLK,DIO / 4, 5 int k,alarm_m,alarm_h; byte w = 1,x,y,z,menu,ton,on=1; uint8_t date_s[]{0,0,0,0};// second uint8_t date_t[]{0x78,0,0,0};// t uint8_t date_on[]{0,0,0x3f,0x37};// ON uint8_t date_off[]{0,0x3f,0x71,0x71};// OFF void setup() { // clock.setDateTime(__DATE__, __TIME__); display.setBrightness(1);// яркость TM1637 0-7 Wire.begin(); clock.begin(); pinMode(6,INPUT);pinMode(10,INPUT);pinMode(11,INPUT);pinMode(12,INPUT); alarm_m = EEPROM.read(0);alarm_h = EEPROM.read(1);z = EEPROM.read(3);// ЧТЕНИЕ EEPROM } void loop() { DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ k = DateTime.hour*100+DateTime.minute; // ВРЕМЯ КАК ЧИСЛО ННММ if(digitalRead(6) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ if(digitalRead(10) == HIGH){menu++;delay(300);if(menu > 6){menu = 0;}} // ПЕРЕБОР МЕНЮ if(menu == 0){y = true;if(w == 0){EEPROM.update(0,alarm_m);EEPROM.update(1,alarm_h);EEPROM.update(3,z);} w = 1;} // ПРИ ВЫХОДЕ ИЗ МЕНЮ ОБНОВЛЕНИЕ EEPROM if(menu == 1){k = DateTime.second;date_s[2] = display.encodeDigit((k/10)%10); date_s[3] = display.encodeDigit((k%10)%10);display.setSegments(date_s); } // ВЫВОД СЕКУНД if(menu == 2){k = DateTime.day*100 + DateTime.month;x = 0x40;} // ВЫВОД ДАТЫ И МЕСЯЦА if(menu == 3){k = clock.readTemperature();date_t[2] = display.encodeDigit((k/10)%10); date_t[3] = display.encodeDigit((k%10)%10);display.setSegments(date_t);} // ВЫВОД ТЕМПЕРАТУРЫ if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА if(digitalRead(11) == HIGH){alarm_h++;delay(500);}if(alarm_h > 23){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА w = 0;} if(menu == 5){ if(digitalRead(11) == HIGH){on=1;delay(300);}if(on==1){display.setSegments(date_on);} // БУДИЛЬНИК ВКЛЮЧЕН if(digitalRead(12) == HIGH){on=0;delay(300);}if(on==0){display.setSegments(date_off);} // БУДИЛЬНИК ВЫКЛЮЧЕН } if(menu == 6){y = false;x = 0x00;k = z; // НАСТРОЙКА ЯРКОСТИ ИНДИКАТОРА if(digitalRead(11) == HIGH){z++;delay(500);}if(z > 7){z = 0;} if(digitalRead(12) == HIGH){z--;delay(500);}if(z > 8){z = 7;} w = 0;} if(digitalRead(11)==HIGH||digitalRead(12)==HIGH){ton=1;} // ПРИ НАЖАТИИ НА КНОПУ + ИЛИ - ПРЕРЫВАЕТСЯ СИГНАЛ БУДИЛНИКА if(DateTime.hour*100+DateTime.minute!=alarm_h*100+alarm_m){ton=0;} if(on==1){pic();} display.setBrightness(z); if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);} } void pic(){if(ton==0&&(DateTime.hour*100+DateTime.minute==alarm_h*100+alarm_m)){tone(7,1000,500);delay(1000);}} // СИГНАЛ БУДИЛЬНИКА, 7 ЦИФРОВОЙ ВЫХОД
Почему то не хочет компилироватся скетч, пишет RTSDate time does not name a type. Подскажите в чём может быть проблема?
Скорее всего неверно установлена библиотека DS3231, необходимо скачать библиотеку указанную в скетче, распаковать ее, переименовать распакованную папку в DS3231, создать архив из папки DS3231.zip.
Файлы с расширением .ccp и .h должны находится в корне папки библиотеки.
Перед установкой удалите старую библиотеку.
http://rcl-radio.ru/wp-content/uploads/2019/01/DS3231.zip
Огромное спасибо, с этой библиотекой всё прогрузилось.
Уважаемый medved323! Распиши пожалуйста для чайника пошагово где и как скачать и распаковать эту библиотеку. А проще скинь мне её. Если не трудно.
http://rcl-radio.ru/wp-content/uploads/2019/01/DS3231.zip
распаковывать архив не надо, просто добавьте библиотеку в arduino IDE
на это мыло пожалуйста eugen_bollinger.mail.ru
Буду очень признателен! Заранее СПАСИБО!
Не грузится, пишет уже есть. Где, что и как удалить? Прежде чем грузить.
В папке где у Вас сохраняются скетчи, есть папка libraries, в ней найдите нужную библиотеку и удалите ее, новую библиотеку Вы можете рапаковать в эту же папку без добавления библиотеки через Arduino IDE.
Век живи — век учись! Спасибо! Всё работает как доктор прописал!
Если есть интерес по подсветке лестницы на Ардуино, пиши на мыло.
У меня работает более 2 лет.
Привет! Помогите сделать настройку часов кнопками?
Во втором примере кода.
Здравствуйте! Опишите подробнее возникшую проблему.
Если Вы про установку времени часов, то раскомментируйте строчку:
// clock.setDateTime(__DATE__, __TIME__);
Залейте скетч в ардуино,
Затем закомментируйте строчку и по новой залейте скетч.
Добавить пункт в меню, и с помощью кнопок менять значения времени.
Есть пример с другого кода :
if (digitalRead(keyPL) && digitalRead(keyHor)){ // часы
second = 0; // сбрасываем секунды
if (hour < 23){hour++;}
else if (hour == 23){hour = 0;}
setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year); // пишим в модуль
delay(200);
}
if (digitalRead(keyPL) && digitalRead(keyMin)){ // минуты
second = 0;
if (minute < 59){minute++;}
else if (minute == 59){minute = 0;}
setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
delay(200);
}
Время можно изменить следующей командой:
// Manual (Year, Month, Day, Hour, Minute, Second)
clock.setDateTime(2014, 4, 25, 0, 0, 0);
В моем коде можно добавить несколько новых разделов меню, для минут, часов, дня месяца и года, но с таким индикатором это не целесообразно, настройка часов разовая процедура, она будет только мешаться, но тем не менее при желании можно добавить следующий код:
int set_Year=2019, set_Month, set_Day, set_h, set_min;// добавим переменные для даты и времени
if(menu == 7){y = true;x = 0x00;k = set_Year; //выводим на индикатор год
if(digitalRead(12) == HIGH){set_Year++;delay(300);}if(set_Year > 2100){set_Year = 2019;}
if(digitalRead(11) == HIGH){set_Year—;delay(300);}if(set_Year < 2019){set_Year = 2019;} w = 0;} if(w==0){clock.setDateTime(set_Year, set_Month, set_Day, set_h, set_min, 0);w=1;} далее создаем menu № 8 9 10... для месяца дня часов и минут Но все же проще воспользоваться командой установки времени компиляции: // clock.setDateTime(__DATE__, __TIME__); для этого и используюся часы реального времени.
if(menu == 4){y = true;x = 0x40;k = alarm_h*100+alarm_m; // УСТАНОВКА БУДИЛЬНИКА
if(digitalRead(12) == HIGH){alarm_m++;delay(300);}if(alarm_m > 59){alarm_m = 0;} // МИНУТЫ БУДИЛЬНИКА
if(digitalRead(11) == HIGH){alarm_h++;delay(500);}if(alarm_h > 23){alarm_h = 0;} // ЧАСЫ БУДИЛЬНИКА
w = 0;}
На примере этой строчки где устанавливаеться время для будильника, тока устанавливать текущее время
if(menu == 7){y = true;x = 0x00;k = set_Year; //выводим на индикатор год
if(digitalRead(12) == HIGH){set_Year++;delay(300);}if(set_Year > 2100){set_Year = 2019;}
if(digitalRead(11) == HIGH){set_Year—;delay(300);}if(set_Year 23){set_h = 0;}
if(digitalRead(11) == HIGH){set_h—;delay(300);}if(set_h 59){set_min = 0;}
if(digitalRead(11) == HIGH){set_min—;delay(300);}if(set_min < 0){set_min = 59;} w = 0;}
if(w==0)
после 4 пункта меню перестает листать, походу что то не так сделал, как будто виснет
if(menu == 7){y = true;x = 0x00;k = set_Year; //выводим на индикатор год
if(digitalRead(12) == HIGH){set_Year++;delay(300);}if(set_Year > 2100){set_Year = 2019;}
if(digitalRead(11) == HIGH){set_Year—;delay(300);}if(set_Year 23){set_h = 0;}
if(digitalRead(11) == HIGH){set_h—;delay(300);}if(set_h 59){set_min = 0;}
if(digitalRead(11) == HIGH){set_min—;delay(300);}if(set_min < 0){set_min = 59;} w = 0;}
if(w==0)
точнее вот, там ошибочно скопировал
Так работать не будет, лучше вывести настройку времени из меню и добавить еще одну кнопку:
в setup() добавить кнопку заменив строку:
pinMode(6,INPUT);pinMode(10,INPUT);pinMode(11,INPUT);pinMode(12,INPUT);
на
pinMode(6,INPUT);pinMode(10,INPUT);pinMode(11,INPUT);pinMode(12,INPUT);pinMode(9,INPUT);// добавим кнопку на вход 9
далее добавим отработку новой кнопки в раздел loop() (в начало раздела)
if(digitalRead(9) == HIGH){menu1++;delay(300);if(menu1 > 3){menu1 = 0;}} // ПЕРЕБОР настроек редактирования времени
// menu1 = 1 — установка года
// menu1 = 2 — установка месяца и даты
// menu1 = 3 — установка часов и минут
// menu1 = 0 — корректировка времени не активна
// корректировка года
if(menu1 == 1){y = true;x = 0x00;k = set_y; //выводим на индикатор год
if(digitalRead(12) == HIGH){set_y++;delay(300);}if(set_y > 2100){set_y = 2019;}
if(digitalRead(11) == HIGH){set_y—;delay(300);}if(set_y < 2019){set_y= 2019;} w1 = 0;}
// корректировка месяца и даты
if(menu1 == 2){y = true;x = 0x00;k = set_mon*100+set_d; //выводим на индикатор месяц и день
if(digitalRead(12) == HIGH){set_mon++;delay(300);}if(set_mon > 12){set_mon = 1;}// прибавляет месяц
if(digitalRead(11) == HIGH){set_d++;delay(300);}if(set_d > 31){set_d= 1;} // прибавляем дату
w1 = 0;}
// корректировка часов и минут
if(menu1 == 3){y = true;x = 0x40;k = set_h*100+set_m; //выводим на индикатор часы и минуты
if(digitalRead(12) == HIGH){set_h++;delay(300);}if(set_h > 24){set_h = 0;}// прибавляет часы
if(digitalRead(11) == HIGH){set_m++;delay(300);}if(set_m > 59){set_m= 0;} // прибавляем минуты
w1 = 0;}
// записываем в память часов новые значения времени
if(w1==0){clock.setDateTime(set_y, set_mon, set_d, set_h, set_m, 0);w1=1;}
// разграничение menu1 и menu
// заменяем строку
if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}
на новую
if(menu1>0){display.showNumberDecEx(k,x,y);}
if(menu1==0){if(menu == 3 || menu == 5 || menu == 1){}else{display.showNumberDecEx(k,x,y);}}
перед разделом setup() добавим новые переменные:
int set_y,set_mon,set_d,set_h,set_m;// год, месяц, дата, часы и минуты
int menu1,w1;
Должно вроде как все работать, но надо тестировать.
спасибо получилось, работает, тока единственное при заливке скетча часы не идут пока не установишь время и после отключения питания все по новой приходиться настраивать время и дату
может модуль часов DS3231 не исправен, батарейка севшая. Время не должно сбрасываться при отключении питания.