#include <LiquidCrystal.h>
#include <RTClib.h>
//ПИНЫ
RTC_DS1307 rtc;
LiquidCrystal lcd(23, 25, 27, 29, 31, 33); // Пины подключения LCD
const int buttonPin1 = 3; // Пин кнопки 2
const int buttonPin2 = 4; // Пин кнопки 3
const int buttonPin4 = 5; // Пин кнопки 4
const int buttonPin7 = 7; // Пин кнопки 5
int buzzerPin = 6; // Пин пьезопищалки
int brightpin = 35; // Пин подсветки
//СОСТОЯНИЕ КНОПОК
int button4State = 0;
int button1State = 0;
int button2State = 0;
bool buttonState7 = false;
bool buttonPressed = false;
int lastButton4State = 0;
int lastButton2State = 0;
int lastButton1State = 0;
bool lastButtonState7 = false;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
//СИМВОЛ
byte bing[] = {
B00100,
B01110,
B01110,
B01110,
B11111,
B00100,
B00000,
B00000
};
//РЕЖИМЫ
int selectedField = 0; // 0 - часы, 1 - минуты, 2 - дни, 3 - месяцы, 4 - годы
int mode = 1; // 1 - часы, 2 - настройка, 3 - будильник, 4 - таймер
enum EditMode { HOURS, MINUTES, DAYS, MONTHS, YEARS };
EditMode editMode = HOURS;
// ПЕРЕМЕННЫЕ
int brightness = 0;
const int febDays = 28;
int alarmHour = 0;
int alarmMinute = 0;
bool AlarmSet = false;
int hours = 0;
int minutes = 0;
int timerValue = 0;
bool timerRunning = false;
void setup() {
lcd.begin(16, 2); // Запуск LCD
lcd.createChar(1, bing);
pinMode(2, INPUT); // Кнопка для переключения режимов
pinMode(buttonPin4, INPUT); // Кнопка для переключения подсветки
pinMode(buttonPin7, INPUT); // Кнопка для сброса времени
pinMode(buttonPin1, INPUT); // Кнопка для управления 1
pinMode(buttonPin2, INPUT); // Кнопка для управления 2
pinMode(buzzerPin, OUTPUT); // Кнопка для пьезопищалки
pinMode(brightpin, OUTPUT); // Пин подсветки
rtc.begin(); // Запуск RTC
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Установка времени компиляции в RTC при первом запуске
}
alarmHour = rtc.now().hour();
alarmMinute = rtc.now().minute();
}
void loop() {
//ПЕРЕКЛЮЧЕНИЕ РЕЖИМОВ
switch(mode) {
case 1:
// Режим отображения даты и времени
displayDateTime();
break;
case 2:
// Режим настройки даты и времени
editDateTime();
break;
case 3:
// Режим Будильника с настройкой
setAlarm();
break;
case 4:
// Режим таймера
timer();
break;
}
// Проверка нажатия кнопки для переключения режимов
if (digitalRead(2) == HIGH && !buttonPressed) {
mode++;
if (mode > 4) {
mode = 1;
}
buttonPressed = true;
delay(200); // Задержка для подавления дребезезга кнопки
} else if (digitalRead(10) == LOW) {
buttonPressed = false;
}
int reading4 = digitalRead(buttonPin4);
if (reading4 != lastButton4State) {
lastDebounceTime = millis();
}
if (reading4 != button4State) {
button4State = reading4;
if (button4State == HIGH) {
lastButton4State = button4State;
brightness -= 255;
if (brightness < 0) {
brightness = 255; // Обнуляем яркость, если достигнуто минимальное значение
}
}
analogWrite(brightpin, brightness);
}
}
//ФУНКЦИИ
//ВЫВОД ВРЕМЕНИ
//Функция вывода времени и даты
void displayDateTime() {
DateTime now = rtc.now();
lcd.setCursor(0, 0);
lcd.print("Time: ");
printDigits(now.hour()); // Выводим часы
lcd.print(":");
printDigits(now.minute()); // Выводим минуты
lcd.print(":");
printDigits(now.second()); // Выводим секунды
lcd.setCursor(0, 1);
lcd.print("Date: ");
printDigits(now.day()); // Выводим день
lcd.print("/");
printDigits(now.month()); // Выводим месяц
lcd.print("/");
lcd.print(now.year()); // Выводим год
if (!AlarmSet) {
lcd.setCursor(15, 0);
lcd.write(1);
}else {
lcd.setCursor(15, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
}
int currentHour = now.hour(); // Получаем текущий час
int currentMinute = now.minute(); // Получаем текущую минуту
// Проверяем, если текущее время совпадает с временем будильника (например, 7:00)
if (currentHour == hours && currentMinute == minutes && !AlarmSet) {
activateAlarm(); // Вызываем функцию активации будильника
}
}
//Функция активации будильника
void activateAlarm() {
tone(buzzerPin, 1000);
delay(150);
noTone(buzzerPin);
delay(150);
tone(buzzerPin, 1000);
delay(150);
noTone(buzzerPin);
delay(500);
tone(buzzerPin, 1000);
delay(150);
noTone(buzzerPin);
delay(150);
tone(buzzerPin, 1000);
delay(150);
noTone(buzzerPin);
delay(500);
}
//Функция корректного вывода времени и даты
void printDigits(int digits) {
// Выводим ведущий 0, если число меньше 10
if (digits < 10)
lcd.print('0');
lcd.print(digits);
}
//НАСТРОЙКА ВРЕМЕНИ
//Функция настройки времени и даты
void editDateTime() {
button1State = digitalRead(buttonPin1);
button2State = digitalRead(buttonPin2);
buttonState7 = digitalRead(buttonPin7);
if (button1State == HIGH) {
switchEditMode();
delay(200);
}
if (button2State == HIGH) {
increaseValue();
delay(200);
}
displayDateTime();
// СБРОС ДАТЫ //
if (buttonState7 != lastButtonState7 && buttonState7 == HIGH) {
rtc.adjust(DateTime(2000, 1, 1, 0, 0, 0));
}
lastButtonState7 = buttonState7;
}
//Переключения настройки
void switchEditMode() {
editMode = static_cast<EditMode>((editMode + 1) % 5);
}
//Настройки времени
void increaseValue() {
DateTime now = rtc.now();
switch (editMode) {
//ЧАС
case HOURS:
rtc.adjust(DateTime(rtc.now().unixtime() + 3600));
break;
//МИНУТА
case MINUTES:
rtc.adjust(DateTime(rtc.now().unixtime() + 60));
break;
//ДЕНЬ
case DAYS:
rtc.adjust(DateTime(rtc.now().unixtime() + 86400));
break;
//МЕСЯЦ
case MONTHS:
int year = now.year();
//Январь
if (now.month() == 1){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
//Февраль
if (now.month() == 2){
int daysInFeb = isLeapYear(year) ? 29 : febDays;
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * daysInFeb));
}
//Март
if (now.month() == 3){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
//Апрель
if (now.month() == 4){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 30));
}
//Май
if (now.month() == 5){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
//Июнь
if (now.month() == 6){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 30));
}
//Июль
if (now.month() == 7){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
//Август
if (now.month() == 8){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
//Сентябрь
if (now.month() == 9){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 30));
}
//Октябрь
if (now.month() == 10){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
//Ноябрь
if (now.month() == 11){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 30));
}
//Декабрь
if (now.month() == 12){
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 31));
}
break;
//ГОД
case YEARS:
rtc.adjust(DateTime(rtc.now().unixtime() + 86400 * 365));
break;
}
}
// Проверяем год и возврвщаем булевое значение ДА если высокосный и НЕТ если обычный год
boolean isLeapYear(int year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
//БУДИЛЬНИК
//Функция будильника настройки
void setAlarm() {
displayTime();
// Увеличиваем часы на 1 по нажатию кнопки
if (digitalRead(buttonPin1) == HIGH) {
delay(50); // Задержка для подавления дребезга
if (digitalRead(buttonPin1) == HIGH) {
hours++;
delay(100);
if (hours > 23) {
hours = 0;
}
displayTime();
}
}
// Увеличиваем минуты на 1 по нажатию кнопки
if (digitalRead(buttonPin2) == HIGH) {
delay(50); // Задержка для подавления дребезга
if (digitalRead(buttonPin2) == HIGH) {
minutes++;
delay(100);
if (minutes > 59) {
minutes = 0;
}
displayTime();
}
}
//Включение и выключение будильника
if (digitalRead(buttonPin7) == HIGH && !AlarmSet) {
AlarmSet = true;
delay(200);
}
if (digitalRead(buttonPin7) == HIGH && AlarmSet) {
AlarmSet = false;
delay(200);
}
}
//Функция обновления дисплея будильника
void displayTime() {
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Time: ");
if (hours < 10) {
lcd.print("0");
}
lcd.print(hours);
lcd.print(":");
lcd.setCursor(9, 0);
if (minutes < 10) {
lcd.print("0");
}
lcd.print(minutes);
if (!AlarmSet) {
lcd.setCursor(0, 1);
lcd.print("Alarm ON");
}else {
lcd.setCursor(0, 1);
lcd.print("Alarm OFF");
}
}
//ТАЙМЕР
void timer() {
updateDisplay();
if (digitalRead(buttonPin1) == HIGH && !timerRunning) {
timerRunning = true;
}
if (digitalRead(buttonPin2) == HIGH && timerRunning) {
timerRunning = false;
}
if (digitalRead(buttonPin7) == HIGH && !timerRunning) {
timerValue = 0;
}
if (timerRunning) {
for (int i = 0; i <= 20; i++) {
delay(50);
}
timerValue++;
updateDisplay();
}
}
//Функция обновления дисплея таймера
void updateDisplay() {
lcd.setCursor(0, 0);
lcd.print("Timer: ");
lcd.setCursor(7, 0);
lcd.print(" ");
lcd.setCursor(7, 0);
lcd.print(timerValue);
lcd.print(" s ");
lcd.setCursor(0, 1);
lcd.print(" ");
}