From aba98c4924feba31e92198622b31c71b59f1ed99 Mon Sep 17 00:00:00 2001 From: maks_gein Date: Sat, 5 Jul 2025 13:10:16 +0000 Subject: [PATCH] Update ESP82_PANEL.ino --- ESP82_PANEL.ino | 540 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 359 insertions(+), 181 deletions(-) diff --git a/ESP82_PANEL.ino b/ESP82_PANEL.ino index f9a4e99..4326d0e 100644 --- a/ESP82_PANEL.ino +++ b/ESP82_PANEL.ino @@ -6,36 +6,75 @@ #include #include #include "data/output.h" +#include "data/bear.h" #include "data/kitleft.h" -const uint8_t* FONT = Font_BOLD; +// Константы +const uint8_t *FONT = Font_BOLD; const int WIDTH = 4; // Количество матриц в ширину const int HEIGHT = 3; // Количество матриц в высоту +const int DISPLAY_WIDTH = WIDTH * 32; +const int DISPLAY_HEIGHT = HEIGHT * 16; +const int TEXT_Y_OFFSET = 17; +const int SCROLL_DELAY = 5; // Задержка для скролла в секундах +const int SCROLL_SPEED = 30; // Скорость скролла в мс + +const int TEXT_HEIGHT = 16; // Высота области для текста +const int TOP_LOGO_HEIGHT = 16; // Высота верхнего логотипа +const int BOTTOM_LOGO_HEIGHT = 16; // Высота нижнего логотипа + +// Настройки WiFi +const char *SSID = "SSID"; +const char *PASSWORD = "PASSWORD"; -AsyncWebServer server(80); -String displayText = "Привет из СКБ \"КИТ\""; -bool isON = true; -bool showText = true; -bool scroll = true; -const char* skb = "СКБ"; -const char* kit = "\"КИТ\""; -const char* ictib = "ИКТИБ"; -const char* ssid = "SKBKIT"; -const char* password = "skbkit2024"; IPAddress staticIP(10, 131, 170, 4); IPAddress gateway(10, 131, 170, 1); IPAddress subnet(255, 255, 255, 0); +// Текстовые константы +const char SKB[] PROGMEM = "СКБ"; +const char KIT[] PROGMEM = "\"КИТ\""; +const char ICTIB[] PROGMEM = "ИКТИБ"; + +// Перечисления для состояний +enum class PanelState : int { + STATIC_LOGO = 0, + SCROLLING_TEXT = 1, + ANIMATED_LOGO = 2, + BEAR = 3, + UNKNOWN = -1 +}; + +enum class PanelPower : int { + POWER_OFF = 0, + POWER_ON = 1 +}; + +// Глобальные переменные +AsyncWebServer server(80); +String displayText = "СКБ~\"КИТ\""; +PanelState currentState = PanelState::ANIMATED_LOGO; +PanelPower panelPower = PanelPower::POWER_ON; +bool showText = true; +bool isUpdater = false; +bool scrollEnabled = false; +int scrollPosition = 0; + +unsigned long lastScrollTime = 0; + SPIDMD dmd(WIDTH, HEIGHT); -DMD_TextBox* box = nullptr; // Указатель на текстовый бокс -Ticker ticker; +DMD_TextBox *box = nullptr; +Ticker modeTicker; +Ticker scrollTicker; void setupWiFi() { - WiFi.begin(ssid, password); + Serial.print("Подключение к WiFi "); + Serial.println(SSID); + WiFi.begin(SSID, PASSWORD); if (!WiFi.config(staticIP, gateway, subnet)) { - Serial.println("Failed WiFi connect!"); + Serial.println("Ошибка настройки статического IP!"); } else { - Serial.println("Static WiFi configured!"); + Serial.println("Статический IP настроен"); } while (WiFi.status() != WL_CONNECTED) { @@ -43,225 +82,364 @@ void setupWiFi() { Serial.print("."); } - Serial.println("\nConnected to WiFi"); + Serial.println("\nПодключено к WiFi"); + Serial.print("IP адрес: "); Serial.println(WiFi.localIP()); +// WiFi.forceSleepWake(); } -void drawBinaryArrayKit() { +void drawBinaryArray(const uint8_t *data) { dmd.clearScreen(); - for (int x = 0; x < WIDTH * 32; x++) { - for (int y = 0; y < HEIGHT * 16; y++) { - int idx = y * (WIDTH * 32) + x; // Индекс с учетом полной ширины - if (output[idx] == 1) { - dmd.setPixel(x, y, GRAPHICS_ON); - } else { - dmd.setPixel(x, y, GRAPHICS_OFF); - } - } - } -} - -void drawBinaryArrayKitLeft() { - dmd.clearScreen(); - - for (int x = 0; x < WIDTH * 32; x++) { - for (int y = 0; y < HEIGHT * 16; y++) { - int idx = y * (WIDTH * 32) + x; // Индекс с учетом полной ширины - if (kitleft[idx] == 1) { - dmd.setPixel(x, y, GRAPHICS_ON); - } else { - dmd.setPixel(x, y, GRAPHICS_OFF); - } + for (int y = 0; y < DISPLAY_HEIGHT; y++) { + for (int x = 0; x < DISPLAY_WIDTH; x++) { + uint8_t pixel = pgm_read_byte(&data[y * DISPLAY_WIDTH + x]); + dmd.setPixel(x, y, pixel ? GRAPHICS_ON : GRAPHICS_OFF); } } } void switchDisplayMode() { - if (isON) { + if (panelPower == PanelPower::POWER_ON) { if (showText) { - drawScrollingText(); // Запускаем скролл текста на второй строке + drawScrollingText(); } else { - drawBinaryArrayKit(); + drawBinaryArray(output); } showText = !showText; } } -void switchDisplayModeScroll() { - if (isON && scroll) { - //box->scrollX(1); // Двигаем текст влево - //box->drawScrollingText(); - dmd.marqueeScrollX(1); - } -} - void drawScrollingText() { - if (!box) { - box = new DMD_TextBox(dmd, 0, 17, WIDTH * 32, HEIGHT * 16); // Устанавливаем текстовый бокс на вторую строку - } else { - box->clear(); + + if(box){ + delete box; + box = nullptr; } + // Вычисляем ширину текста + int textWidth = dmd.stringWidth(displayText.c_str()); - box->print(displayText.c_str()); -} + // Определяем, нужен ли скроллинг + scrollEnabled = (textWidth > DISPLAY_WIDTH); - - -void drawText() { + // Очищаем экран dmd.clearScreen(); - if (!box) { // Создаём текстовый бокс только один раз - box = new DMD_TextBox(dmd, 0, 0, WIDTH * 32, HEIGHT * 16); + // Рисуем статические элементы + drawKitLogoTop(); + drawKitLogoBottom(); + + // Устанавливаем начальную позицию + scrollPosition = scrollEnabled ? DISPLAY_WIDTH : (DISPLAY_WIDTH - textWidth) / 2; + + // Рисуем начальное положение текста + if (box) { + delete box; + } + box = new DMD_TextBox(dmd, scrollPosition, TEXT_Y_OFFSET, DISPLAY_WIDTH, TEXT_HEIGHT); + box->print(displayText.c_str()); + + // Управляем тикером + scrollTicker.detach(); + if (scrollEnabled) { + scrollTicker.attach_ms(SCROLL_SPEED, handleScroll); } else { - box->clear(); // Очищаем текущий бокс перед обновлением текста + scrollTicker.detach(); + } +} + +void handleScroll() { + if (!scrollEnabled || panelPower != PanelPower::POWER_ON || currentState != PanelState::SCROLLING_TEXT) { + return; } + unsigned long currentTime = millis(); + if (currentTime - lastScrollTime < SCROLL_SPEED) { + return; + } + lastScrollTime = currentTime; + + // Вычисляем ширину текста + int textWidth = dmd.stringWidth(displayText.c_str()); + + // Обновляем позицию + scrollPosition--; + + // Проверяем, нужно ли перезапустить скроллинг + if (scrollPosition < -textWidth) { + scrollPosition = DISPLAY_WIDTH; + } + + // Очищаем только текстовую область + for (int y = TEXT_Y_OFFSET; y < TEXT_Y_OFFSET + TEXT_HEIGHT; y++) { + for (int x = 0; x < DISPLAY_WIDTH; x++) { + dmd.setPixel(x, y, GRAPHICS_OFF); + } + } + + // Рисуем текст с помощью DMD_TextBox + if (box) { + delete box; + } + box = new DMD_TextBox(dmd, scrollPosition, TEXT_Y_OFFSET, DISPLAY_WIDTH, TEXT_HEIGHT); box->print(displayText.c_str()); } -void handleText(AsyncWebServerRequest* request, const JsonVariant& json) { +void drawKitLogoTop() { + dmd.drawLine(0, 14, 16, 14, GRAPHICS_ON); // x y x y + dmd.drawLine(0, 13, 16, 13, GRAPHICS_ON); + + dmd.drawLine(16, 14, 20, 5, GRAPHICS_ON); + dmd.drawLine(16, 13, 20, 4, GRAPHICS_ON); + + dmd.drawLine(20, 5, 30, 5, GRAPHICS_ON); + dmd.drawLine(20, 4, 30, 4, GRAPHICS_ON); + + dmd.drawCircle(33, 4, 3, GRAPHICS_ON); + dmd.drawCircle(33, 4, 2, GRAPHICS_ON); // 1 line + + dmd.drawLine(20, 14, 50, 14, GRAPHICS_ON); + dmd.drawLine(20, 13, 50, 13, GRAPHICS_ON); + + dmd.drawLine(50, 14, 55, 5, GRAPHICS_ON); + dmd.drawLine(50, 13, 55, 4, GRAPHICS_ON); + + dmd.drawLine(55, 5, 70, 5, GRAPHICS_ON); + dmd.drawLine(55, 4, 70, 4, GRAPHICS_ON); + + dmd.drawLine(70, 5, 75, 14, GRAPHICS_ON); + dmd.drawLine(70, 4, 75, 13, GRAPHICS_ON); + + dmd.drawLine(75, 14, 85, 14, GRAPHICS_ON); + dmd.drawLine(75, 13, 85, 13, GRAPHICS_ON); + dmd.drawCircle(88, 13, 3, GRAPHICS_ON); + dmd.drawCircle(88, 13, 2, GRAPHICS_ON); // 2 line + + dmd.drawCircle(78, 4, 3, GRAPHICS_ON); + dmd.drawCircle(78, 4, 2, GRAPHICS_ON); + dmd.drawLine(81, 5, 95, 5, GRAPHICS_ON); + dmd.drawLine(81, 4, 95, 4, GRAPHICS_ON); + dmd.drawLine(95, 5, 100, 14, GRAPHICS_ON); + dmd.drawLine(95, 4, 100, 13, GRAPHICS_ON); + dmd.drawLine(100, 14, 110, 14, GRAPHICS_ON); + dmd.drawLine(100, 13, 110, 13, GRAPHICS_ON); + dmd.drawLine(110, 14, 115, 5, GRAPHICS_ON); + dmd.drawLine(110, 13, 115, 4, GRAPHICS_ON); + dmd.drawLine(115, 5, 128, 5, GRAPHICS_ON); + dmd.drawLine(115, 4, 128, 4, GRAPHICS_ON); // 3 line +} + +void drawKitLogoBottom() { + dmd.drawLine(0, 35, 16, 35, GRAPHICS_ON); + dmd.drawLine(0, 36, 16, 36, GRAPHICS_ON); + dmd.drawLine(16, 35, 21, 43, GRAPHICS_ON); + dmd.drawLine(16, 36, 21, 44, GRAPHICS_ON); + dmd.drawLine(21, 43, 31, 43, GRAPHICS_ON); + dmd.drawLine(21, 44, 31, 44, GRAPHICS_ON); + dmd.drawCircle(34, 44, 3, GRAPHICS_ON); + dmd.drawCircle(34, 44, 2, GRAPHICS_ON); // 1 line + + dmd.drawLine(20, 35, 50, 35, GRAPHICS_ON); + dmd.drawLine(20, 36, 50, 36, GRAPHICS_ON); + dmd.drawLine(50, 35, 55, 43, GRAPHICS_ON); + dmd.drawLine(50, 36, 55, 44, GRAPHICS_ON); // 2 line + + dmd.drawLine(55, 43, 70, 43, GRAPHICS_ON); + dmd.drawLine(55, 44, 70, 44, GRAPHICS_ON); + + dmd.drawLine(70, 43, 75, 35, GRAPHICS_ON); + dmd.drawLine(70, 44, 75, 36, GRAPHICS_ON); + dmd.drawLine(75, 35, 85, 35, GRAPHICS_ON); + dmd.drawLine(75, 36, 85, 36, GRAPHICS_ON); + dmd.drawCircle(88, 36, 3, GRAPHICS_ON); + dmd.drawCircle(88, 36, 2, GRAPHICS_ON); + + dmd.drawCircle(78, 44, 3, GRAPHICS_ON); + dmd.drawCircle(78, 44, 2, GRAPHICS_ON); + dmd.drawLine(81, 43, 95, 43, GRAPHICS_ON); + dmd.drawLine(81, 44, 95, 44, GRAPHICS_ON); + dmd.drawLine(95, 43, 100, 35, GRAPHICS_ON); + dmd.drawLine(95, 44, 100, 36, GRAPHICS_ON); + dmd.drawLine(100, 35, 110, 35, GRAPHICS_ON); + dmd.drawLine(100, 36, 110, 36, GRAPHICS_ON); + dmd.drawLine(110, 35, 115, 43, GRAPHICS_ON); + dmd.drawLine(110, 36, 115, 44, GRAPHICS_ON); + dmd.drawLine(115, 43, 128, 43, GRAPHICS_ON); + dmd.drawLine(115, 44, 128, 44, GRAPHICS_ON); +} + +void drawBear(){ + drawBinaryArray(bear); +} + +void drawKitLeftLogoWithText() { + drawBinaryArray(kitleft); + dmd.drawString_P(79, 2, SKB); + dmd.drawString_P(71, 17, KIT); + dmd.drawString_P(68, 32, ICTIB); +} + +void updateScreen() { + modeTicker.detach(); + scrollTicker.detach(); + + if (panelPower == PanelPower::POWER_OFF) { + dmd.clearScreen(); + return; + } + + switch (currentState) { + case PanelState::SCROLLING_TEXT: + drawKitLogoTop(); // Статичный верхний логотип + drawScrollingText(); // Прокручиваемый текст + drawKitLogoBottom(); // Статичный нижний логотип + + if (scrollEnabled) { + scrollTicker.attach_ms(SCROLL_SPEED, handleScroll); + } + break; + + case PanelState::ANIMATED_LOGO: + dmd.clearScreen(); + drawText(); + modeTicker.attach(SCROLL_DELAY, switchDisplayMode); + dmd.clearScreen(); + drawBinaryArray(output); + break; + + case PanelState::STATIC_LOGO: + dmd.clearScreen(); + drawKitLeftLogoWithText(); + break; + + case PanelState::BEAR: + dmd.clearScreen(); + drawBear(); + break; + + default: + dmd.clearScreen(); + drawKitLeftLogoWithText(); + break; + } +} + +void drawText() { + int textWidth = dmd.stringWidth(displayText, Font_BOLD); + int xOffset = (textWidth < DISPLAY_WIDTH) ? (DISPLAY_WIDTH - textWidth) / 2 : 0; + + if (box) { + delete box; + box = nullptr; + } + + box = new DMD_TextBox(dmd, xOffset, TEXT_Y_OFFSET, DISPLAY_WIDTH, DISPLAY_HEIGHT); + box->print(displayText.c_str()); +} + +PanelState intToPanelState(int state) { + switch (state) { + case 0: + return PanelState::STATIC_LOGO; + case 1: + return PanelState::SCROLLING_TEXT; + case 2: + return PanelState::ANIMATED_LOGO; + case 3: + return PanelState::BEAR; + default: + return PanelState::UNKNOWN; + } +} + +String panelStateToString(PanelState state) { + switch (state) { + case PanelState::STATIC_LOGO: + return "0"; + case PanelState::SCROLLING_TEXT: + return "1"; + case PanelState::ANIMATED_LOGO: + return "2"; + case PanelState::BEAR: + return "3"; + default: + return "-1"; + } +} + +void handleText(AsyncWebServerRequest *request, const JsonVariant &json) { if (!json.containsKey("text")) { request->send(400, "application/json", "{\"error\": \"Missing text field\"}"); return; } displayText = json["text"].as(); - drawText(); + isUpdater = true; + updateScreen(); request->send(200, "application/json", "{\"status\": \"OK\"}"); } -void handleTurn(AsyncWebServerRequest* request, const JsonVariant& json) { - String panelTurn = json["panel"].as(); - String panelState = json["state"].as(); +void handleTurn(AsyncWebServerRequest *request, const JsonVariant &json) { + bool powerChanged = false; + bool modeChanged = false; + // Обработка включения/выключения панели if (json.containsKey("panel")) { - panelTurn = json["panel"].as(); - } - if (json.containsKey("state")) { - panelState = json["state"].as(); - } + String panelTurn = json["panel"].as(); - ticker.detach(); - - if (!panelTurn.isEmpty()) { + PanelPower newPower; if (panelTurn == "on") { - isON = true; + newPower = PanelPower::POWER_ON; } else if (panelTurn == "off") { - isON = false; - dmd.clearScreen(); - dmd.drawFilledBox(0, 0, WIDTH * 32 - 1, HEIGHT * 16 - 1, GRAPHICS_OFF); + newPower = PanelPower::POWER_OFF; + } else { + request->send(400, "application/json", "{\"error\": \"Invalid panel value, use 'on' or 'off'\"}"); + return; } + + powerChanged = (panelPower != newPower); + panelPower = newPower; } - if (!panelState.isEmpty()) { - if (panelState == "1") { // Скролинг текста - dmd.clearScreen(); - dmd.selectFont(FONT); - dmd.drawLine(0, 14, 16, 14, GRAPHICS_ON); // x y x y - dmd.drawLine(0, 13, 16, 13, GRAPHICS_ON); + // Обработка изменения режима + if (json.containsKey("state")) { + int panelStateInt = json["state"].as(); + PanelState newState = intToPanelState(panelStateInt); - dmd.drawLine(16, 14, 20, 5, GRAPHICS_ON); - dmd.drawLine(16, 13, 20, 4, GRAPHICS_ON); - - dmd.drawLine(20, 5, 30, 5, GRAPHICS_ON); - dmd.drawLine(20, 4, 30, 4, GRAPHICS_ON); - - dmd.drawCircle(33, 4, 3, GRAPHICS_ON); - dmd.drawCircle(33, 4, 2, GRAPHICS_ON); //1 line - - dmd.drawLine(20, 14, 40, 14, GRAPHICS_ON); - dmd.drawLine(20, 13, 40, 13, GRAPHICS_ON); - - dmd.drawLine(40, 14, 45, 5, GRAPHICS_ON); - dmd.drawLine(40, 13, 45, 4, GRAPHICS_ON); - - dmd.drawLine(45, 5, 60, 5, GRAPHICS_ON); - dmd.drawLine(45, 4, 60, 4, GRAPHICS_ON); - - dmd.drawLine(60, 5, 65, 14, GRAPHICS_ON); - dmd.drawLine(60, 4, 65, 13, GRAPHICS_ON); - - dmd.drawLine(65, 14, 75, 14, GRAPHICS_ON); - dmd.drawLine(65, 13, 75, 13, GRAPHICS_ON); - dmd.drawCircle(78, 13, 3, GRAPHICS_ON); - dmd.drawCircle(78, 13, 2, GRAPHICS_ON); //2 line - - dmd.drawCircle(68, 4, 3, GRAPHICS_ON); - dmd.drawCircle(68, 4, 2, GRAPHICS_ON); - dmd.drawLine(71, 5, 85, 5, GRAPHICS_ON); - dmd.drawLine(71, 4, 85, 4, GRAPHICS_ON); - dmd.drawLine(85, 5, 90, 14, GRAPHICS_ON); - dmd.drawLine(85, 4, 90, 13, GRAPHICS_ON); - dmd.drawLine(90, 14, 100, 14, GRAPHICS_ON); - dmd.drawLine(90, 13, 100, 13, GRAPHICS_ON); - dmd.drawLine(100, 14, 105, 5, GRAPHICS_ON); - dmd.drawLine(100, 13, 105, 4, GRAPHICS_ON); - dmd.drawLine(105, 5, 128, 5, GRAPHICS_ON); - dmd.drawLine(105, 4, 128, 4, GRAPHICS_ON); // 3 line - - // ====================================== - - dmd.drawLine(0, 35, 16, 35, GRAPHICS_ON); - dmd.drawLine(0, 36, 16, 36, GRAPHICS_ON); - dmd.drawLine(16, 35, 21, 43, GRAPHICS_ON); - dmd.drawLine(16, 36, 21, 44, GRAPHICS_ON); - dmd.drawLine(21, 43, 31, 43, GRAPHICS_ON); - dmd.drawLine(21, 44, 31, 44, GRAPHICS_ON); - dmd.drawCircle(34, 44, 3, GRAPHICS_ON); - dmd.drawCircle(34, 44, 2, GRAPHICS_ON); // 1 line - - dmd.drawLine(20, 35, 40, 35, GRAPHICS_ON); - dmd.drawLine(20, 36, 40, 36, GRAPHICS_ON); - dmd.drawLine(40, 35, 45, 43, GRAPHICS_ON); - dmd.drawLine(40, 36, 45, 44, GRAPHICS_ON); // 2 line - - dmd.drawLine(45, 43, 60, 43, GRAPHICS_ON); - dmd.drawLine(45, 44, 60, 44, GRAPHICS_ON); - - dmd.drawLine(60, 43, 65, 35, GRAPHICS_ON); - dmd.drawLine(60, 44, 65, 36, GRAPHICS_ON); - dmd.drawLine(65, 35, 75, 35, GRAPHICS_ON); - dmd.drawLine(65, 36, 75, 36, GRAPHICS_ON); - dmd.drawCircle(78, 36, 3, GRAPHICS_ON); - dmd.drawCircle(78, 36, 2, GRAPHICS_ON); - } else if (panelState == "2") { // Текст и картинка динамика - dmd.clearScreen(); - drawText(); - ticker.attach(5, switchDisplayMode); - dmd.clearScreen(); - drawBinaryArrayKit(); - } else if (panelState == "3") { // Текст и картинка статика - dmd.clearScreen(); - drawBinaryArrayKitLeft(); - dmd.drawString_P(79, 2, skb); - dmd.drawString_P(71, 17, kit); - dmd.drawString_P(68, 32, ictib); + if (newState == PanelState::UNKNOWN) { + request->send(400, "application/json", "{\"error\": \"Invalid state value\"}"); + return; } + + modeChanged = (currentState != newState); + currentState = newState; } - String response = "{\"panel\" : " + String(isON ? "\"on\"" : "\"off\"") + ", \"state\" : " + (panelState.isEmpty() ? "null" : panelState) + "}"; + if (powerChanged || modeChanged) { + updateScreen(); + } + + String response = "{\"panel\":\"" + String(panelPower == PanelPower::POWER_ON ? "on" : "off") + "\",\"state\":" + panelStateToString(currentState) + "}"; request->send(200, "application/json", response); } void setup() { Serial.begin(9600); + setupWiFi(); + Serial.println("\n\nStarting server..."); + dmd.setBrightness(255); dmd.selectFont(FONT); dmd.begin(); dmd.clearScreen(); - box = new DMD_TextBox(dmd, 0, 0, WIDTH * 32, HEIGHT * 16); // Создаём текстовый бокс один раз - - box->print("Hello"); + panelPower = PanelPower::POWER_ON; + updateScreen(); server.on( - "/api/text", HTTP_POST, - [](AsyncWebServerRequest* request) {}, - NULL, - [](AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t, size_t) { + "/api/text", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t, size_t) { StaticJsonDocument<256> jsonReq; DeserializationError error = deserializeJson(jsonReq, data, len); @@ -270,20 +448,16 @@ void setup() { return; } - handleText(request, jsonReq.as()); // Передаём как const JsonVariant& + handleText(request, jsonReq.as()); }); - server.on("/api/led", HTTP_GET, [](AsyncWebServerRequest* request) { - if (isON) { - request->send(200, "application/json", "{\"panel\" : \"on\"}"); - } else if (!isON) { - request->send(200, "application/json", "{\"panel\" : \"off\"}"); - } + server.on("/api/led", HTTP_GET, [](AsyncWebServerRequest *request) { + request->send(200, "application/json", + String("{\"panel\":\"") + (panelPower == PanelPower::POWER_ON ? "on" : "off") + "\",\"state\":" + String(static_cast(currentState)) + "}"); }); server.on( - "/api/led", HTTP_POST, [](AsyncWebServerRequest* request) {}, - NULL, [](AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t, size_t) { + "/api/led", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t, size_t) { StaticJsonDocument<256> jsonReq; DeserializationError error = deserializeJson(jsonReq, data, len); @@ -299,4 +473,8 @@ void setup() { } void loop() { -} + if (isUpdater) { + isUpdater = false; + updateScreen(); + } +} \ No newline at end of file