/
gavr1337
/
smart_socket
Обзор
Документация
Войти
/
gavr1337
/
smart_socket
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/main.cpp
462 строки
10 KB
Igor Gorodensky
release 1.0
22 дек 2025, 20:20
22 дек 2025, 20:20
ce5c3e0
Код
Авторство
О чём код?
#include <Arduino.h> #include "general.h" #include "lcd.h" #include "keypad_mod.h" #include "timer.h" #include "menu.h" #include "wifi_control.h" #include "rtc_mod.h" GyverPortal ui; static struct Timer t_timer; bool isDataDisplayed; bool isManual = true; bool isRelayOn = false; uint32_t timerInterval = 0; uint32_t timerIntervalRtc = 0; TriggerEvent currentTriggerEvent = TriggerEvent::timer; RtcDateTime rtcTriggerTime; void displayCurrentWindow(MenuWindow window); void checkDataDisplayed(); void selectSubWindow(); void startTimer(struct Timer &t_timer); void startRtc(RtcDateTime date_time); void timerTriggered(); void attachActions(); void setup() { initLcd(); initKeyPad(); initRtc(); memset(&t_timer, 0, sizeof(Timer)); pinMode(RELAY_PIN, OUTPUT); WiFi.softAP("Smart_socket", "123456789"); ui.attachBuild(buildUi); ui.attach(attachActions); ui.start(); } void loop() { ui.tick(); checkDataDisplayed(); if (TriggerEvent::rtc == currentTriggerEvent) { if (millis() - timerIntervalRtc >= 999) { timerIntervalRtc = millis(); startRtc(getRtcDateTime()); } } else startTimer(t_timer); int clientCount = WiFi.softAPgetStationNum(); if (clientCount <= 0) isManual = false; else isManual = true; if (!isManual) { if (MenuWindow::remoteControl == getCurrentWindow()) { isDataDisplayed = false; toTimeDisplayUpWindow(); } char key = getPadKey(); switch (key) { case '#': toNextWindow(); isDataDisplayed = false; checkDataDisplayed(); break; case '*': toPreviousWindow(); isDataDisplayed = false; checkDataDisplayed(); break; case 'D': selectSubWindow(); break; default: break; } } else { if (MenuWindow::remoteControl != getCurrentWindow()) { isDataDisplayed = false; toRemoteControl(); } } } void displayCurrentWindow(MenuWindow window) { clearLcd(); switch (window) { case MenuWindow::remoteControl: printData("WiFi mode", 4, 0); break; case MenuWindow::setTime: if (TriggerEvent::timer == currentTriggerEvent) printData("Timer settings", 1, 0); else printData("Alarm settings", 1, 0); break; case MenuWindow::currentTime: { if (TriggerEvent::timer == currentTriggerEvent) { printData("Timer clock", 2, 0); char printTime[9] = {0}; snprintf(printTime, sizeof(printTime), "%02d:%02d:%02d", t_timer.hours, t_timer.minutes, t_timer.seconds); printData(printTime, 4, 1); } else { printData("Alarm clock", 2, 0); char printTime[9] = {0}; snprintf(printTime, sizeof(printTime), "%02d:%02d:%02d", rtcTriggerTime.Hour(), rtcTriggerTime.Minute(), rtcTriggerTime.Second()); printData(printTime, 4, 1); } break; } case MenuWindow::currentMode: { printData("Set trigger mode", 0, 0); auto triggerMode = getCurrentTriggerMode(); switch (triggerMode) { case TriggerMode::off: printData("Off", 6, 1); break; case TriggerMode::on: printData("On", 7, 1); break; case TriggerMode::toggle: printData("Toggle", 5, 1); break; default: break; } break; } case MenuWindow::relayState: isRelayOn = digitalRead(RELAY_PIN); printData("Relay state", 3, 0); if (isRelayOn) printData("On", 7, 1); else printData("Off", 6, 1); break; case MenuWindow::triggerEvent: printData("Trigger event", 1, 0); if (TriggerEvent::timer == currentTriggerEvent) printData("Timer", 5, 1); else printData("Alarm", 5, 1); break; case MenuWindow::setRtc: printData("RTC settings", 2, 0); break; case MenuWindow::timeIsUp: timerTriggered(); break; default: break; } } void checkDataDisplayed() { if (t_timer.isTriggered) toTimeIsUpWindow(); if (!isDataDisplayed) { isDataDisplayed = true; displayCurrentWindow(getCurrentWindow()); } } void selectSubWindow() { auto window = getCurrentWindow(); // switch (window) { case MenuWindow::setTime: if (TriggerEvent::timer == currentTriggerEvent) { if (!t_timer.isActive) toSetTimeWindow(t_timer); } else toRtcSetupWindow(rtcTriggerTime); break; case MenuWindow::currentTime: t_timer.isActive = !t_timer.isActive; if (TriggerMode::off == getCurrentTriggerMode()) digitalWrite(RELAY_PIN, HIGH); break; case MenuWindow::relayState: isRelayOn = !isRelayOn; digitalWrite(RELAY_PIN, isRelayOn); clearLcd(); printData("Relay state", 3, 0); if (isRelayOn) printData("On", 7, 1); else printData("Off", 6, 1); break; case MenuWindow::triggerEvent: if (TriggerEvent::timer == currentTriggerEvent) currentTriggerEvent = TriggerEvent::rtc; else currentTriggerEvent = TriggerEvent::timer; isDataDisplayed = false; break; case MenuWindow::currentMode: toSetModeWindow(); break; case MenuWindow::setRtc: { RtcDateTime date_time = getRtcDateTime(); if (toRtcSetupWindow(date_time)) setRtcDateTime(date_time); break; } default: break; } } void startTimer(struct Timer &t_timer) { if (!t_timer.isActive) return; if ((t_timer.hours == 0) && (t_timer.minutes == 0) && (t_timer.seconds == 0)) { t_timer.isActive = false; t_timer.isTriggered = true; isDataDisplayed = false; return; } if (millis() - timerInterval >= 1000) { timerInterval = millis(); if (t_timer.seconds > 0) { t_timer.seconds--; } else { t_timer.seconds = 59; if (t_timer.minutes > 0) { t_timer.minutes--; } else { t_timer.minutes = 59; if (t_timer.hours > 0) { t_timer.hours--; } } } isDataDisplayed = false; } } void startRtc(RtcDateTime date_time) { if (!t_timer.isActive) return; if ((date_time.Hour() == rtcTriggerTime.Hour()) && (date_time.Minute() == rtcTriggerTime.Minute()) && (date_time.Second() >= rtcTriggerTime.Second())) { t_timer.isTriggered = true; isDataDisplayed = false; t_timer.isActive = false; } } void timerTriggered() { printData("Time is up!", 2, 0); tone(BUZZER_PIN, 2048); auto triggerMode = getCurrentTriggerMode(); switch (triggerMode) { case TriggerMode::off: digitalWrite(RELAY_PIN, LOW); break; case TriggerMode::on: digitalWrite(RELAY_PIN, HIGH); break; case TriggerMode::toggle: digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN)); break; default: break; } while (1) { ui.tick(); if ('D' == getPadKey()) break; if (!t_timer.isTriggered) break; } toTimeDisplayUpWindow(); t_timer.isTriggered = false; isDataDisplayed = false; noTone(BUZZER_PIN); digitalWrite(RELAY_PIN, LOW); } void attachActions() { if (ui.update()) { ui.updateInt("spinner_hh", t_timer.hours); ui.updateInt("spinner_mm", t_timer.minutes); ui.updateInt("spinner_ss", t_timer.seconds); ui.updateInt("trigger_mode", static_cast<int>(getCurrentTriggerMode())); ui.updateInt("trigger_event", static_cast<int>(currentTriggerEvent)); isRelayOn = digitalRead(RELAY_PIN); ui.updateBool("relay_led", isRelayOn); RtcDateTime rtcTime = getRtcDateTime(); ui.updateInt("rtc_hh", rtcTime.Hour()); ui.updateInt("rtc_mm", rtcTime.Minute()); ui.updateInt("rtc_ss", rtcTime.Second()); ui.updateInt("alarm_hh", rtcTriggerTime.Hour()); ui.updateInt("alarm_mm", rtcTriggerTime.Minute()); ui.updateInt("alarm_ss", rtcTriggerTime.Second()); } if (ui.click()) { int triggerMode = static_cast<int>(getCurrentTriggerMode()); int triggerEvent = static_cast<int>(currentTriggerEvent); if (ui.clickInt("spinner_hh", t_timer.hours)) { } else if (ui.clickInt("spinner_mm", t_timer.minutes)) { } else if (ui.clickInt("spinner_ss", t_timer.seconds)) { } RtcDateTime rtcTime = getRtcDateTime(); uint8_t hh = 0, mm = 0, ss = 0; if (ui.clickInt("rtc_hh", hh)) { rtcTime = RtcDateTime(rtcTime.Year(), rtcTime.Month(), rtcTime.Day(), hh, rtcTime.Minute(), rtcTime.Second()); setRtcDateTime(rtcTime); } else if (ui.clickInt("rtc_mm", mm)) { rtcTime = RtcDateTime(rtcTime.Year(), rtcTime.Month(), rtcTime.Day(), rtcTime.Hour(), mm, rtcTime.Second()); setRtcDateTime(rtcTime); } else if (ui.clickInt("rtc_ss", ss)) { rtcTime = RtcDateTime(rtcTime.Year(), rtcTime.Month(), rtcTime.Day(), rtcTime.Hour(), rtcTime.Minute(), ss); setRtcDateTime(rtcTime); } else if (ui.clickInt("alarm_hh", hh)) { rtcTriggerTime = RtcDateTime(rtcTriggerTime.Year(), rtcTriggerTime.Month(), rtcTriggerTime.Day(), hh, rtcTriggerTime.Minute(), rtcTriggerTime.Second()); } else if (ui.clickInt("alarm_mm", mm)) { rtcTriggerTime = RtcDateTime(rtcTriggerTime.Year(), rtcTriggerTime.Month(), rtcTriggerTime.Day(), rtcTriggerTime.Hour(), mm, rtcTriggerTime.Second()); } else if (ui.clickInt("alarm_ss", ss)) { rtcTriggerTime = RtcDateTime(rtcTriggerTime.Year(), rtcTriggerTime.Month(), rtcTriggerTime.Day(), rtcTriggerTime.Hour(), rtcTriggerTime.Minute(), ss); } else if (ui.click("start_timer")) { if (!t_timer.isTriggered) t_timer.isActive = !t_timer.isActive; else t_timer.isTriggered = false; if (TriggerMode::off == getCurrentTriggerMode()) digitalWrite(RELAY_PIN, HIGH); } else if (ui.clickInt("trigger_mode", triggerMode)) { setCurrentTriggerMode(static_cast<TriggerMode>(triggerMode)); } else if (ui.clickInt("trigger_event", triggerEvent)) { currentTriggerEvent = static_cast<TriggerEvent>(triggerEvent); if (TriggerEvent::timer == currentTriggerEvent) t_timer.isActive = false; else { t_timer.isActive = true; if (TriggerMode::off == getCurrentTriggerMode()) digitalWrite(RELAY_PIN, HIGH); } } else if (ui.click("relay_button")) { isRelayOn = digitalRead(RELAY_PIN); isRelayOn = !isRelayOn; ui.updateBool("relay_led", isRelayOn); digitalWrite(RELAY_PIN, isRelayOn); } isDataDisplayed = false; } }