По урокам и библиотекам Эдуарда сделал часы с будильником.
Компоненты: семисегментный 4-разрядный индикатор, модуль часы реального времени RTC DS1307, микросхема Atmega328P, кварц, зуммер, 3 кнопки, стабилизатор напряжение на 5 вольт, 5 конденсаторов и 8 резисторов, блок питания от телефона на 9 вольт, коробка.
Скетч:
Код: Выделить всё
//MyAlarmClock
#include <MsTimer2.h>
#include <Led4Digits.h>
#include <Button.h>
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1307); // подключаем RTC модуль на базе чипа DS1307, используется аппаратная шина I2C
#define SOUND_PIN 17 // звуковой излучатель, вывод 18 (A3)
#define CYCLE_2_TIME 250 // время цикла 2 ( * 2 = 500 мс)
// тип индикатора 1; выводы разрядов 5,10,12,13; выводы сегментов 2,4,6,8,11,3,9,7
Led4Digits disp(1, 5,10,12,13, 2,4,6,8,11,3,9,7);
Button PIN_button_SET(15, 10); // кнопка 1, вывод 15 (A1)
Button PIN_button_UP(14, 10); // кнопка 2, вывод 14 (A0)
Button PIN_button_SELECT(16, 10); // кнопка 3, вывод 16 (A2)
uint8_t VAR_mode_SHOW = 1; // режим вывода: 1-время 2-будильник 3-дата
uint8_t VAR_mode_SET = 0; // режим установки времени: 0-нет 1-сек 2-мин 3-час 4-день 5-мес 6-год 7-день_недели 8-часы будильника 9-минуты будильника
uint8_t VAR_alarm_HOUR = 0; // будильник часы
uint8_t VAR_alarm_MIN = 0; // будильник минуты
bool VAR_alarm_FLAG1 = true; // будильник включен/выкючен
bool VAR_alarm_FLAG2 = false; // будильник разрешение срабатывания
byte soundCount=0; // счетчик времени звука
unsigned int timerCount2; // счетчик таймера 2
boolean flagTimer2; // признак программного таймера 2
uint8_t CurrentSecond = 0; // текущая секунда
void setup() {
MsTimer2::set(2, timerInterrupt); // прерывание по таймеру 2 мс
MsTimer2::start(); // разрешение прерывания
pinMode(SOUND_PIN, OUTPUT); // вывод звукового излучателя
time.begin(); // инициируем модуль часов
}
void loop() {
time.gettime();
if (VAR_alarm_FLAG1 == true) { // если будильник включен
disp.digit[0] |= 0x80; // зажечь децимальную точку в первом разряде
}
else { // иначе
disp.digit[0] &= 0x7f; // погасить децимальную точку в первом разряде
}
if(VAR_mode_SHOW==1){ // если установлен режим вывода времени
if (flagTimer2 == true) {
disp.print(time.Hours*100 + time.minutes, 4, 0); // выводим время
disp.digit[2] |= 0x80; // зажечь децимальную точку
}
if (flagTimer2 == false) {
if (VAR_mode_SET == 3) {disp.digit[2] = B0000000; disp.digit[3] = B0000000;} // в режиме настройки мигаем часами
if (VAR_mode_SET == 2) {disp.digit[0] = B0000000; disp.digit[1] = B0000000;} // в режиме настройки мигаем минутами
disp.digit[2] &= 0x7f; // погасить децимальную точку
}
}
if(VAR_mode_SHOW==2){ // если установлен режим вывода будильника
disp.digit[2] |= 0x80; // зажечь децимальную точку
if (flagTimer2 == true) {
disp.print(VAR_alarm_HOUR*100 + VAR_alarm_MIN, 4, 0); // выводим будильник
}
if (flagTimer2 == false) {
if (VAR_mode_SET == 8) {disp.digit[2] = B0000000; disp.digit[3] = B0000000;} // в режиме настройки часов будильника мигаем часами
if (VAR_mode_SET == 9) {disp.digit[0] = B0000000; disp.digit[1] = B0000000;} // в режиме настройки минут будильника мигаем минутами
}
}
//----------------------- проверка будильника
if(VAR_alarm_FLAG1){ // если будильник включён
if(time.seconds==00){ // если в текущем времени 0 секунд
if(time.minutes==VAR_alarm_MIN){ // если совпали минуты
if(time.Hours==VAR_alarm_HOUR){ // если совпали часы
VAR_alarm_FLAG2=true; // устанавливаем флаг разрешающий срабатывание будильника
}
}
}
}else{VAR_alarm_FLAG2=false;} // если будильник выключен, то сбрасываем флаг разрешающий срабатывание будильника
if(VAR_alarm_FLAG2){digitalWrite(SOUND_PIN, ! digitalRead(SOUND_PIN));} // включаем звук будильника
//----------------------- переключение режима отображения времени/будильника
if ( PIN_button_SELECT.flagClick == true ) {
PIN_button_SELECT.flagClick= false; // сброс признака
if(VAR_alarm_FLAG2){
VAR_alarm_FLAG2=false; // если будильник сработал, то выключаем его
digitalWrite(SOUND_PIN, LOW);
}
else {
soundCount = 50; // звук на нажатие кнопки 50*2 мс
VAR_mode_SHOW=VAR_mode_SHOW==1?2:1; // инверсия режима
VAR_mode_SET = 0; // отмена настройки времени/будильника
}
}
//----------------------- переключение режима установки времени/будильника
if ( PIN_button_SET.flagClick == true && VAR_mode_SHOW==1 ) {
PIN_button_SET.flagClick= false; // сброс признака
if(VAR_alarm_FLAG2){
VAR_alarm_FLAG2=false; // если будильник сработал, то выключаем его
digitalWrite(SOUND_PIN, LOW);
}
else {
soundCount = 50; // звук на нажатие кнопки 50*2 мс
switch (VAR_mode_SET){
case 0: VAR_mode_SET = 3; break;
case 3: VAR_mode_SET = 2; break;
case 2: VAR_mode_SET = 0; break;
}
}
}
if ( PIN_button_SET.flagClick == true && VAR_mode_SHOW==2 ) {
PIN_button_SET.flagClick= false; // сброс признака
if(VAR_alarm_FLAG2){
VAR_alarm_FLAG2=false; // если будильник сработал, то выключаем его
digitalWrite(SOUND_PIN, LOW);
}
else {
soundCount = 50; // звук на нажатие кнопки 50*2 мс
switch (VAR_mode_SET){
case 0: VAR_mode_SET = 8; break;
case 8: VAR_mode_SET = 9; break;
case 9: VAR_mode_SET = 0; break;
}
}
}
//---------------------- настройка времени/будильника
if ( PIN_button_UP.flagClick == true ) {
PIN_button_UP.flagClick= false; // сброс признака
if(VAR_alarm_FLAG2){
VAR_alarm_FLAG2=false; // если будильник сработал, то выключаем его
digitalWrite(SOUND_PIN, LOW);
}
else if (VAR_mode_SET == 0){ // в режиме вывода времени/будильника
soundCount = 50; // звук на нажатие кнопки 50*2 мс
VAR_alarm_FLAG1 = !VAR_alarm_FLAG1; // включааем/выключаем будильник
}
else {
soundCount = 50; // звук на нажатие кнопки 50*2 мс
switch (VAR_mode_SET){ // инкремент (увеличение) устанавливаемого значения
/* мин */ case 2: time.settime(-1, (time.minutes==59?0:time.minutes+1), -1, -1, -1, -1, -1); break;
/* час */ case 3: time.settime(-1, -1, (time.Hours==23?0:time.Hours+1), -1, -1, -1, -1); break;
/* ч.б.*/ case 8: VAR_alarm_HOUR=VAR_alarm_HOUR==23?0:VAR_alarm_HOUR+1; break;
/* м.б.*/ case 9: VAR_alarm_MIN =VAR_alarm_MIN ==59?0:VAR_alarm_MIN +1; break;
}
}
}
//----------------------------------------------------------------
}
// обработчик прерывания 2 мс
void timerInterrupt() {
disp.regen(); // регенерация индикатора
PIN_button_SET.filterAvarage(); // сканирование кнопки, метода фильтрации по среднему
PIN_button_UP.filterAvarage(); // сканирование кнопки, метода фильтрации по среднему
PIN_button_SELECT.filterAvarage(); // сканирование кнопки, метода фильтрации по среднему
timerCount2++; // + 1 к счетчику таймера 2
if (CurrentSecond != time.seconds){ // если секунда переключилась
flagTimer2= true; // установка флага таймера 2
timerCount2= 0; // сброс счетчика
CurrentSecond = time.seconds; // присваиваем текущей секунде новое значение
}
if ( timerCount2 >= CYCLE_2_TIME ) {
flagTimer2= false; // сброс флага таймера 2
}
// звук
if (soundCount != 0) {
digitalWrite(SOUND_PIN, ! digitalRead(SOUND_PIN));
soundCount--;
}
}