#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Глобальные переменные для хранения времени.
int hours = 10; // Часы
int minutes = 10; // Минуты
// Время срабатывания будильника.
int alarm_hours = 0;
int alarm_minutes = 0;
bool alarm_triggered = false; // Переменная для отслеживания срабатывания будильника
// Переменная для хранения времени последнего обновления времени.
unsigned long lastUpdateTime = 0;
// Константа для определения интервала обновления времени (1 минута).
const unsigned long updateInterval = 60000;
// Номера портов, куда подключены кнопки, в виде
// констант.
const int BUTTON_1 = 23;
const int BUTTON_2 = 25;
const int BUTTON_3 = 27; // Кнопка смены режима
// Возможные состояния системы.
const int CLOCK_STATE = 0; // Часы
const int CONFIG_STATE = 1; // Настройка будильника
const int ALARM_STATE = 2; // Режим "будения"
// Состояние системы.
int state = CLOCK_STATE;
// Пины для RGB LED лампы.
const int RED_PIN = 9;
const int GREEN_PIN = 10;
const int BLUE_PIN = 11;
unsigned long alarm_trigger_time = 0;
void setup() {
pinMode(2, OUTPUT);
// Настройка дисплея
lcd.init();
lcd.backlight();
// Настройка кнопочек.
pinMode(BUTTON_1, INPUT_PULLUP);
pinMode(BUTTON_2, INPUT_PULLUP);
pinMode(BUTTON_3, INPUT_PULLUP);
pinMode(3, OUTPUT);
// Настройка пинов для RGB LED лампы.
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
// Инициализация времени последнего обновления.
lastUpdateTime = millis();
}
void loop() {
unsigned long currentMillis = millis(); // Текущее время.
// Обновление времени каждую минуту.
if (currentMillis - lastUpdateTime >= updateInterval) {
lastUpdateTime = currentMillis;
minutes++;
if (minutes == 60) {
minutes = 0;
hours++;
if (hours == 24) {
hours = 0;
}
}
}
lcd.clear(); // Очистка экрана.
if (state == CLOCK_STATE) {
// Вывод текущего времени на экран:
lcd.setCursor(0, 0);
lcd.print(hours);
lcd.setCursor(2, 0);
lcd.print(":");
if (minutes < 10) {
lcd.print("0"); // Добавляем ведущий ноль для однозначных минут.
}
lcd.print(minutes);
lcd.setCursor(0, 1);
lcd.print("CLOCK");
if (digitalRead(BUTTON_3) == LOW) {
state = CONFIG_STATE;
}
} else if (state == CONFIG_STATE) {
// Вывод времени настройки будильника на экран:
lcd.setCursor(0, 0);
lcd.print(alarm_hours);
lcd.setCursor(2, 0);
lcd.print(":");
if (alarm_minutes < 10) {
lcd.print("0"); // Добавляем ведущий ноль для однозначных минут.
}
lcd.print(alarm_minutes);
lcd.setCursor(0, 1);
lcd.print("ALARM");
if (digitalRead(BUTTON_3) == LOW) {
state = CLOCK_STATE;
}
if (digitalRead(BUTTON_1) == LOW) {
alarm_hours = (alarm_hours + 1) % 24; // Переход на следующий час.
}
if (digitalRead(BUTTON_2) == LOW) {
alarm_minutes = (alarm_minutes + 1) % 60; // Переход на следующую минуту.
}
}
if (!alarm_triggered && state == CLOCK_STATE && hours == alarm_hours && minutes == alarm_minutes - 1) {
// Включение красного цвета за минуту до срабатывания будильника.
analogWrite(RED_PIN, 255);
analogWrite(GREEN_PIN, 0);
analogWrite(BLUE_PIN, 0);
}
// Если будильник сработал и прошло 30 секунд после срабатывания.
if (!alarm_triggered && state == CLOCK_STATE && hours == alarm_hours && minutes == alarm_minutes - 1 && (currentMillis - lastUpdateTime >= 30000)) {
// Переключаем цвет лампы на зеленый и продолжаем до совпадения времени.
analogWrite(RED_PIN, 0);
analogWrite(GREEN_PIN, 255);
analogWrite(BLUE_PIN, 0);
}
// Если время на часах совпало с временем будильника.
if (!alarm_triggered && state == CLOCK_STATE && hours == alarm_hours && minutes == alarm_minutes) {
// Меняем цвет лампы на красный и включаем режим будильника.
analogWrite(RED_PIN, 0);
analogWrite(GREEN_PIN, 0);
analogWrite(BLUE_PIN, 255);
state = ALARM_STATE;
alarm_triggered = true;
alarm_trigger_time = currentMillis;
lcd.clear();
lcd.setCursor(0, 1);
tone(3, 530, 10000); // Воспроизводим звук на 10 секунд.
}
// Если режим будильника активен и прошло 10 секунд после его активации.
if (state == ALARM_STATE && currentMillis - alarm_trigger_time >= 10000) {
// Выключаем лампу и возвращаемся в режим часов.
analogWrite(RED_PIN, 0);
analogWrite(GREEN_PIN, 0);
analogWrite(BLUE_PIN, 0);
state = CLOCK_STATE;
// Устанавливаем время последнего обновления перед срабатыванием будильника.
lastUpdateTime = currentMillis;
// Сбрасываем флаг срабатывания будильника
alarm_triggered = false;
// Возвращаем время обратно на минуту.
minutes++;
if (minutes == 60) {
minutes = 0;
hours++;
if (hours == 24) {
hours = 0;
}
}
}
if (state == ALARM_STATE) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("ALARM");
}
delay(100);
}