diff --git a/data/index.html b/data/index.html new file mode 100644 index 0000000..23ca0e2 --- /dev/null +++ b/data/index.html @@ -0,0 +1,72 @@ + + + + + + Sporttafel + + + + + + + + + + + + + + + + + + + + +
+ + + +  
+ + + + + +
  + +  
+ + \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 7a49482..0238a0b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,6 +2,7 @@ platform = espressif32 board = esp32dev framework = arduino +build_type = debug board_build.filesystem = littlefs lib_deps = bblanchon/ArduinoJson ; https://github.com/adafruit/Adafruit_NeoPixel @@ -9,10 +10,10 @@ lib_deps = bblanchon/ArduinoJson build_flags = -DWIFI_SSID=\"HappyNet\" -DWIFI_PKEY=\"1Grausame!Sackratte7\" -DWIFI_HOST=\"Sporttafel\" -;upload_port = 10.0.0.119 -;upload_protocol = espota -upload_port = /dev/ttyUSB0 -upload_speed = 921600 +upload_port = 10.0.0.119 +upload_protocol = espota +;upload_port = /dev/ttyUSB0 +;upload_speed = 921600 monitor_port = /dev/ttyUSB0 monitor_speed = 115200 monitor_filters = esp32_exception_decoder diff --git a/src/INDEX_HTML.cpp b/src/INDEX_HTML.cpp deleted file mode 100644 index fc29e38..0000000 --- a/src/INDEX_HTML.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "INDEX_HTML.h" - -const char *INDEX_HTML = R"( - - - - Sporttafel - - -

Sporttafel

