From 80b83705acb91d2deec82da9827f0a1563597d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Thu, 23 Jan 2025 14:24:29 +0100 Subject: [PATCH] using Patrix library now --- platformio.ini | 18 +- src/BASICS.cpp | 13 -- src/BASICS.h | 24 --- src/Node.h | 36 ++++ src/{display => }/Vector.h | 2 +- src/config.cpp | 105 ------------ src/config.h | 25 --- src/display.cpp | 17 -- src/display.h | 10 -- src/display/Color.cpp | 29 ---- src/display/Color.h | 36 ---- src/display/Display.cpp | 180 -------------------- src/display/Display.h | 329 ------------------------------------- src/main.cpp | 37 ++--- src/mode.cpp | 142 ---------------- src/mode.h | 16 -- src/mqtt.cpp | 141 ---------------- src/mqtt.h | 16 -- src/serial.cpp | 52 ------ src/serial.h | 8 - src/server.cpp | 315 ----------------------------------- src/server.h | 8 - src/wifi.cpp | 104 ------------ src/wifi.h | 10 -- 24 files changed, 54 insertions(+), 1619 deletions(-) delete mode 100644 src/BASICS.cpp delete mode 100644 src/BASICS.h create mode 100644 src/Node.h rename src/{display => }/Vector.h (97%) delete mode 100644 src/config.cpp delete mode 100644 src/config.h delete mode 100644 src/display.cpp delete mode 100644 src/display.h delete mode 100644 src/display/Color.cpp delete mode 100644 src/display/Color.h delete mode 100644 src/display/Display.cpp delete mode 100644 src/display/Display.h delete mode 100644 src/mode.cpp delete mode 100644 src/mode.h delete mode 100644 src/mqtt.cpp delete mode 100644 src/mqtt.h delete mode 100644 src/serial.cpp delete mode 100644 src/serial.h delete mode 100644 src/server.cpp delete mode 100644 src/server.h delete mode 100644 src/wifi.cpp delete mode 100644 src/wifi.h diff --git a/platformio.ini b/platformio.ini index 177cdf7..87bab0f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,20 +1,10 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - [basic] platform = espressif32 board = esp32dev framework = arduino -lib_deps = https://github.com/adafruit/Adafruit_NeoPixel - https://github.com/knolleary/pubsubclient -build_flags = +board_build.filesystem = littlefs +lib_deps = ../Patrix +build_flags = -DWIFI_SSID=\"HappyNet\" -DWIFI_PKEY=\"1Grausame!Sackratte7\" -DWIFI_HOST=\"RGBMatrixDisplay\" monitor_port = /dev/ttyUSB0 monitor_speed = 115200 monitor_filters = esp32_exception_decoder @@ -23,6 +13,7 @@ monitor_filters = esp32_exception_decoder platform = ${basic.platform} board = ${basic.board} framework = ${basic.framework} +board_build.filesystem = ${basic.board_build.filesystem} lib_deps = ${basic.lib_deps} build_flags = ${basic.build_flags} monitor_port = ${basic.monitor_port} @@ -35,6 +26,7 @@ upload_speed = 921600 platform = ${basic.platform} board = ${basic.board} framework = ${basic.framework} +board_build.filesystem = ${basic.board_build.filesystem} lib_deps = ${basic.lib_deps} build_flags = ${basic.build_flags} monitor_port = ${basic.monitor_port} diff --git a/src/BASICS.cpp b/src/BASICS.cpp deleted file mode 100644 index 13e084f..0000000 --- a/src/BASICS.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "BASICS.h" - -double doStep(double valueCurrent, double valueMin, double valueMax, long long millisecondsTotal, microseconds_t microsecondsDelta) { - double valueRange = valueMax - valueMin; - double timeRatio = (double) microsecondsDelta / ((double) millisecondsTotal * 1000.0); - double valueStep = valueRange * timeRatio; - double valueNew = max(valueMin, min(valueMax, valueCurrent + valueStep)); - return valueNew; -} - -bool randomBool(int uncertainty) { - return random(uncertainty) == 0; -} diff --git a/src/BASICS.h b/src/BASICS.h deleted file mode 100644 index 5dc2432..0000000 --- a/src/BASICS.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BASICS_H -#define BASICS_H - -#include - -#define X true -#define _ false - -#define ____ 0 -#define QUAR 64 -#define HALF 128 -#define FULL 255 - -#define countof(x) (sizeof(x) / sizeof(x[0])) - -typedef int64_t microseconds_t; - -typedef unsigned long milliseconds_t; - -double doStep(double valueCurrent, double valueMin, double valueMax, microseconds_t millisecondsTotal, microseconds_t microsecondsDelta); - -bool randomBool(int uncertainty); - -#endif diff --git a/src/Node.h b/src/Node.h new file mode 100644 index 0000000..7318586 --- /dev/null +++ b/src/Node.h @@ -0,0 +1,36 @@ +#ifndef NODE_H +#define NODE_H + +#include +#include +#include + +Config config("/test.json"); + +DisplayMatrix<32, 8> display(27); + +class Node final : public PatrixNode { + +public: + + explicit Node() : PatrixNode(true, true, true) { + // + } + + void setup() override { + config.read(); + display.setup(); + display.setBrightness(6); + display.clear(); + display.foreground = Blue; + display.printf("Test"); + } + + void loop() override { + config.loop(); + display.loop(); + } + +}; + +#endif diff --git a/src/display/Vector.h b/src/Vector.h similarity index 97% rename from src/display/Vector.h rename to src/Vector.h index 2477c04..d4c81df 100644 --- a/src/display/Vector.h +++ b/src/Vector.h @@ -1,7 +1,7 @@ #ifndef POSITION_H #define POSITION_H -#include "BASICS.h" +#include class Vector { diff --git a/src/config.cpp b/src/config.cpp deleted file mode 100644 index 9df3ae3..0000000 --- a/src/config.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include "config.h" -#include "display.h" - -#define WRITE_DELAY_MS (30 * 1000) - -uint32_t calculateChecksum(Config *ptr); - -void config_defaults(); - -bool validateChecksum(uint32_t checksumEEPROM, Config &tmp); - -Config config; - -bool dirty = false; - -bool notify = false; - -milliseconds_t lastDirtyMillis = 0; - -void config_setup() { - if (!config_load()) { - config_defaults(); - } -} - -void config_set_dirty() { - dirty = true; - lastDirtyMillis = millis(); -} - -void config_loop() { - if (notify && millis() - lastDirtyMillis > WRITE_DELAY_MS + 2000) { - notify = false; - } - if (notify) { - bool blink = ((millis() - lastDirtyMillis) / 100) % 2 == 0; - display.set(0, 0, blink ? MAGENTA : BLACK); - } - - if (!dirty) { - return; - } - if (millis() - lastDirtyMillis <= 30000) { - return; - } - - dirty = false; - notify = true; - - uint32_t checksum = calculateChecksum(&config); - - EEPROM.begin(512); - EEPROM.writeBytes(0, &config, sizeof(Config)); - EEPROM.writeUInt(sizeof(Config), checksum); - EEPROM.end(); - - Serial.printf("Config saved to EEPROM.\n"); -} - -void configSaveNowIfDirty() { - if (dirty) { - lastDirtyMillis = millis() - 30000; - } -} - -bool config_load() { - Config tmp{}; - - EEPROM.begin(512); - EEPROM.readBytes(0, &tmp, sizeof(Config)); - uint32_t checksum = EEPROM.readUInt(sizeof(Config)); - EEPROM.end(); - - bool success = validateChecksum(checksum, tmp); - if (success) { - memcpy(&config, &tmp, sizeof(Config)); - Serial.printf("Config loaded from EEPROM.\n"); - } else { - Serial.printf("Failed to load config from EEPROM.\n"); - } - - return success; -} - -bool validateChecksum(uint32_t checksumEEPROM, Config &tmp) { - uint32_t calculated = calculateChecksum(&tmp); - return checksumEEPROM == calculated; -} - -void config_defaults() { - config.mode = COUNT_DOWN_SLEEP; - config.speed = 1.0; - config.brightness = 16; - config.date = {0}; - Serial.printf("Config DEFAULTS loaded.\n"); -} - -uint32_t calculateChecksum(Config *ptr) { - uint32_t checksum = 0; - for (auto *b = (uint8_t *) ptr; b < (uint8_t *) ptr + sizeof(Config); b++) { - checksum += *b; - } - return checksum; -} diff --git a/src/config.h b/src/config.h deleted file mode 100644 index 34d4bbc..0000000 --- a/src/config.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef RGBMATRIXDISPLAY_CONFIG_H -#define RGBMATRIXDISPLAY_CONFIG_H - -#include "mode/Mode.h" - -struct Config { - ModeId mode; - double speed; - uint8_t brightness; - tm date; -}; - -extern Config config; - -void config_setup(); - -void config_loop(); - -void configSaveNowIfDirty(); - -bool config_load(); - -void config_set_dirty(); - -#endif diff --git a/src/display.cpp b/src/display.cpp deleted file mode 100644 index 96c1237..0000000 --- a/src/display.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "display.h" -#include "config.h" - -Display display(32, 8); - -void setBrightness(int brightness) { - brightness = max(1, min(brightness, 255)); - if (display.getBrightness() == brightness) { - return; - } - - config.brightness = brightness; - display.setBrightness(brightness); - config_set_dirty(); - - Serial.printf("Setting brightness to %5.1f%%\n", brightness / 2.55); -} diff --git a/src/display.h b/src/display.h deleted file mode 100644 index 0817378..0000000 --- a/src/display.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef RGBMATRIXDISPLAY_DISPLAY_H -#define RGBMATRIXDISPLAY_DISPLAY_H - -#include "display/Display.h" - -extern Display display; - -void setBrightness(int brightness); - -#endif diff --git a/src/display/Color.cpp b/src/display/Color.cpp deleted file mode 100644 index b7b473a..0000000 --- a/src/display/Color.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "Color.h" - -const Color BLACK = {____, ____, ____}; - -const Color WHITE = {FULL, FULL, FULL}; - -const Color RED = {FULL, ____, ____}; - -const Color GREEN = {____, FULL, ____}; - -const Color ORANGE = {FULL, QUAR, ____}; - -const Color BLUE = {____, ____, FULL}; - -const Color YELLOW = {FULL, FULL, ____}; - -const Color MAGENTA = {FULL, ____, FULL}; - -const Color VIOLET = {HALF, ____, FULL}; - -const Color TURQUOISE = {____, FULL, FULL}; - -Color gray(uint8_t brightness) { - return {brightness, brightness, brightness}; -} - -Color randomColor() { - return {(uint8_t) random(255), (uint8_t) random(255), (uint8_t) random(255)}; -} diff --git a/src/display/Color.h b/src/display/Color.h deleted file mode 100644 index 280fe8b..0000000 --- a/src/display/Color.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef PIXEL_H -#define PIXEL_H - -#include "BASICS.h" - -struct Color { - uint8_t r; - uint8_t g; - uint8_t b; -}; - -Color gray(uint8_t brightness); - -Color randomColor(); - -extern const Color BLACK; - -extern const Color WHITE; - -extern const Color RED; - -extern const Color GREEN; - -extern const Color ORANGE; - -extern const Color BLUE; - -extern const Color YELLOW; - -extern const Color MAGENTA; - -extern const Color VIOLET; - -extern const Color TURQUOISE; - -#endif diff --git a/src/display/Display.cpp b/src/display/Display.cpp deleted file mode 100644 index d8eb390..0000000 --- a/src/display/Display.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "Display.h" - -bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT] = { - { - X, X, X, - X, _, X, - X, _, X, - X, _, X, - X, X, X, - }, - { - _, _, X, - _, X, X, - X, _, X, - _, _, X, - _, _, X, - }, - { - X, X, X, - _, _, X, - X, X, X, - X, _, _, - X, X, X, - }, - { - X, X, X, - _, _, X, - _, X, X, - _, _, X, - X, X, X, - }, - { - X, _, X, - X, _, X, - X, X, X, - _, _, X, - _, _, X, - }, - { - X, X, X, - X, _, _, - X, X, X, - _, _, X, - X, X, X, - }, - { - X, X, X, - X, _, _, - X, X, X, - X, _, X, - X, X, X, - }, - { - X, X, X, - _, _, X, - _, X, _, - X, _, _, - X, _, _, - }, - { - X, X, X, - X, _, X, - X, X, X, - X, _, X, - X, X, X, - }, - { - X, X, X, - X, _, X, - X, X, X, - _, _, X, - X, X, X, - }, - { - _, _, _, - _, X, _, - _, _, _, - _, X, _, - _, _, _, - }, - { - _, _, X, - _, _, X, - _, _, X, - X, _, X, - _, X, _, - }, - { - X, _, X, - X, X, X, - _, X, _, - X, X, X, - X, _, X, - }, - { - _, _, _, - _, _, _, - X, X, X, - _, _, _, - _, _, _, - }, - { - X, _, _, - _, _, X, - _, X, _, - X, _, _, - _, _, X, - }, - { - X, X, X, - _, X, _, - _, X, _, - _, X, _, - _, X, _, - }, - { - _, X, _, - X, _, X, - X, X, X, - X, _, X, - X, _, X, - }, - { - _, X, X, - X, _, _, - X, X, X, - X, _, X, - _, X, _, - }, - { - X, X, X, - X, _, _, - X, X, X, - X, _, _, - X, X, X, - }, - { - X, _, X, - X, _, X, - X, X, X, - X, _, X, - X, _, X, - }, - { - X, X, _, - X, _, X, - X, X, _, - X, X, _, - X, _, X, - }, - { - X, _, _, - X, _, _, - X, _, _, - X, _, _, - X, _, _, - }, - { - X, _, _, - X, _, _, - X, _, _, - X, _, _, - X, X, X, - }, - { - _, _, _, - _, _, _, - _, _, _, - _, _, _, - _, _, _, - }, - // this must always be the last symbol (fallback) - { - X, X, X, - X, X, X, - X, X, X, - X, X, X, - X, X, X, - }, -}; diff --git a/src/display/Display.h b/src/display/Display.h deleted file mode 100644 index f68cc2d..0000000 --- a/src/display/Display.h +++ /dev/null @@ -1,329 +0,0 @@ -#ifndef DISPLAY_H -#define DISPLAY_H - -#include "Color.h" -#include "Adafruit_NeoPixel.h" -#include "Vector.h" - -#define SYMBOL_COUNT 26 - -#define SYMBOL_J 11 -#define SYMBOL_X 12 -#define SYMBOL_DASH 13 -#define SYMBOL_PERCENT 14 -#define SYMBOL_T 15 -#define SYMBOL_A 16 -#define SYMBOL_G 17 -#define SYMBOL_E 18 -#define SYMBOL_H 19 -#define SYMBOL_R 20 -#define SYMBOL_I 21 -#define SYMBOL_L 22 -#define SYMBOL_SPACE 23 - -#define DISPLAY_CHAR_WIDTH 3 -#define DISPLAY_CHAR_HEIGHT 5 - -extern bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT]; - -class Display { - -public: - - const uint8_t width; - - const uint8_t height; - - const size_t pixelCount; - - const size_t pixelByteCount; - - bool fpsShow = false; - -private: - - Adafruit_NeoPixel leds; - - milliseconds_t fpsLastMillis = 0; - - int fps = 0; - - Color *buffer = nullptr; - - uint8_t brightness = 10; - -public: - - Display(uint8_t width, uint8_t height) : width(width), height(height), - pixelCount(width * height), - pixelByteCount(pixelCount * sizeof(Color)), - leds(pixelCount, GPIO_NUM_13) { - buffer = (Color *) malloc(pixelByteCount); - if (buffer == nullptr) { - Serial.print("+-----------------------------------------------+\n"); - Serial.print("| OUT OF MEMORY: Cannot allocate double-buffer! |\n"); - Serial.print("+-----------------------------------------------+\n"); - } - } - - ~Display() { - if (buffer == nullptr) { - return; - } - free(buffer); - buffer = nullptr; - } - - void setup() { - leds.begin(); - clear(); - flush(); - } - - void loop() { - calculateFPS(); - drawFpsBorder(); - if (isDirty()) { - flush(); - } - } - - void setBrightness(uint8_t value) { - brightness = value; - } - - uint8_t getBrightness() const { - return brightness; - } - - void clear() { - if (buffer == nullptr) { - return; - } - memset(buffer, 0, pixelByteCount); - } - - enum ALIGN { - LEFT, RIGHT - }; - - uint8_t print2(int x, int y, double valueDbl, Color colorPositive, Color colorZero, Color colorNegative, ALIGN align = RIGHT) { - const Color color = valueDbl == 0 ? colorZero : (valueDbl < 0 ? colorNegative : colorPositive); - return print2(x, y, valueDbl, color, align); - } - - uint8_t print2(int x, int y, double valueDbl, Color color, ALIGN align = RIGHT) { - if (isnan(valueDbl)) { - x -= 3 * (DISPLAY_CHAR_WIDTH + 1) - 1; - x += print(x, y, SYMBOL_DASH, color, true) + 1; - x += print(x, y, SYMBOL_DASH, color, true) + 1; - x += print(x, y, SYMBOL_DASH, color, true) + 1; - return x; - } - - const int value = (int) round(abs(valueDbl)); - const bool negative = valueDbl < 0; - - const int digitCount = (int) max(1.0, floor(log10(value)) + 1); // log10 is -inf for value==0, hence the max(1.0, ...) - if (align == RIGHT) { - x -= ((negative ? 1 : 0) + digitCount) * (DISPLAY_CHAR_WIDTH + 1) - 1; - } - - int divider = (int) pow(10, digitCount - 1); - if (negative) { - x += print(x, y, SYMBOL_DASH, color, true) + 1; - } - - bool showIfZero = false; - // Serial.printf("x=%d, y=%d, value=%d, align=%s, digitCount=%d, divider=%d\n", x, y, value, align == LEFT ? "LEFT" : "RIGHT", digitCount, divider); - for (int digitPos = 0; digitPos < digitCount; ++digitPos) { - const int digitVal = value / divider % 10; - showIfZero |= digitVal != 0 || (digitPos == digitCount - 1); - x += print(x, y, digitVal, color, showIfZero) + 1; - // Serial.printf(" digitPos=%d, x=%d, y=%d, digitVal=%d, showIfZero=%s, divider=%d\n", digitPos, x, y, digitVal, showIfZero ? "true" : "false", divider); - divider /= 10; - } - // Serial.println(); - - return x; - } - - uint8_t print(uint8_t xPos, uint8_t yPos, uint8_t index, Color color, bool showIfZero) { - if (index == 0 && !showIfZero) { - return DISPLAY_CHAR_WIDTH; - } - if (index >= SYMBOL_COUNT) { - Serial.printf("Cannot print2 symbol #%u.\n", index); - index = SYMBOL_COUNT - 1; - } - bool *symbolBit = SYMBOLS[index]; - for (uint8_t y = 0; y < DISPLAY_CHAR_HEIGHT; ++y) { - for (uint8_t x = 0; x < DISPLAY_CHAR_WIDTH; ++x) { - if (*(symbolBit++)) { - set(xPos + x, yPos + y, color); - } else { - set(xPos + x, yPos + y, BLACK); - } - } - } - return DISPLAY_CHAR_WIDTH; - } - - // TODO REMOVE QUICK & DIRTY - uint8_t printM(uint8_t xPos, uint8_t yPos, Color color) { - bool sym[5][5] = { - {X,_,_,_,X}, - {X,X,_,X,X}, - {X,_,X,_,X}, - {X,_,_,_,X}, - {X,_,_,_,X}, - }; - for (int y = 0; y < countof(sym); ++y) { - for (int x = 0; x < countof(sym[0]); ++x) { - if (sym[y][x]) { - set(xPos + x, yPos + y, color); - } else { - set(xPos + x, yPos + y, BLACK); - } - } - } - return countof(sym[0]); - } - - static bool doCreeperBlink() { - const auto now = millis(); - static auto blink = false; - static auto last = now; - if (!blink) { - if (now - last >= 3000) { - last = now; - if (random(3) == 0) { - blink = true; - } - } - } else { - if (now - last >= 500) { - last = now; - blink = false; - } - } - return blink; - } - - // TODO REMOVE QUICK & DIRTY - uint8_t printCreeper(uint8_t xPos, uint8_t yPos) { - const auto creeperBlink = doCreeperBlink(); - bool sym[8][8] = { - {X, X, X, X, X, X, X, X}, - {X, X, X, X, X, X, X, X}, - {X, _, _, X, X, _, _, X}, - {X, _, _, X, X, _, _, X}, - {X, X, X, _, _, X, X, X}, - {X, X, _, _, _, _, X, X}, - {X, X, _, _, _, _, X, X}, - {X, X, _, X, X, _, X, X}, - }; - for (int y = 0; y < countof(sym); ++y) { - for (int x = 0; x < countof(sym[0]); ++x) { - if (creeperBlink && ((x == 1 || x == 2) && y == 2)) { - set(xPos + x, yPos + y, GREEN); - } else { - set(xPos + x, yPos + y, sym[y][x] ? GREEN : BLACK); - } - } - } - return countof(sym[0]); - } - - // TODO REMOVE QUICK & DIRTY - uint8_t printI(uint8_t xPos, uint8_t yPos, Color color) { - for (int y = 0; y < 5; ++y) { - set(xPos, yPos + y, color); - } - return 1; - } - - void set(Vector pos, Color color) { - set((uint8_t) round(pos.x), (uint8_t) round(pos.y), color); - } - - void set(uint8_t x, uint8_t y, Color color) { - if (x >= width || y >= height) { - return; - } - if ((y % 2) != 0) { - x = width - x - 1; - } - set(y * width + x, color); - } - - void set(uint16_t index, Color color) { - if (buffer == nullptr) { - return; - } - buffer[index] = { - // yes, correct order is GRB !!! - (uint8_t) (color.g * brightness >> 8), - (uint8_t) (color.r * brightness >> 8), - (uint8_t) (color.b * brightness >> 8) - }; - } - -private: - - void flush() { - if (buffer == nullptr) { - return; - } - memcpy(leds.getPixels(), buffer, pixelByteCount); - leds.show(); - } - - bool isDirty() const { - if (buffer == nullptr) { - return false; - } - return memcmp(leds.getPixels(), buffer, pixelByteCount) != 0; - } - - void calculateFPS() { - fps = (int) round(1000.0 / (millis() - fpsLastMillis)); - fpsLastMillis = millis(); - } - - void drawFpsBorder() { - if (!fpsShow) { - return; - } - - int frames = fps; - - Color color = RED; - if (frames > 3 * 76) { - frames -= 3 * 76; - color = WHITE; - } else if (frames > 2 * 76) { - frames -= 2 * 76; - color = BLUE; - } else if (frames > 76) { - frames -= 76; - color = GREEN; - } - - for (int x = 0; x <= width - 1 && frames-- > 0; x++) { - set(x, 0, color); - } - for (int y = 0; y <= height - 1 && frames-- > 0; y++) { - set(width - 1, y, color); - } - for (int x = width - 1; x >= 0 && frames-- > 0; x--) { - set(x, height - 1, color); - } - for (int y = height - 1; y >= 0 && frames-- > 0; y--) { - set(0, y, color); - } - } - -}; - -#endif diff --git a/src/main.cpp b/src/main.cpp index 6ae0c79..546ce7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,32 +1,19 @@ -#include "serial.h" -#include "config.h" -#include "wifi.h" +#include "Node.h" -#include "server.h" +// ReSharper disable once CppUnusedIncludeDirective +#include -#include "mode.h" -#include "display.h" -#include "mqtt.h" +// ReSharper disable once CppUnusedIncludeDirective +#include -void setup() { - delay(500); +// ReSharper disable once CppUnusedIncludeDirective +#include - serial_setup(); - config_setup(); - wifi_setup(); +// ReSharper disable once CppUnusedIncludeDirective +#include - server_setup(); +auto node = Node(); - display.setup(); - display.setBrightness(config.brightness); -} - -void loop() { - serial_loop(); - wifi_loop(); - mqtt_loop(); - server_loop(); - mode_loop(); - config_loop(); - display.loop(); +PatrixNode &patrixGetNode() { + return node; } diff --git a/src/mode.cpp b/src/mode.cpp deleted file mode 100644 index 0159156..0000000 --- a/src/mode.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "mode.h" -#include "config.h" -#include "mode/Border/Border.h" -#include "mode/Clock/Clock.h" -#include "mode/GameOfLife/GameOfLife.h" -#include "mode/Pong/Pong.h" -#include "mode/SpaceInvaders/SpaceInvaders.h" -#include "mode/CountDown/CountDown.h" -#include "mode/Starfield/Starfield.h" -#include "mode/Matrix/Matrix.h" -#include "display.h" -#include "mode/Power/Power.h" -#include "mode/Energy/Energy.h" -#include "mode/Timer/Timer.h" - -ModeId currentModeId = NONE; - -microseconds_t lastMicros = 0; - -Mode *mode = nullptr; - -void unloadOldMode(); - -void loadNewMode(); - -void mode_step(); - -void mode_loop() { - if (currentModeId != config.mode) { - unloadOldMode(); - loadNewMode(); - } - mode_step(); -} - -void setMode(ModeId value) { - if (config.mode == value) { - return; - } - config.mode = value; - config_set_dirty(); -} - -void modeMove(int index, int x, int y) { - if (mode != nullptr) { - mode->move(index, x, y); - } -} - -void modeFire(int index) { - if (mode != nullptr) { - mode->fire(index); - } -} - -void setSpeed(double speed) { - speed = min(max(0.01, speed), 10000.0); - if (config.speed == speed) { - return; - } - config.speed = speed; - config_set_dirty(); - Serial.printf("Setting speed to %6.2fx\n", config.speed); -} - -void unloadOldMode() { - if (mode != nullptr) { - delete mode; - mode = nullptr; - } - display.clear(); -} - -void loadNewMode() { - currentModeId = config.mode; - lastMicros = 0; - switch (currentModeId) { - case BORDER: - mode = new Border(display); - break; - case CLOCK: - mode = new Clock(display); - break; - case GAME_OF_LIFE_BLACK_WHITE: - mode = new GameOfLife(display, BLACK_WHITE); - break; - case GAME_OF_LIFE_GRAYSCALE: - mode = new GameOfLife(display, GRAYSCALE); - break; - case GAME_OF_LIFE_COLOR_FADE: - mode = new GameOfLife(display, COLOR_FADE); - break; - case GAME_OF_LIFE_RANDOM_COLOR: - mode = new GameOfLife(display, RANDOM_COLOR); - break; - case PONG: - mode = new Pong(display); - break; - case SPACE_INVADERS: - mode = new SpaceInvaders(display); - break; - case COUNT_DOWN: - mode = new CountDown(display, false, false); - break; - case COUNT_DOWN_BARS: - mode = new CountDown(display, true, false); - break; - case COUNT_DOWN_SLEEP: - mode = new CountDown(display, false, true); - break; - case STARFIELD: - mode = new Starfield(display); - break; - case MATRIX: - mode = new Matrix(display); - break; - case POWER: - mode = new Power(display); - break; - case ENERGY: - mode = new Energy(display); - break; - case TIMER: - mode = new Timer2(display); - break; - default: - Serial.print("No mode loaded.\n"); - display.clear(); - break; - } - Serial.printf("Mode: %s\n", mode == nullptr ? "None" : mode->getName()); -} - -void mode_step() { - if (mode == nullptr) { - return; - } - auto currentMicros = (int64_t) micros(); - microseconds_t microseconds = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * config.speed)); - lastMicros = currentMicros; - mode->loop(microseconds); -} diff --git a/src/mode.h b/src/mode.h deleted file mode 100644 index e483e32..0000000 --- a/src/mode.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef RGBMATRIXDISPLAY_MODE_H -#define RGBMATRIXDISPLAY_MODE_H - -#include "mode/Mode.h" - -void mode_loop(); - -void setMode(ModeId value); - -void setSpeed(double speed); - -void modeMove(int index, int x, int y); - -void modeFire(int index); - -#endif diff --git a/src/mqtt.cpp b/src/mqtt.cpp deleted file mode 100644 index 3a0d43f..0000000 --- a/src/mqtt.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include -#include "mqtt.h" -#include "PubSubClient.h" -#include "wifi.h" - -#define MQTT_CONNECT_TIMEOUT_MILLISECONDS 5000 - -#define MQTT_MAX_MESSAGE_AGE_MILLIS 11000 - -#define PHOTOVOLTAIC_POWER_W "openDTU/pv/ac/power" -#define PHOTOVOLTAIC_ENERGY_KWH "openDTU/pv/ac/yieldtotal" -#define GRID_POWER_W "electricity/grid/power/signed/w" -#define GRID_IMPORT_WH "electricity/grid/energy/import/wh" -#define GRID_EXPORT_WH "electricity/grid/energy/export/wh" - -WiFiClient espClient; - -PubSubClient mqtt(espClient); - -bool mqttConnected = false; - -unsigned long mqttLastConnectTry = 0; - -double photovoltaicPowerW = NAN; - -unsigned long photovoltaicPowerWLast = 0; - -double photovoltaicEnergyKWh = NAN; - -unsigned long photovoltaicEnergyKWhLast = 0; - -double gridPowerW = NAN; - -unsigned long gridPowerWLast = 0; - -double gridImportKWh = NAN; - -unsigned long gridImportKWhLast = 0; - -double gridExportKWh = NAN; - -unsigned long gridExportKWhLast = 0; - -void mqttDisconnect(); - -void mqttCallback(char *topic, uint8_t *payload, unsigned int length) { - char message[128]; - if (length > sizeof message - 1) { - Serial.printf("MQTT: received too long message: topic=%s, length=%d", topic, length); - return; - } - memcpy(message, payload, length); - message[length] = 0; - if (strcmp(PHOTOVOLTAIC_POWER_W, topic) == 0) { - photovoltaicPowerW = strtod(message, nullptr); - photovoltaicPowerWLast = millis(); - } else if (strcmp(PHOTOVOLTAIC_ENERGY_KWH, topic) == 0) { - photovoltaicEnergyKWh = strtod(message, nullptr); - photovoltaicEnergyKWhLast = millis(); - } else if (strcmp(GRID_POWER_W, topic) == 0) { - gridPowerW = strtod(message, nullptr); - gridPowerWLast = millis(); - } else if (strcmp(GRID_IMPORT_WH, topic) == 0) { - gridImportKWh = strtod(message, nullptr) / 1000; - gridImportKWhLast = millis(); - } else if (strcmp(GRID_EXPORT_WH, topic) == 0) { - gridExportKWh = strtod(message, nullptr) / 1000; - gridExportKWhLast = millis(); - } -} - -void mqtt_loop() { - if (!wifiIsConnected()) { - mqttDisconnect(); - return; - } - if (!mqtt.loop() && (mqttLastConnectTry == 0 || millis() - mqttLastConnectTry > MQTT_CONNECT_TIMEOUT_MILLISECONDS)) { - mqttLastConnectTry = millis(); - mqtt.setServer("10.0.0.50", 1883); - mqttConnected = mqtt.connect(WiFiClass::getHostname()); - if (mqttConnected) { - Serial.printf("Successfully connected mqtt broker at %s:%d\n", "10.0.0.50", 1883); - mqtt.setCallback(mqttCallback); - mqtt.subscribe(PHOTOVOLTAIC_POWER_W); - mqtt.subscribe(PHOTOVOLTAIC_ENERGY_KWH); - mqtt.subscribe(GRID_POWER_W); - mqtt.subscribe(GRID_IMPORT_WH); - mqtt.subscribe(GRID_EXPORT_WH); - } else { - Serial.printf("ERROR: Failed to connect MQTT broker at %s:%d\n", "10.0.0.50", 1883); - mqttDisconnect(); - } - } -} - -void mqttDisconnect() { - if (mqttConnected) { - mqtt.disconnect(); - mqttConnected = false; - photovoltaicPowerW = NAN; - photovoltaicPowerWLast = 0; - gridPowerW = NAN; - gridPowerWLast = 0; - } -} - -double getPhotovoltaicPowerW() { - if (millis() - photovoltaicPowerWLast > MQTT_MAX_MESSAGE_AGE_MILLIS) { - return NAN; - } - return photovoltaicPowerW; -} - -double getPhotovoltaicEnergyKWh() { - if (millis() - photovoltaicEnergyKWhLast > MQTT_MAX_MESSAGE_AGE_MILLIS) { - return NAN; - } - return photovoltaicEnergyKWh; -} - -double getGridPowerW() { - if (millis() - gridPowerWLast > MQTT_MAX_MESSAGE_AGE_MILLIS) { - return NAN; - } - return gridPowerW; -} - -double getGridImportKWh() { - if (millis() - gridImportKWhLast > MQTT_MAX_MESSAGE_AGE_MILLIS) { - return NAN; - } - return gridImportKWh; -} - -double getGridExportKWh() { - if (millis() - gridExportKWhLast > MQTT_MAX_MESSAGE_AGE_MILLIS) { - return NAN; - } - return gridExportKWh; -} diff --git a/src/mqtt.h b/src/mqtt.h deleted file mode 100644 index 189c25a..0000000 --- a/src/mqtt.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef SENSOR2_MQTT_H -#define SENSOR2_MQTT_H - -void mqtt_loop(); - -double getPhotovoltaicPowerW(); - -double getPhotovoltaicEnergyKWh(); - -double getGridPowerW(); - -double getGridImportKWh(); - -double getGridExportKWh(); - -#endif diff --git a/src/serial.cpp b/src/serial.cpp deleted file mode 100644 index f5ded6a..0000000 --- a/src/serial.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include "serial.h" -#include "display.h" -#include "config.h" -#include "mode.h" - -void serial_setup() { - Serial.begin(115200); - Serial.println("\n\n\nStartup!"); -} - -void serial_loop() { - if (Serial.available()) { - int input = Serial.read(); - switch (input) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - setMode((ModeId) (input - '0')); - break; - case 'a': - case 'b': - setMode((ModeId) (input - 'a' + 10)); - break; - case 'r': - setSpeed(1.0); - break; - case '+': - setBrightness(display.getBrightness() + 10); - break; - case '-': - setBrightness(display.getBrightness() - 10); - break; - case ',': - setSpeed(config.speed / 1.1); - break; - case '.': - setSpeed(config.speed * 1.1); - break; - default: - Serial.printf("Unknown command: %c\n", input); - break; - } - } -} diff --git a/src/serial.h b/src/serial.h deleted file mode 100644 index 91fb57f..0000000 --- a/src/serial.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RGBMATRIXDISPLAY_SERIAL_H -#define RGBMATRIXDISPLAY_SERIAL_H - -void serial_loop(); - -void serial_setup(); - -#endif diff --git a/src/server.cpp b/src/server.cpp deleted file mode 100644 index 66548e0..0000000 --- a/src/server.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include -#include -#include "server.h" -#include "mode/Mode.h" -#include "mode.h" -#include "display.h" -#include "config.h" - -static const char *const style = R"( - -)"; - -static const char *const script = R"( - -)"; - -WebServer server(80); - -void web_index(); - -void web_player(); - -void web_player_move(); - -void web_player_fire(); - -void web_setMode(); - -void web_brighter(); - -void web_darker(); - -void web_faster(); - -void web_slower(); - -void web_fps_on(); - -void web_fps_off(); - -void web_config_date(); - -void web_config_save(); - -void server_setup() { - server.on("/", web_index); - server.on("/player", web_player); - server.on("/player/move", web_player_move); - server.on("/player/fire", web_player_fire); - server.on("/mode", web_setMode); - server.on("/brighter", web_brighter); - server.on("/darker", web_darker); - server.on("/faster", web_faster); - server.on("/slower", web_slower); - server.on("/fps/on", web_fps_on); - server.on("/fps/off", web_fps_off); - server.on("/config/date", web_config_date); - server.on("/config/save", web_config_save); - server.begin(); -} - -void server_loop() { - server.handleClient(); -} - -void web_index() { - server.setContentLength(CONTENT_LENGTH_UNKNOWN); - server.send(200, "text/html", ""); - server.sendContent(style); - server.sendContent(script); - - server.sendContent(R"(

)"); - server.sendContent(R"(Player 0
)"); - server.sendContent(R"(Player 1
)"); - server.sendContent(R"(

)"); - - server.sendContent(R"(

)"); - server.sendContent(R"(NONE
)"); - server.sendContent(R"(BORDER
)"); - server.sendContent(R"(CLOCK
)"); - server.sendContent(R"(GAME_OF_LIFE_BLACK_WHITE
)"); - server.sendContent(R"(GAME_OF_LIFE_GRAYSCALE
)"); - server.sendContent(R"(GAME_OF_LIFE_COLOR_FADE
)"); - server.sendContent(R"(GAME_OF_LIFE_RANDOM_COLOR
)"); - server.sendContent(R"(PONG
)"); - server.sendContent(R"(SPACE_INVADERS
)"); - server.sendContent(R"(COUNT_DOWN
)"); - server.sendContent(R"(COUNT_DOWN_BARS
)"); - server.sendContent(R"(COUNT_DOWN_SLEEP
)"); - server.sendContent(R"(STARFIELD
)"); - server.sendContent(R"(MATRIX
)"); - server.sendContent(R"(POWER
)"); - server.sendContent(R"(ENERGY
)"); - server.sendContent(R"(TIMER
)"); - server.sendContent(R"(

)"); - - server.sendContent(R"(

)"); - server.sendContent(R"(Helligkeit: + / -
)"); - server.sendContent(R"(Geschwindigkeit: + / -
)"); - server.sendContent(R"(FPS: EIN / AUS
)"); - server.sendContent(R"(

)"); - - server.sendContent(R"(

)"); - server.sendContent(R"()"); - server.sendContent(R"()"); - server.sendContent(R"()"); - server.sendContent(R"()"); - server.sendContent(R"(

)"); - - server.sendContent(R"(

)"); - server.sendContent(R"()"); - server.sendContent(R"(

)"); - - server.client().flush(); -} - -void web_player() { - char buffer[128]; - - if (!server.hasArg("index")) { - server.send(400, "text/plain", "Missing 'index'"); - return; - } - double value = strtod(server.arg("index").c_str(), nullptr); - int index = (int) value; - - server.setContentLength(CONTENT_LENGTH_UNKNOWN); - server.send(200, "text/html", ""); - server.sendContent(style); - server.sendContent(script); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"()"); - - server.sendContent(R"(
)"); - snprintf(buffer, sizeof buffer, R"(
)", index); - server.sendContent(buffer); - server.sendContent(R"(
 
)"); - snprintf(buffer, sizeof buffer, R"(
)", index); - server.sendContent(buffer); - server.sendContent(R"(
)"); - snprintf(buffer, sizeof buffer, R"(
)", index); - server.sendContent(buffer); - server.sendContent(R"(
)"); - snprintf(buffer, sizeof buffer, R"(
)", index); - server.sendContent(buffer); - server.sendContent(R"(
 )"); - snprintf(buffer, sizeof buffer, R"(
)", index); - server.sendContent(buffer); - server.sendContent(R"(
 
)"); - server.client().flush(); -} - -void web_player_move() { - double value; - - if (!server.hasArg("index")) { - server.send(400, "text/plain", "Missing 'index'"); - return; - } - value = strtod(server.arg("index").c_str(), nullptr); - int index = (int) value; - - if (!server.hasArg("x")) { - server.send(400, "text/plain", "Missing 'x'"); - return; - } - value = strtod(server.arg("x").c_str(), nullptr); - int x = (int) value; - - if (!server.hasArg("y")) { - server.send(400, "text/plain", "Missing 'y'"); - return; - } - value = strtod(server.arg("y").c_str(), nullptr); - int y = (int) value; - - modeMove(index, x, y); - - server.send(200, "application/json", "true"); -} - -void web_player_fire() { - double value; - - if (!server.hasArg("index")) { - server.send(400, "text/plain", "Missing 'index'"); - return; - } - value = strtod(server.arg("index").c_str(), nullptr); - int index = (int) value; - - modeFire(index); - - server.send(200, "application/json", "true"); -} - -void web_setMode() { - if (!server.hasArg("mode")) { - server.send(400, "text/plain", "Missing 'mode'"); - return; - } - double value = strtod(server.arg("mode").c_str(), nullptr); - if (isnan(value)) { - server.send(400, "text/plain", "'mode' not a number"); - return; - } - setMode((ModeId) value); - server.send(200); -} - -void web_brighter() { - setBrightness(display.getBrightness() + 10); - server.send(200); -} - -void web_darker() { - setBrightness(display.getBrightness() - 10); - server.send(200); -} - -void web_faster() { - setSpeed(config.speed * 1.1); - server.send(200); -} - -void web_slower() { - setSpeed(config.speed / 1.1); - server.send(200); -} - -void web_fps_on() { - display.fpsShow = true; - server.send(200); -} - -void web_fps_off() { - display.fpsShow = false; - server.send(200); -} - -void web_config_save() { - configSaveNowIfDirty(); - server.send(200); -} - -void web_config_date() { - double year = strtod(server.arg("year").c_str(), nullptr); - double month = strtod(server.arg("month").c_str(), nullptr); - double day = strtod(server.arg("day").c_str(), nullptr); - if (!isnan(year)) { - config.date.tm_year = (int) year; - config.date.tm_mon = (int) month; - config.date.tm_mday = (int) day; - config.date.tm_hour = 0; - config.date.tm_min = 0; - config.date.tm_sec = 0; - server.send(200); - } - server.send(400); -} diff --git a/src/server.h b/src/server.h deleted file mode 100644 index 6ad69eb..0000000 --- a/src/server.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RGBMATRIXDISPLAY_SERVER_H -#define RGBMATRIXDISPLAY_SERVER_H - -void server_setup(); - -void server_loop(); - -#endif diff --git a/src/wifi.cpp b/src/wifi.cpp deleted file mode 100644 index bb3fff1..0000000 --- a/src/wifi.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "wifi.h" -#include "display.h" -#include "mqtt.h" - -#include -#include -#include - -bool wifiConnected = false; - -void onConnect(); - -uint32_t ip2int(const IPAddress &ip); - -void timeSyncCallback(struct timeval *tv); - -char *calculateGateway(char *calculatedGateway, size_t size); - -void wifi_setup() { - WiFiClass::setHostname("RGBMatrixDisplay"); - WiFi.begin("HappyNet", "1Grausame!Sackratte7"); - yield(); - - ArduinoOTA.onStart([]() { - Serial.print("\n\nOTA Update: "); - display.clear(); - display.loop(); - }); - ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - double ratio = (double) progress / (double) total; - Serial.printf("\rOTA Update: %3.0f%%", ratio * 100); - - auto index = (uint16_t) round(ratio * (double) display.pixelCount); - auto color = (uint8_t) round(ratio * 255.0); - display.set(index, {(uint8_t) (255 - color), color, 0}); - display.loop(); - }); - ArduinoOTA.onEnd([]() { - Serial.println("\nOTA Success!\n"); - display.clear(); - display.loop(); - }); - ArduinoOTA.onError([](int error) { - Serial.println("\nOTA Failure!\n"); - display.clear(); - display.loop(); - }); - ArduinoOTA.begin(); - yield(); -} - -void wifi_loop() { - ArduinoOTA.handle(); - bool hasIp = (uint32_t) WiFi.localIP() != 0; - if (!wifiConnected) { - if (hasIp) { - wifiConnected = true; - onConnect(); - } - } else { - if (!hasIp) { - wifiConnected = false; - Serial.println("WiFi disconnected!"); - } - } -} - -void onConnect() { - Serial.printf("WiFi connected: %s\n", WiFi.localIP().toString().c_str()); - char calculatedGateway[16] = {0}; - calculateGateway(calculatedGateway, sizeof(calculatedGateway)); - sntp_set_time_sync_notification_cb(timeSyncCallback); - Serial.printf("configTime(%s / %s / %s)\n", WiFi.gatewayIP().toString().c_str(), calculatedGateway, "pool.ntp.org"); - configTime(3600, 3600, "pool.ntp.org", WiFi.gatewayIP().toString().c_str(), calculatedGateway); - yield(); -} - -bool wifiIsConnected() { - return wifiConnected; -} - -char *calculateGateway(char *calculatedGateway, size_t size) { - uint32_t local = ip2int(WiFi.localIP()); - uint32_t netmask = ip2int(WiFi.subnetMask()); - uint32_t gateway = local & netmask + 1; - snprintf( - calculatedGateway, - size, - "%u.%u.%u.%u", - (gateway >> 24) & 0xFF, - (gateway >> 16) & 0xFF, - (gateway >> 8) & 0xFF, - (gateway >> 0) & 0xFF - ); - return calculatedGateway; -} - -uint32_t ip2int(const IPAddress &ip) { - return ((ip[0] * 256 + ip[1]) * 256 + ip[2]) * 256 + ip[3]; -} - -void timeSyncCallback(struct timeval *tv) { - Serial.printf("timeSyncCallback: %ld\n", tv->tv_sec); -} diff --git a/src/wifi.h b/src/wifi.h deleted file mode 100644 index c2bf457..0000000 --- a/src/wifi.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef RGBMATRIXDISPLAY_WIFI_H -#define RGBMATRIXDISPLAY_WIFI_H - -void wifi_setup(); - -void wifi_loop(); - -bool wifiIsConnected(); - -#endif