#include <WiFi.h>
#include "time.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ========== НАСТРОЙКИ WiFi ==========
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
// ========== НАСТРОЙКИ NTP (Новосибирск) ==========
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 25200; // UTC+7 для Новосибирска
const int daylightOffset_sec = 0;
// ========== НАСТРОЙКИ БУДИЛЬНИКА ==========
const int ALARM_HOUR = 11;
const int ALARM_MINUTE = 01;
const int LED_PIN = 4;
const int BUZZER_PIN = 5;
// ========== ЖК-Дисплей ==========
LiquidCrystal_I2C lcd(0x27, 16, 2); // Адрес 0x27, 16 символов × 2 строки
// ========== ФЛАГИ ==========
bool alarmTriggered = false; // Флаг: будильник сработал
bool lastAlarmState = false; // Предыдущее состояние для однократного срабатывания
void setup() {
Serial.begin(115200);
// Инициализация дисплея
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Smart Alarm Clock");
lcd.setCursor(0, 1);
lcd.print("Connecting WiFi...");
// Настройка пинов
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// Подключение к WiFi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
lcd.setCursor(14, 1);
lcd.print(".");
}
Serial.println("\nWiFi connected!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi: Connected!");
lcd.setCursor(0, 1);
lcd.print("Syncing time...");
// Настройка и синхронизация времени
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
// Ждём получения времени (до 10 секунд)
struct tm timeinfo;
int timeout = 0;
while (!getLocalTime(&timeinfo) && timeout < 10) {
delay(1000);
timeout++;
Serial.print("Waiting for time sync... ");
Serial.println(timeout);
}
lcd.clear();
if (timeout < 10) {
lcd.print("Time synced!");
Serial.println("Time synchronized successfully!");
} else {
lcd.print("Time sync failed!");
Serial.println("Failed to get time from NTP!");
}
delay(2000);
}
void loop() {
struct tm timeinfo;
// Получаем актуальное время
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
lcd.clear();
lcd.print("Time error!");
delay(2000);
return;
}
// ===== ОТОБРАЖЕНИЕ ВРЕМЕНИ НА ЖК =====
lcd.setCursor(0, 0);
lcd.printf("%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
lcd.setCursor(0, 1);
lcd.printf("%02d.%02d.%04d", timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900);
// Вывод в серийный монитор для отладки
Serial.printf("Time: %02d:%02d:%02d | Date: %02d.%02d.%04d\n",
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec,
timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900);
// ===== ПРОВЕРКА БУДИЛЬНИКА =====
bool isAlarmTime = (timeinfo.tm_hour == ALARM_HOUR && timeinfo.tm_min == ALARM_MINUTE);
// Срабатывание будильника (однократно при переходе в нужное время)
if (isAlarmTime && !lastAlarmState && !alarmTriggered) {
triggerAlarm();
alarmTriggered = true;
}
// Сброс флага будильника, если время прошло
if (!isAlarmTime) {
alarmTriggered = false;
digitalWrite(LED_PIN, LOW);
noTone(BUZZER_PIN);
}
lastAlarmState = isAlarmTime;
delay(1000); // Обновление раз в секунду
}
// ===== ФУНКЦИЯ СРАБАТЫВАНИЯ БУДИЛЬНИКА =====
void triggerAlarm() {
Serial.println("⏰ ALARM TRIGGERED!");
// Мигание светодиодом
for (int i = 0; i < 10; i++) {
digitalWrite(LED_PIN, HIGH);
tone(BUZZER_PIN, 1000, 200); // Звук 1 кГц, 200 мс
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("!!! ALARM !!!");
lcd.setCursor(0, 1);
lcd.print("Wake up!");
delay(300);
digitalWrite(LED_PIN, LOW);
noTone(BUZZER_PIN);
delay(300);
}
// Возврат к отображению времени
lcd.clear();
}