- - -)"; diff --git a/src/INDEX_HTML.h b/src/INDEX_HTML.h deleted file mode 100644 index 6f974b3..0000000 --- a/src/INDEX_HTML.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef INDEX_HTML_H -#define INDEX_HTML_H - -extern const char *INDEX_HTML; - -#endif diff --git a/src/app/App.cpp b/src/app/App.cpp index 00055fc..f7ecb7a 100644 --- a/src/app/App.cpp +++ b/src/app/App.cpp @@ -1,27 +1,29 @@ #include "App.h" +#include "../core/log.h" + #include "AppMatch.h" App *app = nullptr; uint8_t getHeapUsagePercent() { - return (ESP.getHeapSize() - ESP.getFreeHeap()) / ESP.getHeapSize(); + return static_cast(round((100.0 * ESP.getHeapSize() - ESP.getFreeHeap()) / ESP.getHeapSize())); } void appStart(const String& name) { appStop(); - Serial.printf("Loading app: \"%s\" (heap usage: %d%%)\n", name.c_str(), getHeapUsagePercent()); + info("Loading app: \"%s\" (heap usage: %d%%)", name.c_str(), getHeapUsagePercent()); if (name.equals(APP_MATCH_NAME)) { app = new AppMatch(); } else { - Serial.printf("No such app: \"%s\"\n", name.c_str()); + error("No such app: \"%s\"\n", name.c_str()); return; } - Serial.printf("App instantiated: \"%s\" (heap usage: %d%%)\n", app->getName(), getHeapUsagePercent()); + info("App instantiated: \"%s\" (heap usage: %d%%)", app->getName(), getHeapUsagePercent()); app->start(); - Serial.printf("App started: \"%s\" (heap usage: %d%%)\n", app->getName(), getHeapUsagePercent()); + info("App started: \"%s\" (heap usage: %d%%)", app->getName(), getHeapUsagePercent()); } void appStop() { @@ -29,14 +31,14 @@ void appStop() { return; } const auto name = app->getName(); - Serial.printf("Stopping app: \"%s\" (heap usage: %d%%)\n", name, getHeapUsagePercent()); + info("Stopping app: \"%s\" (heap usage: %d%%)", name, getHeapUsagePercent()); app->stop(); - Serial.printf("App stopped: \"%s\" (heap usage: %d%%)\n", name, getHeapUsagePercent()); + info("App stopped: \"%s\" (heap usage: %d%%)", name, getHeapUsagePercent()); delete app; app = nullptr; - Serial.printf("App unloaded: \"%s\" (heap usage: %d%%)\n", name, getHeapUsagePercent()); + info("App unloaded: \"%s\" (heap usage: %d%%)", name, getHeapUsagePercent()); display.clear(); display.flush(); diff --git a/src/app/App.h b/src/app/App.h index 0b9f38e..c38594b 100644 --- a/src/app/App.h +++ b/src/app/App.h @@ -3,6 +3,7 @@ #include #include +#include class App { @@ -34,12 +35,14 @@ public: } void loop() { - static auto lastMillis = millis(); - const auto dtMillis = millis() - lastMillis; + const auto now = millis(); + static auto lastMillis = now; + const auto dtMillis = now - lastMillis; + lastMillis = now; _loop(dtMillis); if (dirty) { dirty = false; - _draw(); + draw(); } } @@ -47,6 +50,30 @@ public: _stop(); } + virtual void confirm() { + // + } + + virtual void cancel() { + // + } + + virtual void up() { + // + } + + virtual void down() { + // + } + + virtual void left() { + // + } + + virtual void right() { + // + } + protected: template @@ -65,7 +92,7 @@ protected: // } - virtual void _draw() { + virtual void draw() { // } @@ -80,7 +107,9 @@ protected: private: void configLoad() { - auto file = LittleFS.open(String("/apps/") + name + ".json", "r"); + const auto path = String("/apps/") + name + ".json"; + configJson.clear(); + auto file = LittleFS.open(path, "r"); deserializeJson(configJson, file); config = configJson.to(); } diff --git a/src/app/AppMatch.h b/src/app/AppMatch.h index 32d2d6d..b3563cc 100644 --- a/src/app/AppMatch.h +++ b/src/app/AppMatch.h @@ -83,7 +83,7 @@ protected: if (blinkIntervalMillis > 0) { const auto now = millis(); - if (blinkMillis - now > 500) { + if (now - blinkMillis > 500) { blinkMillis = now; blinkState = !blinkState; markDirty(); @@ -102,27 +102,41 @@ protected: } } - void _draw() override { + void draw() override { display.clear(); if (blinkIntervalMillis == 0 || blinkState) { if (totalMinutes > 0) { display.setColor(totalMillis < configMillis / 2 ? YELLOW : GREEN); display.printf("%2d:%02d", totalMinutes, partSeconds); - Serial.printf("%2d:%02d", totalMinutes, partSeconds); + info("%2d:%02d", totalMinutes, partSeconds); } else if (totalMillis > 0) { display.setColor(RED); display.printf("%2d.%02d", partSeconds, partCentis); } else { display.printf("00:00"); } + } else if (state == PAUSE) { + info("PAUS", totalMinutes, partSeconds); } display.flush(); } + void confirm() override { + if (state == PAUSE) { + setState(MINUTES); + } else { + setState(PAUSE); + } + } + + void cancel() override { + _start(); + } + private: void blinkEnable(const unsigned long intervalMillis) { - blinkState = true; + blinkState = false; blinkIntervalMillis = intervalMillis; blinkMillis = millis(); } @@ -146,7 +160,7 @@ private: blinkEnable(100); break; } - Serial.printf("state changed to %s", getStateName()); + info("state changed to %s", getStateName()); markDirty(); } diff --git a/src/boot.cpp b/src/core/boot.cpp similarity index 100% rename from src/boot.cpp rename to src/core/boot.cpp diff --git a/src/boot.h b/src/core/boot.h similarity index 100% rename from src/boot.h rename to src/core/boot.h diff --git a/src/clock.cpp b/src/core/clock.cpp similarity index 100% rename from src/clock.cpp rename to src/core/clock.cpp diff --git a/src/clock.h b/src/core/clock.h similarity index 100% rename from src/clock.h rename to src/core/clock.h diff --git a/src/filesystem.cpp b/src/core/filesystem.cpp similarity index 56% rename from src/filesystem.cpp rename to src/core/filesystem.cpp index 3cdba09..24c9afe 100644 --- a/src/filesystem.cpp +++ b/src/core/filesystem.cpp @@ -1,11 +1,12 @@ #include "filesystem.h" #include +#include "log.h" void filesystemMount() { if (LittleFS.begin(true)) { - Serial.println("filesystem mounted"); + info("filesystem mounted"); } else { - Serial.println("failed to mount filesystem"); + error("failed to mount filesystem"); } } diff --git a/src/filesystem.h b/src/core/filesystem.h similarity index 100% rename from src/filesystem.h rename to src/core/filesystem.h diff --git a/src/core/http.cpp b/src/core/http.cpp new file mode 100644 index 0000000..0396ad5 --- /dev/null +++ b/src/core/http.cpp @@ -0,0 +1,65 @@ +#include "http.h" + +#include +#include +#include "log.h" + +AsyncWebServer server(80); + +void httpIndex(AsyncWebServerRequest *request) { + info(request->url().c_str()); + request->send(LittleFS, "/index.html", "text/html"); +} + +void httpActionLeft(AsyncWebServerRequest *request) { + request->send(200); + if (app != nullptr) { + app->left(); + } +} + +void httpActionUp(AsyncWebServerRequest *request) { + request->send(200); + if (app != nullptr) { + app->up(); + } +} + +void httpActionDown(AsyncWebServerRequest *request) { + request->send(200); + if (app != nullptr) { + app->down(); + } +} + +void httpActionRight(AsyncWebServerRequest *request) { + request->send(200); + if (app != nullptr) { + app->right(); + } +} + +void httpActionCancel(AsyncWebServerRequest *request) { + request->send(200); + if (app != nullptr) { + app->cancel(); + } +} + +void httpActionConfirm(AsyncWebServerRequest *request) { + request->send(200); + if (app != nullptr) { + app->confirm(); + } +} + +void httpSetup() { + server.on("/", HTTP_GET, httpIndex); + server.on("/action/left", HTTP_GET, httpActionLeft); + server.on("/action/up", HTTP_GET, httpActionUp); + server.on("/action/down", HTTP_GET, httpActionDown); + server.on("/action/right", HTTP_GET, httpActionRight); + server.on("/action/cancel", HTTP_GET, httpActionCancel); + server.on("/action/confirm", HTTP_GET, httpActionConfirm); + server.begin(); +} diff --git a/src/http.h b/src/core/http.h similarity index 52% rename from src/http.h rename to src/core/http.h index e4c0a70..abcba1f 100644 --- a/src/http.h +++ b/src/core/http.h @@ -3,8 +3,4 @@ void httpSetup(); -void httpLoop(); - -void httpPublish(char *payload); - #endif diff --git a/src/log.cpp b/src/core/log.cpp similarity index 74% rename from src/log.cpp rename to src/core/log.cpp index 58e1874..0161406 100644 --- a/src/log.cpp +++ b/src/core/log.cpp @@ -1,13 +1,56 @@ #include "log.h" -#include #include +#include #include "clock.h" +void doLog(LogLevel level, const char *format, va_list args); + auto logLevel = DEBUG; -void log(const LogLevel level, const char *format, const va_list args) { +void logSetup() { + delay(500); + Serial.begin(115200); + info("Startup"); +} + +void log(const LogLevel level, const char *format, ...) { + va_list args; + va_start(args, format); + doLog(level, format, args); + va_end(args); +} + +void error(const char *format, ...) { + va_list args; + va_start(args, format); + doLog(ERROR, format, args); + va_end(args); +} + +void warn(const char *format, ...) { + va_list args; + va_start(args, format); + doLog(WARN, format, args); + va_end(args); +} + +void info(const char *format, ...) { + va_list args; + va_start(args, format); + doLog(INFO, format, args); + va_end(args); +} + +void debug(const char *format, ...) { + va_list args; + va_start(args, format); + doLog(DEBUG, format, args); + va_end(args); +} + +void doLog(const LogLevel level, const char *format, const va_list args) { if (level > logLevel) { return; } @@ -34,38 +77,3 @@ void log(const LogLevel level, const char *format, const va_list args) { yield(); } - -void log(const LogLevel level, const char *format, ...) { - va_list args; - va_start(args, format); - log(level, format, args); - va_end(args); -} - -void error(const char *format, ...) { - va_list args; - va_start(args, format); - log(ERROR, format, args); - va_end(args); -} - -void warn(const char *format, ...) { - va_list args; - va_start(args, format); - log(WARN, format, args); - va_end(args); -} - -void info(const char *format, ...) { - va_list args; - va_start(args, format); - log(INFO, format, args); - va_end(args); -} - -void debug(const char *format, ...) { - va_list args; - va_start(args, format); - log(DEBUG, format, args); - va_end(args); -} diff --git a/src/log.h b/src/core/log.h similarity index 94% rename from src/log.h rename to src/core/log.h index f088acc..eab560e 100644 --- a/src/log.h +++ b/src/core/log.h @@ -8,7 +8,7 @@ enum LogLevel { DEBUG = 3 }; -void log(LogLevel level, const char *format, ...); +void logSetup(); void error(const char *format, ...); @@ -18,4 +18,6 @@ void info(const char *format, ...); void debug(const char *format, ...); +void log(LogLevel level, const char *format, ...); + #endif diff --git a/src/wifi.cpp b/src/core/wifi.cpp similarity index 100% rename from src/wifi.cpp rename to src/core/wifi.cpp diff --git a/src/wifi.h b/src/core/wifi.h similarity index 100% rename from src/wifi.h rename to src/core/wifi.h diff --git a/src/display/Display.h b/src/display/Display.h index 2bca767..28a85bf 100644 --- a/src/display/Display.h +++ b/src/display/Display.h @@ -3,6 +3,8 @@ // #include +#include "../core/log.h" + #include "Color.h" #include "font.h" @@ -29,16 +31,6 @@ class Display { public: Display() /* : leds(PIXEL_COUNT, GPIO_NUM_13) */ { - Serial.printf("%20s = %d\n", "PIXELS_PER_SEGMENT", PIXELS_PER_SEGMENT); - Serial.printf("%20s = %d\n", "PIXELS_PER_DOT", PIXELS_PER_DOT); - Serial.printf("%20s = %d\n", "SEGMENTS_PER_DIGIT", SEGMENTS_PER_DIGIT); - Serial.printf("%20s = %d\n", "DOTS_PER_DIGIT", DOTS_PER_DIGIT); - Serial.printf("%20s = %d\n", "DIGITS", DIGITS); - Serial.printf("%20s = %d\n", "PIXELS_PER_DIGIT_SEGMENTS", PIXELS_PER_DIGIT_SEGMENTS); - Serial.printf("%20s = %d\n", "PIXELS_PER_DIGIT_DOTS", PIXELS_PER_DIGIT_DOTS); - Serial.printf("%20s = %d\n", "PIXELS_PER_DIGIT_AND_DOTS", PIXELS_PER_DIGIT_AND_DOTS); - Serial.printf("%20s = %d\n", "PIXEL_COUNT", PIXEL_COUNT); - Serial.printf("%20s = %d\n", "PIXEL_BYTE_COUNT", PIXEL_BYTE_COUNT); // leds.begin(); setBrightness(6); clear(); diff --git a/src/display/font.cpp b/src/display/font.cpp index 3ded170..1e6ed1c 100644 --- a/src/display/font.cpp +++ b/src/display/font.cpp @@ -1,6 +1,7 @@ #include "font.h" #include +#include "../core/log.h" SYMBOL SYMBOLS[][SYMBOL_SIZE] = { {X,X,X,X,X,X,_}, // 0 @@ -33,7 +34,7 @@ SYMBOL SYMBOLS[][SYMBOL_SIZE] = { {_,_,_,_,_,X,X}, // R {X,X,_,X,X,_,X}, // S {X,_,_,_,X,X,X}, // T - {_,_,_,X,X,X,_}, // U + {X,_,X,X,X,X,_}, // U {X,_,X,_,X,_,_}, // V {X,_,X,_,X,_,X}, // W {_,_,_,X,_,X,_}, // X @@ -61,7 +62,7 @@ SYMBOL *getSymbol(const char character) { case '^': return SYMBOLS[38]; case ' ': return SYMBOLS[39]; default: { - Serial.printf("[ERROR] NO SYMBOL MAPPING FOR CHARACTER \"%c\" = #%d\n", character, character); + error("[ERROR] NO SYMBOL MAPPING FOR CHARACTER \"%c\" = #%d\n", character, character); return SYMBOLS[SYMBOL_SIZE - 1]; } } diff --git a/src/http.cpp b/src/http.cpp deleted file mode 100644 index eaaef69..0000000 --- a/src/http.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "http.h" - -#include - -#include "INDEX_HTML.h" -#include "log.h" - -AsyncWebServer server(80); - -AsyncWebSocket ws("/ws"); - -void httpIndex(AsyncWebServerRequest *request) { - request->send(200, "text/html", INDEX_HTML); -} - -void httpSetup() { - ws.onEvent([](AsyncWebSocket *socket, AsyncWebSocketClient *client, AwsEventType type, void *arg, unsigned char *message, unsigned length) { - const char *t; - switch (type) { - case WS_EVT_CONNECT: - t = "CONNECT"; - break; - case WS_EVT_DISCONNECT: - t = "DISCONNECT"; - break; - case WS_EVT_PONG: - t = "PONG"; - break; - case WS_EVT_ERROR: - t = "ERROR"; - break; - case WS_EVT_DATA: - t = "DATA"; - break; - default: - t = "[???]"; - break; - } - debug("%s: %s (%d bytes)", client->remoteIP().toString().c_str(), t, length); - }); - server.addHandler(&ws); - - server.on("/", HTTP_GET, httpIndex); - server.begin(); -} - -void httpLoop() { - ws.cleanupClients(); -} - -void httpPublish(char *payload) { - ws.textAll(payload); -} diff --git a/src/main.cpp b/src/main.cpp index 93741b2..37eb2b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,13 @@ -#include +#include +#include "core/boot.h" +#include "core/filesystem.h" +#include "core/http.h" +#include "core/wifi.h" -#include "boot.h" -#include "filesystem.h" -#include "http.h" -#include "wifi.h" #include "app/AppMatch.h" void setup() { - delay(500); - Serial.begin(115200); - Serial.print("Startup\n"); + logSetup(); bootDelay(); filesystemMount(); httpSetup(); @@ -18,6 +16,5 @@ void setup() { void loop() { wifiLoop(); - httpLoop(); appLoop(); }