From 16e28dda76d106a0b868f13376ab01bfebe658c0 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Thu, 6 Aug 2026 23:27:12 +0200 Subject: [PATCH 01/39] 1 Remove WiFiManager and OTA, move config to config.h 2 3 Drop the WiFiManager captive-portal flow, its SPIFFS-persisted 4 config.json, and ArduinoOTA support to simplify the connectivity 5 path. WiFi/MQTT/strip settings are now compile-time values in a 6 gitignored include/config.h (template in config.example.h) instead 7 of being set at runtime and persisted to flash. 8 9 Also fixes a buffer-size mismatch on mqtt_ssl (was sized for "no" 10 only) now that its default comes from config.h. --- software/.gitignore | 1 + software/include/config.example.h | 21 +++ software/platformio.ini | 8 +- software/src/main.cpp | 215 ++++-------------------------- 4 files changed, 52 insertions(+), 193 deletions(-) create mode 100644 software/include/config.example.h diff --git a/software/.gitignore b/software/.gitignore index 79c96b7..7533fe0 100644 --- a/software/.gitignore +++ b/software/.gitignore @@ -4,3 +4,4 @@ .clang_complete .gcc-flags.json .vscode +include/config.h diff --git a/software/include/config.example.h b/software/include/config.example.h new file mode 100644 index 0000000..1180c69 --- /dev/null +++ b/software/include/config.example.h @@ -0,0 +1,21 @@ +// Copy this file to config.h and fill in real values. +// config.h is gitignored and must never be committed. + +#pragma once + +#include + +#define WIFI_SSID "YourNetwork" +#define WIFI_PASSWORD "YourPassword" + +#define MQTT_SERVER "" +#define MQTT_PORT "8080" +#define MQTT_USERNAME "esp" +#define MQTT_PASSWORD "supersecurepassword" +#define MQTT_SSL "no" + +// One of: RGB_STRIP, RGBW_STRIP, RGBWW_STRIP, WS2812_STRIP, APA102_STRIP +#define STRIP_TYPE RGB_STRIP + +// Number of LEDs on the strip +#define STRIP_LENGTH 60 diff --git a/software/platformio.ini b/software/platformio.ini index 7deac77..8a8bccd 100644 --- a/software/platformio.ini +++ b/software/platformio.ini @@ -16,17 +16,17 @@ framework = arduino lib_deps = # Using a library name - WifiManager PubSubClient FastLED arduinoFFT + ArduinoJson #upload_port = 192.168.178.67 #upload_protocol = espota -upload_port = /dev/ttyUSB3 -upload_speed = 921600 +upload_port = /dev/cu.usbserial-141420 +upload_speed = 115200 monitor_speed = 115200 -monitor_port = /dev/ttyUSB3 +monitor_port = /dev/cu.usbserial-141420 diff --git a/software/src/main.cpp b/software/src/main.cpp index 99f2afa..ff8bf6f 100644 --- a/software/src/main.cpp +++ b/software/src/main.cpp @@ -1,13 +1,6 @@ //--Includes-------------------------------------------------------------------- -#include #include -#include -#include #include -#include -#include -#include -#include #include #include #include @@ -16,6 +9,7 @@ #include #include #include +#include //--Includes-------------------------------------------------------------------- @@ -26,12 +20,14 @@ bool* varSiloChanged = new bool(false); const unsigned int pwmFreq = 1000; -char mqtt_server[40]; -char mqtt_port[6] = "8080"; -char strip_type[8] = "RGB"; -char mqtt_ssl[3] = "no"; -char mqtt_username[40] = "esp"; -char mqtt_password[40] = "supersecurepassword"; +char mqtt_server[40] = MQTT_SERVER; +char mqtt_port[6] = MQTT_PORT; +char mqtt_ssl[4] = MQTT_SSL; +char mqtt_username[40] = MQTT_USERNAME; +char mqtt_password[40] = MQTT_PASSWORD; + +const char* wifi_default_ssid = WIFI_SSID; +const char* wifi_default_password = WIFI_PASSWORD; char mainTopic[80] = "/ESPLED/"; char debugTopic[80]; @@ -40,16 +36,12 @@ char debugTopic[80]; const char* fingerprint = "A6 AE 85 65 63 DD D8 7C 70 F7 92 73 DE 8F 18 2B 9F DA 0A 76"; -stripType type; - -bool shouldSaveConfig = false; +stripType type = STRIP_TYPE; const char* mqtt_device_id = "/rgbController/"; const LogLevel LOGLEVEL = INFO; -WiFiManager wifiManager; - WiFiClient espClient; WiFiClientSecure espClientSecure; @@ -96,22 +88,6 @@ void debugFkt(String message, LogLevel LevelOfMessage){ } } -//callback notifying us of the need to save config -void saveConfigCallback () { - debugFkt("Should save config", INFO); - shouldSaveConfig = true; -} - -void firmmareReset(){ - if(digitalRead(pinM) == LOW){ - wifiManager.resetSettings(); - SPIFFS.format(); - digitalWrite(pinB, HIGH); - delay(500); - digitalWrite(pinB, LOW); - } -} - //WARNING: If received json incomplete, increase MQTT_MAX_PACKET_SIZE in PubSunClient Library void callback(char* topic, byte* payload, unsigned int length) { for (unsigned int i = 0; i < length; i++) { @@ -165,11 +141,11 @@ void callback(char* topic, byte* payload, unsigned int length) { void initMQTT() { if(strcmp(mqtt_ssl, "yes") == 0){ - client = PubSubClient(espClientSecure); + client.setClient(espClientSecure); debugFkt("Will compare SSL-Fingerprint and use WifiClientSecure", INFO); espClientSecure.setFingerprint(fingerprint); }else{ - client = PubSubClient(espClient); + client.setClient(espClient); debugFkt("Will not use SSL -> Standard WifiClient", INFO); } @@ -200,7 +176,7 @@ void initMQTT() { connected = client.connect(clientId.c_str(), mqtt_username, mqtt_password); }else{ debugFkt("connecting to mqtt server without username and password", INFO); - connected = client.connect(clientId.c_str()); + connected = client.connect(clientId.c_str()); } //react to outcome of connect try @@ -216,14 +192,14 @@ void initMQTT() { //subscribe this device's topic client.subscribe(mainTopic); - + debugFkt("subscribed main Topic ", INFO); - + //Publish Info that Board Connected //client.publish("/ESPLED/",WiFi.macAddress().c_str()); String HelloMessage = "espled-board "+ WiFi.macAddress() + " connected"; - client.publish("/ESPLED/", HelloMessage.c_str()); - + client.publish("/ESPLED/", HelloMessage.c_str()); + } else { @@ -231,7 +207,7 @@ void initMQTT() { debugFkt("failed, rc=", ERROR); debugFkt(String(client.state()), ERROR); debugFkt("Try again in 5 seconds", ERROR); - + // Wait 5 seconds before retrying delay(5000); } @@ -240,148 +216,19 @@ void initMQTT() { void initWifi() { - WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40); - WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6); - WiFiManagerParameter custom_strip_type("strip_type", "strip type", strip_type, 8); - WiFiManagerParameter custom_mqtt_ssl("ssl", "no", mqtt_ssl, 3); - WiFiManagerParameter custom_mqtt_username("mqtt_username", "username", mqtt_username, 40); - WiFiManagerParameter custom_mqtt_password("mqtt_password", "password", mqtt_password, 40); - - wifiManager.setSaveConfigCallback(saveConfigCallback); - - wifiManager.addParameter(&custom_mqtt_server); - wifiManager.addParameter(&custom_mqtt_port); - wifiManager.addParameter(&custom_strip_type); - wifiManager.addParameter(&custom_mqtt_ssl); - wifiManager.addParameter(&custom_mqtt_username); - wifiManager.addParameter(&custom_mqtt_password); - - wifiManager.autoConnect("RGB Controller Setup"); - wifiManager.setConfigPortalTimeout(180); - - //After the WiFi Manger is done, we are most probably connected - debugFkt("local ip", INFO); - debugFkt(WiFi.localIP().toString(), INFO); - - - strcpy(mqtt_server, custom_mqtt_server.getValue()); - strcpy(mqtt_port, custom_mqtt_port.getValue()); - strcpy(strip_type, custom_strip_type.getValue()); - strcpy(mqtt_ssl, custom_mqtt_ssl.getValue()); - strcpy(mqtt_username, custom_mqtt_username.getValue()); - strcpy(mqtt_password, custom_mqtt_password.getValue()); + WiFi.mode(WIFI_STA); + WiFi.begin(wifi_default_ssid, wifi_default_password); + debugFkt("Connecting to WiFi: " + String(wifi_default_ssid), INFO); - //save the custom parameters to FS - if (shouldSaveConfig) { - debugFkt("saving config", INFO); - - DynamicJsonDocument doc(4000); - JsonObject json = doc.to(); - - json["mqtt_server"] = mqtt_server; - json["mqtt_port"] = mqtt_port; - json["strip_type"] = strip_type; - json["mqtt_ssl"] = mqtt_ssl; - json["mqtt_username"] = mqtt_username; - json["mqtt_password"] = mqtt_password; - - - File configFile = SPIFFS.open("/config.json", "w"); - if (!configFile) { - debugFkt("failed to open config file for writing", ERROR); - } - - serializeJson(json, Serial); - serializeJson(json, configFile); - configFile.close(); - //end save + while (WiFi.status() != WL_CONNECTED) { + delay(500); } -} - -void initOta(){ - //TODO: Password - //Init OTA update routine - ArduinoOTA.onStart([]() { - String type; - if (ArduinoOTA.getCommand() == U_FLASH) { - type = "sketch"; - } else { // U_SPIFFS - type = "filesystem"; - } - debugFkt("Start updating " + type, INFO); - }); - ArduinoOTA.onEnd([]() { - debugFkt("End", INFO); - }); - ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - Serial.printf("Progress: %u%%\r", (progress / (total / 100))); - }); - ArduinoOTA.onError([](ota_error_t error) { - Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) { - debugFkt("Auth Failed", ERROR); - } else if (error == OTA_BEGIN_ERROR) { - debugFkt("Begin Failed", ERROR); - } else if (error == OTA_CONNECT_ERROR) { - debugFkt("Connect Failed", ERROR); - } else if (error == OTA_RECEIVE_ERROR) { - debugFkt("Receive Failed", ERROR); - } else if (error == OTA_END_ERROR) { - debugFkt("End Failed", ERROR); - } - }); - ArduinoOTA.begin(); + debugFkt("local ip", INFO); + debugFkt(WiFi.localIP().toString(), INFO); } -void initFS(){ - debugFkt("mounting FS...", INFO); - - if (SPIFFS.begin()) { - debugFkt("mounted file system", INFO); - if (SPIFFS.exists("/config.json")) { - //file exists, reading and loading - debugFkt("reading config file", INFO); - File configFile = SPIFFS.open("/config.json", "r"); - if (configFile) { - debugFkt("opened config file", INFO); - size_t size = configFile.size(); - // Allocate a buffer to store contents of the file. - std::unique_ptr buf(new char[size]); - - configFile.readBytes(buf.get(), size); - - DynamicJsonDocument doc(2000); - DeserializationError error = deserializeJson(doc, buf.get()); - if (error) { - } - JsonObject json = doc.as(); - - - - serializeJson(json, Serial); - if (!json.isNull()) { - debugFkt("parsed json", INFO); - - strcpy(mqtt_server, json["mqtt_server"]); - strcpy(mqtt_port, json["mqtt_port"]); - strcpy(strip_type, json["strip_type"]); - strcpy(mqtt_ssl, json["mqtt_ssl"]); - strcpy(mqtt_username, json["mqtt_username"]); - strcpy(mqtt_password, json["mqtt_password"]); - - } else { - debugFkt("failed to load json config", ERROR); - } - configFile.close(); - } - } - } else { - debugFkt("failed to mount FS", ERROR); - } - debugFkt("Finished spiffs", INFO); -} void initPins(){ pinMode(pinR, OUTPUT); @@ -402,15 +249,10 @@ void initPins(){ } void initStrip(){ - if(strcmp(strip_type, "RGB") == 0) type = stripType::RGB_STRIP; - else if(strcmp(strip_type, "RGBW") == 0) type = stripType::RGBW_STRIP; - else if(strcmp(strip_type, "RGBWW") == 0) type = stripType::RGBWW_STRIP; - else if(strcmp(strip_type, "WS2812") == 0) type = stripType::WS2812_STRIP; - else if(strcmp(strip_type, "APA102") == 0) type = stripType::APA102_STRIP; - if(type < 6){ debugFkt("Animation handler, strip and Silo initialized", INFO); Silo = new varSilo(); + Silo->length = STRIP_LENGTH; simpleStrip = new StripControle(type); pwmHandler = new AnimationHandlerPWM(simpleStrip, Silo, varSiloChanged); } @@ -434,17 +276,14 @@ void runAnimationHandler(){ void setup(){ initPins(); - firmmareReset(); Serial.begin(115200); delay(50); debugFkt("Booting", INFO); delay(500); - initFS(); initWifi(); initMQTT(); - initOta(); initStrip(); debugFkt("Ready", INFO); @@ -459,8 +298,6 @@ unsigned int freeHeap = 0; void loop() { cycleCount = ESP.getCycleCount(); - //OTA Handler - ArduinoOTA.handle(); //Run PWM Handler handle runAnimationHandler(); From eabe4c86f7e526c0416cfc5ebd355f1d775a9665 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Fri, 7 Aug 2026 00:30:34 +0200 Subject: [PATCH 02/39] Pull in AnnimationHandlerBus implementations --- software/README.md | 174 ++++++++++++++++-- .../AnimationHandlerBus.cpp | 172 +++++++++++++++-- .../AnimationHandlerBus/AnimationHandlerBus.h | 24 ++- software/lib/Definitions/PinDefinitions.h | 2 + software/lib/Definitions/TypeDefinitions.h | 2 +- software/src/main.cpp | 23 +-- 6 files changed, 350 insertions(+), 47 deletions(-) diff --git a/software/README.md b/software/README.md index 9cf44a0..a1484da 100644 --- a/software/README.md +++ b/software/README.md @@ -10,17 +10,21 @@ Although the ESPLED board is fully customizable, the default software should sat The configuration mode allows you to select your local WiFi network and the type of led strip you want to use. To enter the configuration mode, perform the following tasks: -- Press the __reset__ button -- Press and hold the __mode__ button after within 1 second after releasing the reset button -- Release the __mode__ button within 2 seconds +? +- Press and release the __reset__ button +- Press and hold the __mode__ button, the ESP Module should turn on its blue led permanently +- Hold the __mode__ button down until the led strip blinks blue once +- then the board is reset and should open up it's own wifi again After sucessfully entering the configuration mode, use your smartphone or computer to connect to the wireless network called "ESPLED config" and follow the screen. ## Control LEDs -There are three different interfaces to connect to the controller. -*MQTT -*REST API -*On-Board-Button +The README historically listed three interfaces (MQTT, REST API, On-Board-Button), but in the +current firmware only __MQTT__ is actually implemented for runtime control. The on-board "mode" +button (`pinM`) is only read once at boot to decide whether to enter configuration mode +(see [Configuration](#configuration)) — it is not wired up to change modes while running. No REST +API/webserver for LED control exists in the code; `initWifi()` only starts WiFiManager's setup +portal, which is torn down after Wi-Fi credentials are captured. ### MQTT The different functions of the controller are available under the following MQTT topic: @@ -44,12 +48,150 @@ The payload contais json in the following format: } ``` -| Function | Topic | Values | -|------------------------------------------|--------------------------|--------------------| -| Change Mode | mode | 0 to 200 | -| Color amplitudes | color[ R,G,B,(CW),(WW) ] | 10 bit integer | -| Timeframe in milliseconds(ex. fade time) | time | unsigned integer | -| Frequency in hertz | frequency | float | -| Relativ sensitivity | sensitivity | float (0.0 to 1.0) | -| Number of leds (mode specific) | length | unsigned integer | -| Select start led (mode specific) | position | unsigned integer | +Any subset of fields can be sent — only keys present in the JSON payload overwrite the +corresponding value; everything else keeps its last value. + +| Function | Topic | Values | Used by modes | +|--------------------------------------------|--------------------------|---------------------|---------------| +| Change Mode | mode | see [Modes](#modes) below | all | +| Color amplitudes | color[ R,G,B,WW,CW ] | 10 bit integer (0-1023) | 0,1,2,4,6,100,101,103 | +| Timeframe in milliseconds (ex. fade time) | time | unsigned integer | 0, 1 (fade legs), 4 (period), 100 | +| Frequency in hertz | frequency | unsigned integer, 1-60 | 2, 101 | +| Relative sensitivity | sensitivity | __unsigned char (0-255)__ — see note | 103 | +| Number of leds (mode specific) | length | unsigned integer | 1 (blink repeat count) | +| Select start led (mode specific) | position | unsigned integer | 103 (render style 0/1/2) | +| Lower brightness bound | minBrightnes | unsigned integer (0-1023) | 4 | +| Upper brightness bound | maxBrightnes | unsigned integer (0-1023) | 4 | +| Random jitter on `time` | timeVariance | unsigned integer (ms) | 4 | +| Random jitter on `maxBrightnes` | maxBrightnesVariance | unsigned integer | 4 | +| Hold time / recovery probability (mode specific) | duration | unsigned integer | 1 (hold ms), 6 (probability 0-65535) | + +> __Note on `sensitivity`:__ the README used to describe this as a `float` (0.0-1.0), and that is how +> `vuMeter()` uses it conceptually (`amplitude * (1 + sensitivity * 0.09)`). However `varSilo.sensitivity` +> is declared as `unsigned char` ([TypeDefinitions.h](/lib/Definitions/TypeDefinitions.h)) and the MQTT +> callback assigns the JSON value to it directly, so any fractional value sent over MQTT is truncated +> to an integer 0-255 before use. Send whole numbers until this is fixed in firmware. + +> __Note on `length` / `position`:__ these are documented generically as "mode specific" and are *not* +> generic strip-geometry controls — `length` is only read by mode 1 (`blinkColor`, as a repeat count) +> and `position` is only read by mode 103 (`vuMeter`, as a layout-style selector). No mode currently +> uses them to mean "number of LEDs" or "start LED index". + +### Modes +Which modes are available depends on the strip type selected during [configuration](#configuration): + +- __Uniform strips__ (`RGB`, `RGBW`, `RGBWW`) are driven by `AnimationHandlerPWM` and only support the + *uniform color* modes (0-6). Sending an addressable-only mode (100+) is rejected (logged as an error, + outputs black). +- __Addressable strips__ (`WS2812`, `APA102`) are driven by `AnimationHandlerBus` and support both the + uniform modes (rendered by filling the whole strip with one calculated color) and the addressable + modes (100+, which control individual pixels). + +| # | Mode | Strip support | Status | Parameters used | Description | +|---|------|----------------|--------|------------------|--------------| +| 0 | FADE_2_COLOR | uniform + addressable | Implemented | `color`, `time` | Linearly fades every channel from the previous color to `color` over `time` ms, then holds. | +| 1 | BLINK_COLOR | uniform + addressable | Implemented | `color`, `time`, `duration`, `length` | State machine: fades up to `color` over `time`, holds for `duration`, fades back down over `time`, holds off for `duration`, repeating `length` times (a `length` ≤ 1 skips the fade-to-min leg, giving a single blink). After the last cycle it fades back into whatever mode/color was active before this one was triggered (stored in `oldVarSilo`). While mode 1 is already active, a new `mode: 1` MQTT message is ignored/dismissed rather than restarting the sequence (see `callback()` in [initFunctions.h](/src/initFunctions.h)). | +| 2 | STROBE | uniform + addressable | Implemented | `color`, `frequency` | Square-wave toggles the strip between off and `color` at `frequency` Hz. `frequency` of 0 or >60 is rejected (logged as error, outputs black). | +| 3 | SOUND_2_LIGHT | uniform + addressable | Stub only | — | Currently just triggers an FFT calculation and dumps the frequency vector to the debug log every 200ms; does __not__ drive any LED color yet (always returns black). Placeholder for a future audio-reactive uniform mode — mode 103 (`vuMeter`) is the working audio-reactive mode today. | +| 4 | BREATHE | uniform + addressable | Implemented | `color`, `time`, `minBrightnes`, `maxBrightnes`, `timeVariance`, `maxBrightnesVariance` | Cosine "breathing" brightness oscillation of `color` between `minBrightnes` and `maxBrightnes` with period `time`. Each cycle, the period and peak brightness are randomly jittered by ±`timeVariance`/±`maxBrightnesVariance` for a more organic look. Guards: `timeVariance` is reset to 0 if ≥ `time`; `maxBrightnes` and `maxBrightnesVariance` are reset to 1023/0 if their sum would exceed 1023. | +| 5 | TEMPVIS | — | __Reserved, not implemented__ | — | Defined in the `Mode` enum but has no handler function and no `switch` case in either `AnimationHandlerPWM` or `AnimationHandlerBus`. Selecting it logs an error and outputs black. | +| 6 | INDUSTRIAL_FLICKER | uniform + addressable | Implemented | `color`, `duration` | Simulates a failing/flickering light via a random-walk state machine between "flash" (on), "old color" (dim/previous color), and "permanent on". `duration` (0-65535) is the probability threshold that a flicker recovers into another flash rather than settling permanently on `color`; 0 or values above `UINT16_MAX` default to ~43690 (2/3 of the range). | +| 100 | WIPE | addressable only | Implemented | `color`, `time` | Lights the strip LED-by-LED from index 0 to the end over `time` ms total (`time`/stripLength per LED), then holds `color` once fully lit. Does not use `length`/`position`. | +| 101 | NOISE | addressable only | Implemented | `color`, `frequency` | Randomly (50/50 per LED, per refresh) sets each LED to `color` or off, refreshed at `frequency` Hz. `frequency` of 0 or >60 is rejected the same way as mode 2. | +| 102 | FIRE | addressable only | __Reserved, not implemented__ | — | Declared on `AnimationHandlerBus` and has a source file ([fire.cpp](/lib/AnimationHandlerBus/AdressableModes/fire.cpp)), but that file is currently empty and there is no `switch` case for it in `getNewStripBuffer()`. Selecting it logs "mode not implemented" and leaves the strip buffer unchanged. | +| 103 | VU_METER | addressable only | Implemented | `color`, `sensitivity`, `position` | Audio-reactive bar driven by the microphone's average amplitude (scaled by `sensitivity`), plus a slow-decaying red peak-hold pixel. `position` selects the render style: `0` = bar grows from the start of the strip, `1` = symmetric bar growing outward from the center, `2` = bar grows backward from the end of the strip. | +| 104 | STROBE_PARTS | addressable only | __Reserved, not implemented__ | — | Defined in the enum only — no handler function, no `switch` case. | +| 105 | MOVING_PARTS | addressable only | __Reserved, not implemented__ | — | Defined in the enum only — no handler function, no `switch` case. | + +### Example payloads +One MQTT payload to activate each implemented mode, each using a different color so the +effects are easy to tell apart. Modes 5, 102, 104 and 105 are omitted — they are reserved but +not implemented, so there is no meaningful payload for them (any `color`/`time`/etc. sent +alongside them is simply ignored). + +__0 — FADE_2_COLOR__ (amber, 2s fade) +```json +{ + "mode": 0, + "color": [1023, 400, 60, 0, 0], + "time": 2000 +} +``` + +__1 — BLINK_COLOR__ (cyan, 3 blinks, 300ms fade legs, 400ms hold) +```json +{ + "mode": 1, + "color": [0, 700, 1023, 0, 0], + "time": 300, + "duration": 400, + "length": 3 +} +``` + +__2 — STROBE__ (magenta, 10 Hz) +```json +{ + "mode": 2, + "color": [1023, 0, 850, 0, 0], + "frequency": 10 +} +``` + +__3 — SOUND_2_LIGHT__ (teal — stub only, currently has no visible effect) +```json +{ + "mode": 3, + "color": [0, 1023, 650, 0, 0] +} +``` + +__4 — BREATHE__ (violet, 4s base period, brightness 100-900 ±150 jitter) +```json +{ + "mode": 4, + "color": [550, 0, 1023, 0, 0], + "time": 4000, + "minBrightnes": 100, + "maxBrightnes": 900, + "timeVariance": 500, + "maxBrightnesVariance": 100 +} +``` + +__6 — INDUSTRIAL_FLICKER__ (warm white, ~2/3 recovery probability) +```json +{ + "mode": 6, + "color": [900, 500, 100, 300, 0], + "duration": 43690 +} +``` + +__100 — WIPE__ (green, addressable strips only, 1.5s total wipe) +```json +{ + "mode": 100, + "color": [50, 1023, 150, 0, 0], + "time": 1500 +} +``` + +__101 — NOISE__ (blue-white sparkle, addressable strips only, 20 Hz refresh) +```json +{ + "mode": 101, + "color": [200, 220, 1023, 0, 0], + "frequency": 20 +} +``` + +__103 — VU_METER__ (red-orange, addressable strips only, high sensitivity, centered bar) +```json +{ + "mode": 103, + "color": [1023, 250, 0, 0, 0], + "sensitivity": 200, + "position": 1 +} +``` diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp index 096b62f..7f63282 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp @@ -1,18 +1,160 @@ #include +extern void debugFkt(String, LogLevel); -//case FIRE: -// fire(); -// break; -// case NOISE: -// noise(); -// break; -// case VU_METER: -// vuMeter(): -// break; -// case STROBE_PARTS: -// strobeParts(); -// break; -// case MOVING_PARTS: -// movingParts(); -// break; +AnimationHandlerBus::AnimationHandlerBus(stripType* type, unsigned int stripLength, varSilo* silo, bool* varSiloChanged) + : AnimationHandler{silo, varSiloChanged} +{ + this->stripLength = stripLength; + + //Allocate memory for CRGB led Buffer according to number of leds + this->leds = (CRGB*)malloc(sizeof(CRGB) * stripLength); + memset(this->leds, 0, stripLength * sizeof(CRGB)); + + //Setup fastled lib with memory area and length + switch(*type){ + case WS2812_STRIP: + FastLED.addLeds(leds, stripLength); + debugFkt("WS2812 Bus initialized", INFO); + break; + case APA102_STRIP: + FastLED.addLeds(leds, stripLength); + debugFkt("APA102 Bus initialized", INFO); + break; + default: + debugFkt("Unknown stripType in AnimationHandlerBus or not implemented yet", ERROR); + break; + } +} + +AnimationHandlerBus::~AnimationHandlerBus(){ + free(this->leds); +} + +void AnimationHandlerBus::handle(){ + unsigned int now = millis(); + + if(*varSiloChanged){ + lastChange = now; + oldColor = FastLedCRGB2CRGBWW(this->leds[0]); + *varSiloChanged = false; + } + + if(now > fpsTimer + UPDATE_TIME){ + fpsTimer = now; + + if(silo->mode < 100){ + //Uniform color mode -> fill the whole strip with one calculated color + fill_solid(this->leds, this->stripLength, CRGBWW2FastLedCRGB(this->getNewColor())); + }else{ + //Addressable mode -> individual pixels are set by the mode function itself + this->getNewStripBuffer(); + } + + FastLED.show(); + } +} + +CRGB AnimationHandlerBus::CRGBWW2FastLedCRGB(CRGBWW color){ + CRGB out; + out.r = color.R / 4; + out.g = color.G / 4; + out.b = color.B / 4; + //TODO: include CW/WW channels + return out; +} + +CRGBWW AnimationHandlerBus::FastLedCRGB2CRGBWW(CRGB color){ + CRGBWW out; + out.R = color.r * 4; + out.G = color.g * 4; + out.B = color.b * 4; + out.WW = 0; + out.CW = 0; + return out; +} + +CRGBWW AnimationHandlerBus::getNewColor(){ + switch(silo->mode){ + case FADE_2_COLOR: + return fade2Color(); + case BLINK_COLOR: + return blinkColor(); + case STROBE: + return strobe(); + case SOUND_2_LIGHT: + return sound2Light(); + case BREATHE: + return breathe(); + default: + debugFkt("The Selected Mode is not a uniform color mode", ERROR); + return CRGBWW{0,0,0,0,0}; + } +} + +void AnimationHandlerBus::getNewStripBuffer(){ + switch(silo->mode){ + case WIPE: + this->wipe(); + break; + case NOISE: + this->noise(); + break; + default: + debugFkt("The Selected Mode is not implemented yet", ERROR); + break; + } +} + +void AnimationHandlerBus::wipe(){ + unsigned long now = millis(); + bool wipeEndReached = now > (this->lastChange + this->silo->time + UPDATE_TIME); + static CRGB color = CRGB::Black; + static unsigned long timePerLed = 0; + + // handle reset of static vars through varSiloChanged + if(now < this->lastChange + UPDATE_TIME){ + timePerLed = this->silo->time / this->stripLength; + if(timePerLed < 1) timePerLed = 1; + + color = CRGBWW2FastLedCRGB(silo->colorValue); + } + + if(!wipeEndReached){ + unsigned int numberOfLedsToTurnOn = (now - this->lastChange) / timePerLed; + if(numberOfLedsToTurnOn > this->stripLength) numberOfLedsToTurnOn = this->stripLength; + + for(unsigned int i = 0; i < numberOfLedsToTurnOn; i++){ + this->leds[i] = color; + } + }else{ + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = color; + } + } +} + +void AnimationHandlerBus::noise(){ + if(this->silo->frequency == 0 || this->silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static unsigned long lastStateChange = 0; + long period = (1000 / this->silo->frequency); + + if(now >= lastStateChange + period){ + lastStateChange = now; + + CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); + + for(unsigned int i = 0; i < this->stripLength; i++){ + if(random16(0, 1000) > 500){ + this->leds[i] = color; + }else{ + this->leds[i] = CRGB::Black; + } + } + } +} diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h index 7f1f6b1..ea0d65f 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h @@ -2,11 +2,27 @@ #include #include +#include +class AnimationHandlerBus : AnimationHandler{ + public: + AnimationHandlerBus(stripType* type, unsigned int stripLength, varSilo* silo, bool* varSiloChanged); + ~AnimationHandlerBus(); -class AnimationHandlerBus{ -public: - void fade(CRGBWW value,double transitionTime); -private: + void handle(); + private: + CRGB* leds; //buffer on Heap for Adressable Strips + unsigned int stripLength; + + CRGBWW getNewColor(); + void getNewStripBuffer(); + + //Helpers + CRGB CRGBWW2FastLedCRGB(CRGBWW color); + CRGBWW FastLedCRGB2CRGBWW(CRGB color); + + //Addressable Modes + void wipe(); + void noise(); }; diff --git a/software/lib/Definitions/PinDefinitions.h b/software/lib/Definitions/PinDefinitions.h index 05265e3..517ba56 100644 --- a/software/lib/Definitions/PinDefinitions.h +++ b/software/lib/Definitions/PinDefinitions.h @@ -8,5 +8,7 @@ #define pinWW 12 #define pinCW 13 #define pinM 2 +#define pinData 5 //Addressable strip data line (WS2812/APA102), shares GPIO with pinR since only one strip type is active at a time +#define pinClock 3 //APA102 clock line only //------------------------------------------------------------------------------ #endif diff --git a/software/lib/Definitions/TypeDefinitions.h b/software/lib/Definitions/TypeDefinitions.h index 9c10fce..d6143ee 100644 --- a/software/lib/Definitions/TypeDefinitions.h +++ b/software/lib/Definitions/TypeDefinitions.h @@ -39,7 +39,7 @@ enum stripType {RGB_STRIP = 3, RGBW_STRIP, RGBWW_STRIP, WS2812_STRIP, APA102_STR //LED Strip Modes -enum Mode {FADE_2_COLOR, BLINK_COLOR, STROBE, SOUND_2_LIGHT, BREATHE, FIRE = 101, NOISE, VU_METER, STROBE_PARTS, MOVING_PARTS}; +enum Mode {FADE_2_COLOR, BLINK_COLOR, STROBE, SOUND_2_LIGHT, BREATHE, WIPE = 100, FIRE = 101, NOISE, VU_METER, STROBE_PARTS, MOVING_PARTS}; //Log LEVELS enum LogLevel {VERBOSE, DEBUG, INFO, WARNING, ERROR}; diff --git a/software/src/main.cpp b/software/src/main.cpp index ff8bf6f..9a6c5d9 100644 --- a/software/src/main.cpp +++ b/software/src/main.cpp @@ -50,7 +50,6 @@ PubSubClient client; StripControle* simpleStrip; AnimationHandlerPWM* pwmHandler; AnimationHandlerBus* busHandler; -//TODO: Adressable Strip void debugFkt(String message, LogLevel LevelOfMessage){ @@ -249,16 +248,17 @@ void initPins(){ } void initStrip(){ + Silo = new varSilo(); + Silo->length = STRIP_LENGTH; + if(type < 6){ - debugFkt("Animation handler, strip and Silo initialized", INFO); - Silo = new varSilo(); - Silo->length = STRIP_LENGTH; + debugFkt("Animation handler, strip and Silo initialized [uniform strip]", INFO); simpleStrip = new StripControle(type); pwmHandler = new AnimationHandlerPWM(simpleStrip, Silo, varSiloChanged); } else{ - //TODO - //busHandler = new AnimationHandlerBus() + debugFkt("Animation handler, strip and Silo initialized [adressable strip]", INFO); + busHandler = new AnimationHandlerBus(&type, STRIP_LENGTH, Silo, varSiloChanged); } } @@ -267,8 +267,7 @@ void runAnimationHandler(){ pwmHandler->handle(); } else{ - //TODO - //busHandler->handle(); + busHandler->handle(); } } @@ -288,9 +287,11 @@ void setup(){ debugFkt("Ready", INFO); debugFkt("IP address: " + WiFi.localIP().toString(), INFO); - simpleStrip->showColor(CRGBWW{0,1023,0,1023,0}); - delay(500); - simpleStrip->showColor(CRGBWW{0,0,0,0,0}); + if(type < 6){ + simpleStrip->showColor(CRGBWW{0,1023,0,1023,0}); + delay(500); + simpleStrip->showColor(CRGBWW{0,0,0,0,0}); + } } unsigned int cycleCount = 0; From fb8b37048a3aabbe710f94c67b8d0ca76ed72373 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 01:43:25 +0200 Subject: [PATCH 03/39] 1 Part A: split AnimationHandlerBus modes into one file per mode 2 3 Move wipe()/noise() out of the monolithic AnimationHandlerBus.cpp into 4 their own files under AnimationHandlerBus/Modes/, matching the existing 5 convention in AnimationHandler/Modes/. No behavior change. 6 7 Co-Authored-By: Claude Sonnet 5 --- .../AnimationHandlerBus.cpp | 54 +------------------ .../lib/AnimationHandlerBus/Modes/noise.cpp | 26 +++++++++ .../lib/AnimationHandlerBus/Modes/wipe.cpp | 29 ++++++++++ 3 files changed, 57 insertions(+), 52 deletions(-) create mode 100644 software/lib/AnimationHandlerBus/Modes/noise.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/wipe.cpp diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp index 7f63282..f0f886f 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp @@ -106,55 +106,5 @@ void AnimationHandlerBus::getNewStripBuffer(){ } } -void AnimationHandlerBus::wipe(){ - unsigned long now = millis(); - bool wipeEndReached = now > (this->lastChange + this->silo->time + UPDATE_TIME); - static CRGB color = CRGB::Black; - static unsigned long timePerLed = 0; - - // handle reset of static vars through varSiloChanged - if(now < this->lastChange + UPDATE_TIME){ - timePerLed = this->silo->time / this->stripLength; - if(timePerLed < 1) timePerLed = 1; - - color = CRGBWW2FastLedCRGB(silo->colorValue); - } - - if(!wipeEndReached){ - unsigned int numberOfLedsToTurnOn = (now - this->lastChange) / timePerLed; - if(numberOfLedsToTurnOn > this->stripLength) numberOfLedsToTurnOn = this->stripLength; - - for(unsigned int i = 0; i < numberOfLedsToTurnOn; i++){ - this->leds[i] = color; - } - }else{ - for(unsigned int i = 0; i < this->stripLength; i++){ - this->leds[i] = color; - } - } -} - -void AnimationHandlerBus::noise(){ - if(this->silo->frequency == 0 || this->silo->frequency > 60){ - debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); - return; - } - - unsigned long now = millis(); - static unsigned long lastStateChange = 0; - long period = (1000 / this->silo->frequency); - - if(now >= lastStateChange + period){ - lastStateChange = now; - - CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); - - for(unsigned int i = 0; i < this->stripLength; i++){ - if(random16(0, 1000) > 500){ - this->leds[i] = color; - }else{ - this->leds[i] = CRGB::Black; - } - } - } -} +// Per-mode render functions live under Modes/ (one file per mode), matching +// the convention already used by AnimationHandler/Modes/. diff --git a/software/lib/AnimationHandlerBus/Modes/noise.cpp b/software/lib/AnimationHandlerBus/Modes/noise.cpp new file mode 100644 index 0000000..2739c2d --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/noise.cpp @@ -0,0 +1,26 @@ +#include + +void AnimationHandlerBus::noise(){ + if(this->silo->frequency == 0 || this->silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static unsigned long lastStateChange = 0; + long period = (1000 / this->silo->frequency); + + if(now >= lastStateChange + period){ + lastStateChange = now; + + CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); + + for(unsigned int i = 0; i < this->stripLength; i++){ + if(random16(0, 1000) > 500){ + this->leds[i] = color; + }else{ + this->leds[i] = CRGB::Black; + } + } + } +} diff --git a/software/lib/AnimationHandlerBus/Modes/wipe.cpp b/software/lib/AnimationHandlerBus/Modes/wipe.cpp new file mode 100644 index 0000000..80e26da --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/wipe.cpp @@ -0,0 +1,29 @@ +#include + +void AnimationHandlerBus::wipe(){ + unsigned long now = millis(); + bool wipeEndReached = now > (this->lastChange + this->silo->time + UPDATE_TIME); + static CRGB color = CRGB::Black; + static unsigned long timePerLed = 0; + + // handle reset of static vars through varSiloChanged + if(now < this->lastChange + UPDATE_TIME){ + timePerLed = this->silo->time / this->stripLength; + if(timePerLed < 1) timePerLed = 1; + + color = CRGBWW2FastLedCRGB(silo->colorValue); + } + + if(!wipeEndReached){ + unsigned int numberOfLedsToTurnOn = (now - this->lastChange) / timePerLed; + if(numberOfLedsToTurnOn > this->stripLength) numberOfLedsToTurnOn = this->stripLength; + + for(unsigned int i = 0; i < numberOfLedsToTurnOn; i++){ + this->leds[i] = color; + } + }else{ + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = color; + } + } +} From d71afd611bc83bf9b7bb27547c43a80e73c5d0a9 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 01:46:36 +0200 Subject: [PATCH 04/39] 1 Part B: implement 8 addressable-only effect modes 2 3 Fill in the 4 reserved-but-unimplemented modes (FIRE, VU_METER, 4 STROBE_PARTS, MOVING_PARTS) and add 4 more (RAINBOW_CYCLE, THEATER_CHASE, 5 COMET, NIGHT_SKY) to AnimationHandlerBus, each as its own file under 6 Modes/. FIRE is a directional single-end flame with a tunable side 7 (silo->position), occasional blue base tint and dim smoke near the tip. 8 VU_METER needed AnimationHandlerBus::handle() to start sampling audio 9 every tick (it never did), so it's wired up the same way 10 AnimationHandlerPWM::handle() already does. 11 12 Co-Authored-By: Claude Sonnet 5 --- .../AnimationHandlerBus.cpp | 29 ++++++++ .../AnimationHandlerBus/AnimationHandlerBus.h | 8 +++ .../lib/AnimationHandlerBus/Modes/comet.cpp | 28 ++++++++ .../lib/AnimationHandlerBus/Modes/fire.cpp | 72 +++++++++++++++++++ .../AnimationHandlerBus/Modes/movingParts.cpp | 35 +++++++++ .../AnimationHandlerBus/Modes/nightSky.cpp | 57 +++++++++++++++ .../Modes/rainbowCycle.cpp | 27 +++++++ .../AnimationHandlerBus/Modes/strobeParts.cpp | 39 ++++++++++ .../Modes/theaterChase.cpp | 31 ++++++++ .../lib/AnimationHandlerBus/Modes/vuMeter.cpp | 47 ++++++++++++ software/lib/Definitions/TypeDefinitions.h | 6 +- 11 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 software/lib/AnimationHandlerBus/Modes/comet.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/fire.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/movingParts.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/nightSky.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/rainbowCycle.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/strobeParts.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/theaterChase.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/vuMeter.cpp diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp index f0f886f..a82aba9 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp @@ -40,6 +40,11 @@ void AnimationHandlerBus::handle(){ *varSiloChanged = false; } + if(now > audioTimer){ + audioTimer = now; + recordAudioSample(); + } + if(now > fpsTimer + UPDATE_TIME){ fpsTimer = now; @@ -100,6 +105,30 @@ void AnimationHandlerBus::getNewStripBuffer(){ case NOISE: this->noise(); break; + case FIRE: + this->fire(); + break; + case VU_METER: + this->vuMeter(); + break; + case STROBE_PARTS: + this->strobeParts(); + break; + case MOVING_PARTS: + this->movingParts(); + break; + case RAINBOW_CYCLE: + this->rainbowCycle(); + break; + case THEATER_CHASE: + this->theaterChase(); + break; + case COMET: + this->comet(); + break; + case NIGHT_SKY: + this->nightSky(); + break; default: debugFkt("The Selected Mode is not implemented yet", ERROR); break; diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h index ea0d65f..f904baf 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h @@ -25,4 +25,12 @@ class AnimationHandlerBus : AnimationHandler{ //Addressable Modes void wipe(); void noise(); + void fire(); + void vuMeter(); + void strobeParts(); + void movingParts(); + void rainbowCycle(); + void theaterChase(); + void comet(); + void nightSky(); }; diff --git a/software/lib/AnimationHandlerBus/Modes/comet.cpp b/software/lib/AnimationHandlerBus/Modes/comet.cpp new file mode 100644 index 0000000..4a040ff --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/comet.cpp @@ -0,0 +1,28 @@ +#include + +// Bright head pixel with a fading trail, traveling along the strip and +// wrapping at the end. Position is derived from (now - lastChange), same +// idiom as movingParts(), but the trail itself decays via fadeToBlackBy() +// instead of being a hard-edged block. +void AnimationHandlerBus::comet(){ + if(this->silo->time == 0){ + debugFkt("Time was set to 0, this is not possible", ERROR); + return; + } + + const uint8_t FADE_AMOUNT = 40; + + unsigned long now = millis(); + static CRGB color = CRGB::Black; + + if(now < this->lastChange + UPDATE_TIME){ + color = CRGBWW2FastLedCRGB(silo->colorValue); + fill_solid(this->leds, this->stripLength, CRGB::Black); + } + + unsigned long elapsed = (now - this->lastChange) % this->silo->time; + unsigned int headPos = (unsigned int)(elapsed * this->stripLength / this->silo->time); + + fadeToBlackBy(this->leds, this->stripLength, FADE_AMOUNT); + this->leds[headPos] = color; +} diff --git a/software/lib/AnimationHandlerBus/Modes/fire.cpp b/software/lib/AnimationHandlerBus/Modes/fire.cpp new file mode 100644 index 0000000..6b1a652 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/fire.cpp @@ -0,0 +1,72 @@ +#include + +// Directional single-end flame: logical index 0 is always "the base" (closest +// to the fire's origin); silo->position selects which physical end that maps +// to. Heat simulation follows the classic FastLED "Fire2012" reference +// (cool -> diffuse -> spark), with an occasional blue tint at the base and +// occasional dim smoke near the tip layered on top of the usual HeatColor(). +void AnimationHandlerBus::fire(){ + if(this->silo->frequency == 0 || this->silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + + const uint8_t COOLING = 55; + const uint8_t SPARKING = 120; + const CRGB SMOKE_COLOR = CRGB(20, 20, 25); + const unsigned int BASE_ZONE = 3; + + unsigned long now = millis(); + static uint8_t* heat = nullptr; + static unsigned long lastStep = 0; + + // handle reset of static vars through varSiloChanged + if(now < this->lastChange + UPDATE_TIME){ + if(heat == nullptr) heat = (uint8_t*)malloc(this->stripLength); + memset(heat, 0, this->stripLength); + lastStep = 0; + } + + bool reversed = (this->silo->position != 0); + long period = 1000 / this->silo->frequency; + + if(now >= lastStep + period){ + lastStep = now; + + // Step 1: cool down every cell a little + for(unsigned int i = 0; i < this->stripLength; i++){ + heat[i] = qsub8(heat[i], random8(0, ((COOLING * 10) / this->stripLength) + 2)); + } + + // Step 2: heat drifts away from the base and diffuses + for(int k = this->stripLength - 1; k >= 2; k--){ + heat[k] = (heat[k-1] + heat[k-2] + heat[k-2]) / 3; + } + + // Step 3: randomly ignite new sparks near the base + if(random8() < SPARKING){ + unsigned int sparkRange = this->stripLength < 7 ? this->stripLength : 7; + unsigned int y = random8(sparkRange); + heat[y] = qadd8(heat[y], random8(160, 255)); + } + + // Step 4: map heat to color and write into the physical buffer according + // to which side the fire is anchored on + unsigned int outerZoneStart = (this->stripLength * 6) / 10; + for(unsigned int logicalIndex = 0; logicalIndex < this->stripLength; logicalIndex++){ + uint8_t h = heat[logicalIndex]; + CRGB color; + + if(logicalIndex < BASE_ZONE && h > 150 && random8() < 40){ + color = blend(HeatColor(h), CRGB::Blue, random8(60, 140)); + }else if(h < 20 && logicalIndex >= outerZoneStart && random8() < 15){ + color = SMOKE_COLOR; + }else{ + color = HeatColor(h); + } + + unsigned int physicalIndex = reversed ? (this->stripLength - 1 - logicalIndex) : logicalIndex; + this->leds[physicalIndex] = color; + } + } +} diff --git a/software/lib/AnimationHandlerBus/Modes/movingParts.cpp b/software/lib/AnimationHandlerBus/Modes/movingParts.cpp new file mode 100644 index 0000000..b2fdc51 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/movingParts.cpp @@ -0,0 +1,35 @@ +#include + +// A single hard-edged solid block of silo->length LEDs translates along the +// strip and wraps around at the end. silo->time is the ms for one full-strip +// traversal, same unit/semantic as wipe()'s time. Position is derived every +// frame from (now - lastChange) rather than stored, so it self-restarts +// whenever the mode/params change. +void AnimationHandlerBus::movingParts(){ + if(this->silo->length == 0 || this->silo->length > this->stripLength){ + debugFkt("Length was set to 0 or larger than the strip, this is not possible", ERROR); + return; + } + if(this->silo->time == 0){ + debugFkt("Time was set to 0, this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static CRGB color = CRGB::Black; + + if(now < this->lastChange + UPDATE_TIME){ + color = CRGBWW2FastLedCRGB(silo->colorValue); + } + + unsigned long elapsed = (now - this->lastChange) % this->silo->time; + unsigned int headPos = (unsigned int)(elapsed * this->stripLength / this->silo->time); + + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = CRGB::Black; + } + for(unsigned int offset = 0; offset < this->silo->length; offset++){ + unsigned int pixel = (headPos + offset) % this->stripLength; + this->leds[pixel] = color; + } +} diff --git a/software/lib/AnimationHandlerBus/Modes/nightSky.cpp b/software/lib/AnimationHandlerBus/Modes/nightSky.cpp new file mode 100644 index 0000000..61c2625 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/nightSky.cpp @@ -0,0 +1,57 @@ +#include + +// Stars sparkle at tunable positions, count, brightness and frequency. +// silo->length caps the number of concurrently active stars; silo-> +// minBrightnes/maxBrightnes bound the brightness newly-spawned stars are +// randomly assigned within, matching how breathe() already uses that pair. +void AnimationHandlerBus::nightSky(){ + if(this->silo->frequency == 0 || this->silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + if(this->silo->length == 0 || this->silo->length > this->stripLength){ + debugFkt("Length was set to 0 or larger than the strip, this is not possible", ERROR); + return; + } + + const uint8_t FADE_AMOUNT = 10; + const uint8_t SPAWN_CHANCE = 60; // out of 255, per tick while below the max star count + + unsigned long now = millis(); + static uint8_t* starBrightness = nullptr; + static unsigned long lastStep = 0; + + if(now < this->lastChange + UPDATE_TIME){ + if(starBrightness == nullptr) starBrightness = (uint8_t*)malloc(this->stripLength); + memset(starBrightness, 0, this->stripLength); + lastStep = 0; + } + + long period = 1000 / this->silo->frequency; + if(now >= lastStep + period){ + lastStep = now; + + unsigned int activeCount = 0; + for(unsigned int i = 0; i < this->stripLength; i++){ + starBrightness[i] = qsub8(starBrightness[i], FADE_AMOUNT); + if(starBrightness[i] > 0) activeCount++; + } + + if(activeCount < this->silo->length && random8() < SPAWN_CHANCE){ + unsigned int index = random16(0, this->stripLength); + if(starBrightness[index] == 0){ + unsigned int lo = this->silo->minBrightnes; + unsigned int hi = this->silo->maxBrightnes; + if(hi < lo) hi = lo; + unsigned int brightness1023 = random16(lo, hi + 1); + starBrightness[index] = (uint8_t)(brightness1023 / 4); + } + } + + for(unsigned int i = 0; i < this->stripLength; i++){ + uint8_t b = starBrightness[i]; + uint8_t blueBoost = (b > 235) ? 255 : (uint8_t)(b + 20); + this->leds[i] = CRGB(b, b, blueBoost); + } + } +} diff --git a/software/lib/AnimationHandlerBus/Modes/rainbowCycle.cpp b/software/lib/AnimationHandlerBus/Modes/rainbowCycle.cpp new file mode 100644 index 0000000..b684d01 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/rainbowCycle.cpp @@ -0,0 +1,27 @@ +#include + +// Continuous hue-shift across the strip. startHue advances proportionally to +// elapsed time so the cycle period equals silo->time regardless of frame +// rate; it wraps naturally on uint8_t overflow. +void AnimationHandlerBus::rainbowCycle(){ + if(this->silo->time == 0){ + debugFkt("Time was set to 0, this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static uint8_t startHue = 0; + static unsigned long lastAdvance = 0; + + if(now < this->lastChange + UPDATE_TIME){ + startHue = 0; + lastAdvance = now; + } + + unsigned long elapsed = now - lastAdvance; + lastAdvance = now; + startHue += (uint8_t)((255UL * elapsed) / this->silo->time); + + uint8_t deltaHue = this->stripLength > 0 ? (uint8_t)(255 / this->stripLength) : 0; + fill_rainbow(this->leds, this->stripLength, startHue, deltaHue); +} diff --git a/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp b/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp new file mode 100644 index 0000000..d74ca25 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp @@ -0,0 +1,39 @@ +#include + +// Alternating-block checkerboard strobe: the strip is divided into blocks of +// silo->length LEDs; on each tick every block inverts together (even blocks +// lit / odd blocks off, then swapped). Distinct from the uniform strobe() +// (mode < 100), which flashes the whole strip at once. +void AnimationHandlerBus::strobeParts(){ + if(this->silo->frequency == 0 || this->silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + if(this->silo->length == 0 || this->silo->length > this->stripLength){ + debugFkt("Length was set to 0 or larger than the strip, this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static unsigned long lastToggle = 0; + static bool phaseOn = true; + + if(now < this->lastChange + UPDATE_TIME){ + lastToggle = 0; + phaseOn = true; + } + + long period = 1000 / this->silo->frequency; + if(now >= lastToggle + period){ + lastToggle = now; + phaseOn = !phaseOn; + + CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); + for(unsigned int i = 0; i < this->stripLength; i++){ + unsigned int blockIndex = i / this->silo->length; + bool blockIsEven = (blockIndex % 2 == 0); + bool lit = (blockIsEven == phaseOn); + this->leds[i] = lit ? color : CRGB::Black; + } + } +} diff --git a/software/lib/AnimationHandlerBus/Modes/theaterChase.cpp b/software/lib/AnimationHandlerBus/Modes/theaterChase.cpp new file mode 100644 index 0000000..8c4e0a2 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/theaterChase.cpp @@ -0,0 +1,31 @@ +#include + +// Classic marquee/theater-chase: fixed spacing of 3 (the canonical look), +// with the lit set shifting by one every silo->time ms. +void AnimationHandlerBus::theaterChase(){ + const unsigned int SPACING = 3; + + if(this->silo->time == 0){ + debugFkt("Time was set to 0, this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static unsigned long lastStep = 0; + static unsigned int phase = 0; + + if(now < this->lastChange + UPDATE_TIME){ + lastStep = 0; + phase = 0; + } + + if(now >= lastStep + this->silo->time){ + lastStep = now; + phase = (phase + 1) % SPACING; + + CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = ((i % SPACING) == phase) ? color : CRGB::Black; + } + } +} diff --git a/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp b/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp new file mode 100644 index 0000000..f1471b5 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp @@ -0,0 +1,47 @@ +#include + +// Simple rectified-amplitude envelope bar-graph (not FFT/spectrum - cheaper +// on the ESP8266, and a mono mic doesn't justify a per-band spectrum on a +// short strip). Depends on AnimationHandlerBus::handle() sampling audio into +// audioRingBuffer every tick. +void AnimationHandlerBus::vuMeter(){ + if(this->silo->frequency == 0 || this->silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + + unsigned long now = millis(); + static unsigned long lastStep = 0; + static float smoothedAmplitude = 0.0f; + + if(now < this->lastChange + UPDATE_TIME){ + smoothedAmplitude = 0.0f; + lastStep = 0; + } + + long period = 1000 / this->silo->frequency; + if(now >= lastStep + period){ + lastStep = now; + + float sumAbs = 0.0f; + for(unsigned int i = 0; i < ringBufferSize; i++){ + sumAbs += fabsf(audioRingBuffer[i] - 0.5f); + } + float rawAmplitude = sumAbs / ringBufferSize; + float gain = 1.0f + (this->silo->sensitivity / 255.0f) * 4.0f; + float target = rawAmplitude * gain * 2.0f; + if(target > 1.0f) target = 1.0f; + if(target < 0.0f) target = 0.0f; + + // one-pole smoothing so the bar doesn't flicker every tick + smoothedAmplitude = smoothedAmplitude * 0.7f + target * 0.3f; + + unsigned int litCount = (unsigned int)(smoothedAmplitude * this->stripLength); + if(litCount > this->stripLength) litCount = this->stripLength; + + CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = (i < litCount) ? color : CRGB::Black; + } + } +} diff --git a/software/lib/Definitions/TypeDefinitions.h b/software/lib/Definitions/TypeDefinitions.h index d6143ee..ba3213c 100644 --- a/software/lib/Definitions/TypeDefinitions.h +++ b/software/lib/Definitions/TypeDefinitions.h @@ -39,7 +39,11 @@ enum stripType {RGB_STRIP = 3, RGBW_STRIP, RGBWW_STRIP, WS2812_STRIP, APA102_STR //LED Strip Modes -enum Mode {FADE_2_COLOR, BLINK_COLOR, STROBE, SOUND_2_LIGHT, BREATHE, WIPE = 100, FIRE = 101, NOISE, VU_METER, STROBE_PARTS, MOVING_PARTS}; +enum Mode {FADE_2_COLOR, BLINK_COLOR, STROBE, SOUND_2_LIGHT, BREATHE, + OCEAN, FOREST, DUSK, FIRE_FLICKER, + WIPE = 100, FIRE = 101, NOISE, VU_METER, STROBE_PARTS, MOVING_PARTS, + RAINBOW_CYCLE = 106, THEATER_CHASE = 107, COMET = 108, PIXEL_ARRAY = 109, + NIGHT_SKY = 110}; //Log LEVELS enum LogLevel {VERBOSE, DEBUG, INFO, WARNING, ERROR}; From 4282377b116f18f070847867f94bd0fb30430dc0 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 01:48:26 +0200 Subject: [PATCH 05/39] 1 Part C: add PIXEL_ARRAY mode for direct per-pixel RGB control 2 3 Lets an MQTT client push an explicit R,G,B target for every LED in one 4 shot (e.g. lighting only selected rack-unit sections), decoupled from 5 the JSON control channel so it scales to 500 LEDs: a raw 3-bytes/LED 6 binary payload on a new /pixels sub-topic, with PubSubClient's 7 buffer grown to fit and the callback dispatching to 8 AnimationHandlerBus::setPixelData() before the existing per-byte debug 9 print/JSON parsing. 10 11 Co-Authored-By: Claude Sonnet 5 --- .../AnimationHandlerBus.cpp | 21 +++++++++++++++++++ .../AnimationHandlerBus/AnimationHandlerBus.h | 8 +++++++ .../AnimationHandlerBus/Modes/pixelArray.cpp | 10 +++++++++ software/src/main.cpp | 20 ++++++++++++++++-- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 software/lib/AnimationHandlerBus/Modes/pixelArray.cpp diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp index a82aba9..c2900ce 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp @@ -11,6 +11,10 @@ AnimationHandlerBus::AnimationHandlerBus(stripType* type, unsigned int stripLeng this->leds = (CRGB*)malloc(sizeof(CRGB) * stripLength); memset(this->leds, 0, stripLength * sizeof(CRGB)); + //Allocate memory for PIXEL_ARRAY's per-LED target buffer + this->pixelTargets = (PixelBytes*)malloc(sizeof(PixelBytes) * stripLength); + memset(this->pixelTargets, 0, stripLength * sizeof(PixelBytes)); + //Setup fastled lib with memory area and length switch(*type){ case WS2812_STRIP: @@ -29,6 +33,20 @@ AnimationHandlerBus::AnimationHandlerBus(stripType* type, unsigned int stripLeng AnimationHandlerBus::~AnimationHandlerBus(){ free(this->leds); + free(this->pixelTargets); +} + +void AnimationHandlerBus::setPixelData(const uint8_t* data, unsigned int length){ + unsigned int expectedLength = this->stripLength * 3; + if(length != expectedLength){ + debugFkt("Pixel array payload size mismatch, expected " + String(expectedLength) + " got " + String(length), ERROR); + return; + } + + for(unsigned int i = 0; i < this->stripLength; i++){ + unsigned int base = i * 3; + this->pixelTargets[i] = PixelBytes{data[base], data[base+1], data[base+2]}; + } } void AnimationHandlerBus::handle(){ @@ -129,6 +147,9 @@ void AnimationHandlerBus::getNewStripBuffer(){ case NIGHT_SKY: this->nightSky(); break; + case PIXEL_ARRAY: + this->pixelArray(); + break; default: debugFkt("The Selected Mode is not implemented yet", ERROR); break; diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h index f904baf..552a9f2 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h @@ -4,16 +4,23 @@ #include #include +// Raw per-LED target color received via the /pixels binary MQTT topic. +// 3 bytes/LED (0-255 each) - WS2812/APA102 have no WW/CW channels, so +// unlike CRGBWW there's nothing to carry for those here. +struct PixelBytes { uint8_t r, g, b; }; + class AnimationHandlerBus : AnimationHandler{ public: AnimationHandlerBus(stripType* type, unsigned int stripLength, varSilo* silo, bool* varSiloChanged); ~AnimationHandlerBus(); void handle(); + void setPixelData(const uint8_t* data, unsigned int length); private: CRGB* leds; //buffer on Heap for Adressable Strips unsigned int stripLength; + PixelBytes* pixelTargets; //buffer on Heap for PIXEL_ARRAY mode CRGBWW getNewColor(); void getNewStripBuffer(); @@ -33,4 +40,5 @@ class AnimationHandlerBus : AnimationHandler{ void theaterChase(); void comet(); void nightSky(); + void pixelArray(); }; diff --git a/software/lib/AnimationHandlerBus/Modes/pixelArray.cpp b/software/lib/AnimationHandlerBus/Modes/pixelArray.cpp new file mode 100644 index 0000000..9c7cd59 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/pixelArray.cpp @@ -0,0 +1,10 @@ +#include + +// Renders whatever was last delivered via setPixelData() (see the /pixels +// binary MQTT topic in main.cpp). No animation/timing of its own - just a +// direct copy each tick. +void AnimationHandlerBus::pixelArray(){ + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = CRGB(pixelTargets[i].r, pixelTargets[i].g, pixelTargets[i].b); + } +} diff --git a/software/src/main.cpp b/software/src/main.cpp index 9a6c5d9..dcd4025 100644 --- a/software/src/main.cpp +++ b/software/src/main.cpp @@ -31,6 +31,7 @@ const char* wifi_default_password = WIFI_PASSWORD; char mainTopic[80] = "/ESPLED/"; char debugTopic[80]; +char pixelTopic[90]; //Fingerprint of odroid const char* fingerprint = "A6 AE 85 65 63 DD D8 7C 70 F7 92 73 DE 8F 18 2B 9F DA 0A 76"; @@ -89,6 +90,15 @@ void debugFkt(String message, LogLevel LevelOfMessage){ //WARNING: If received json incomplete, increase MQTT_MAX_PACKET_SIZE in PubSunClient Library void callback(char* topic, byte* payload, unsigned int length) { + if(strcmp(topic, pixelTopic) == 0){ + if(busHandler != nullptr){ + busHandler->setPixelData(payload, length); + }else{ + debugFkt("Received pixel data but no addressable strip handler is active", ERROR); + } + return; + } + for (unsigned int i = 0; i < length; i++) { Serial.print((char)payload[i]); } @@ -148,6 +158,9 @@ void initMQTT() { debugFkt("Will not use SSL -> Standard WifiClient", INFO); } + //grow the receive buffer so a full-strip PIXEL_ARRAY payload (3 bytes/LED) fits + client.setBufferSize(STRIP_LENGTH * 3 + 128); + //set the server and callback function client.setServer(mqtt_server, atoi(mqtt_port)); client.setCallback(callback); @@ -180,17 +193,20 @@ void initMQTT() { //react to outcome of connect try if (connected) { - //setup main Topic and debug topic path in mqtt + //setup main Topic, debug topic and pixel topic path in mqtt strcat(mainTopic, WiFi.macAddress().c_str()); strcat(debugTopic, mainTopic); strcat(debugTopic, "/debug"); + strcpy(pixelTopic, mainTopic); + strcat(pixelTopic, "/pixels"); debugFkt("Now Connected - Main Topic of this device: ", INFO); debugFkt(mainTopic, INFO); debugFkt("-------------", INFO); - //subscribe this device's topic + //subscribe this device's topics client.subscribe(mainTopic); + client.subscribe(pixelTopic); debugFkt("subscribed main Topic ", INFO); From c332dbcb7c4c01962d42f91148b4cf9df0addaee Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 01:50:50 +0200 Subject: [PATCH 06/39] 1 Part D: add Ocean/Forest/Dusk/FireFlicker shared uniform modes 2 3 Four modes that need no color input from the user, only speed, working 4 on both PWM and Bus strips: three fixed-palette gradient loops (Ocean, 5 Forest, Dusk) sharing a new cycleColors() interpolation helper on 6 AnimationHandler, and a whole-strip fire-flicker mode that lerps between 7 random picks from a fixed fire-hued palette. Wired into both 8 AnimationHandlerPWM::handle() and AnimationHandlerBus::getNewColor(). 9 10 Co-Authored-By: Claude Sonnet 5 --- .../lib/AnimationHandler/AnimationHandler.cpp | 23 ++++++++++++ .../lib/AnimationHandler/AnimationHandler.h | 8 +++++ software/lib/AnimationHandler/Modes/dusk.cpp | 12 +++++++ .../AnimationHandler/Modes/fireFlicker.cpp | 36 +++++++++++++++++++ .../lib/AnimationHandler/Modes/forest.cpp | 12 +++++++ software/lib/AnimationHandler/Modes/ocean.cpp | 12 +++++++ .../AnimationHandlerBus.cpp | 8 +++++ .../AnimationHandlerPWM.cpp | 12 +++++++ 8 files changed, 123 insertions(+) create mode 100644 software/lib/AnimationHandler/Modes/dusk.cpp create mode 100644 software/lib/AnimationHandler/Modes/fireFlicker.cpp create mode 100644 software/lib/AnimationHandler/Modes/forest.cpp create mode 100644 software/lib/AnimationHandler/Modes/ocean.cpp diff --git a/software/lib/AnimationHandler/AnimationHandler.cpp b/software/lib/AnimationHandler/AnimationHandler.cpp index cb9cd47..7173400 100644 --- a/software/lib/AnimationHandler/AnimationHandler.cpp +++ b/software/lib/AnimationHandler/AnimationHandler.cpp @@ -79,3 +79,26 @@ void AnimationHandler::recordAudioSample(){ audioRingBuffer[ringBufferCounter++] = analogRead(A0)/1024.0; if(ringBufferCounter == ringBufferSize) ringBufferCounter = 0; } + +CRGBWW AnimationHandler::cycleColors(const CRGBWW colors[], unsigned int count){ + if(silo->time == 0){ + debugFkt("Time was set to 0, this is not possible", ERROR); + return CRGBWW{0,0,0,0,0}; + } + + unsigned long cyclePos = (millis() - lastChange) % silo->time; + float segmentFloat = (float)cyclePos / silo->time * count; + unsigned int segment = (unsigned int)segmentFloat; + float t = segmentFloat - segment; + + const CRGBWW &from = colors[segment % count]; + const CRGBWW &to = colors[(segment + 1) % count]; + + CRGBWW out; + out.R = from.R + (int)(to.R - from.R) * t; + out.G = from.G + (int)(to.G - from.G) * t; + out.B = from.B + (int)(to.B - from.B) * t; + out.WW = from.WW + (int)(to.WW - from.WW) * t; + out.CW = from.CW + (int)(to.CW - from.CW) * t; + return out; +} diff --git a/software/lib/AnimationHandler/AnimationHandler.h b/software/lib/AnimationHandler/AnimationHandler.h index b3f3e1a..3166ae3 100644 --- a/software/lib/AnimationHandler/AnimationHandler.h +++ b/software/lib/AnimationHandler/AnimationHandler.h @@ -18,6 +18,10 @@ class AnimationHandler{ CRGBWW sound2Light(); CRGBWW strobe(); CRGBWW breathe(); + CRGBWW ocean(); + CRGBWW forest(); + CRGBWW dusk(); + CRGBWW fireFlicker(); void rgb2hsv(CRGBWW &rgbContainer, unsigned int hsvContainer[]); void hsv2rgb(unsigned int hsvContainer[], CRGBWW &rgbContainer); @@ -38,6 +42,10 @@ class AnimationHandler{ unsigned int UPDATE_TIME = 16; + // Shared helper for ocean()/forest()/dusk(): loops through the given + // keyframe colors over silo->time ms, linearly interpolating between them. + CRGBWW cycleColors(const CRGBWW colors[], unsigned int count); + }; #endif diff --git a/software/lib/AnimationHandler/Modes/dusk.cpp b/software/lib/AnimationHandler/Modes/dusk.cpp new file mode 100644 index 0000000..c818975 --- /dev/null +++ b/software/lib/AnimationHandler/Modes/dusk.cpp @@ -0,0 +1,12 @@ +#include + +// Continuous gradient loop, no color input needed - only silo->time (speed) +// is tunable. Deep Purple -> Magenta -> Warm Orange -> repeat. +CRGBWW AnimationHandler::dusk(){ + static const CRGBWW colors[3] = { + {250, 0, 450, 0, 0}, // Deep Purple + {650, 0, 500, 0, 0}, // Magenta + {800, 250, 0, 0, 0} // Warm Orange + }; + return cycleColors(colors, 3); +} diff --git a/software/lib/AnimationHandler/Modes/fireFlicker.cpp b/software/lib/AnimationHandler/Modes/fireFlicker.cpp new file mode 100644 index 0000000..96444e9 --- /dev/null +++ b/software/lib/AnimationHandler/Modes/fireFlicker.cpp @@ -0,0 +1,36 @@ +#include +#include + +// Whole-strip fire flicker (uniform color, shared by PWM and Bus). No color +// input needed - only silo->frequency (flicker rate) is tunable. Smoothly +// lerps toward a newly-picked random fire-hued target each pick, for a +// natural flicker instead of a hard strobe. +CRGBWW AnimationHandler::fireFlicker(){ + if(silo->frequency == 0 || silo->frequency > 60){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return CRGBWW{0,0,0,0,0}; + } + + static const CRGBWW palette[4] = { + {700, 20, 0, 0, 0}, + {900, 300, 0, 0, 0}, + {950, 500, 50, 0, 0}, + {1000, 650, 100, 0, 0} + }; + static CRGBWW target = palette[0]; + static CRGBWW current = palette[0]; + static unsigned long lastPick = 0; + + unsigned long now = millis(); + long period = 1000 / silo->frequency; + if(now >= lastPick + period){ + lastPick = now; + target = palette[random8(0, 4)]; + } + + float lerpAmount = 0.15f; // smoothing factor per handle() tick, not per flicker-pick + current.R += (int)(target.R - current.R) * lerpAmount; + current.G += (int)(target.G - current.G) * lerpAmount; + current.B += (int)(target.B - current.B) * lerpAmount; + return current; +} diff --git a/software/lib/AnimationHandler/Modes/forest.cpp b/software/lib/AnimationHandler/Modes/forest.cpp new file mode 100644 index 0000000..f5c4992 --- /dev/null +++ b/software/lib/AnimationHandler/Modes/forest.cpp @@ -0,0 +1,12 @@ +#include + +// Continuous gradient loop, no color input needed - only silo->time (speed) +// is tunable. Emerald Green -> Soft Yellow-Green -> Deep Green -> repeat. +CRGBWW AnimationHandler::forest(){ + static const CRGBWW colors[3] = { + {0, 600, 250, 0, 0}, // Emerald Green + {350, 650, 80, 0, 0}, // Soft Yellow-Green + {0, 250, 40, 0, 0} // Deep Green + }; + return cycleColors(colors, 3); +} diff --git a/software/lib/AnimationHandler/Modes/ocean.cpp b/software/lib/AnimationHandler/Modes/ocean.cpp new file mode 100644 index 0000000..b237bd3 --- /dev/null +++ b/software/lib/AnimationHandler/Modes/ocean.cpp @@ -0,0 +1,12 @@ +#include + +// Continuous gradient loop, no color input needed - only silo->time (speed) +// is tunable. Deep Blue -> Teal -> Cyan -> repeat. +CRGBWW AnimationHandler::ocean(){ + static const CRGBWW colors[3] = { + {0, 10, 500, 0, 0}, // Deep Blue + {0, 350, 350, 0, 0}, // Teal + {0, 700, 800, 0, 0} // Cyan + }; + return cycleColors(colors, 3); +} diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp index c2900ce..08075c0 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp @@ -109,6 +109,14 @@ CRGBWW AnimationHandlerBus::getNewColor(){ return sound2Light(); case BREATHE: return breathe(); + case OCEAN: + return ocean(); + case FOREST: + return forest(); + case DUSK: + return dusk(); + case FIRE_FLICKER: + return fireFlicker(); default: debugFkt("The Selected Mode is not a uniform color mode", ERROR); return CRGBWW{0,0,0,0,0}; diff --git a/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp b/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp index d6045ff..1af517a 100644 --- a/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp +++ b/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp @@ -46,6 +46,18 @@ void AnimationHandlerPWM::handle(){ case BREATHE: strip->showColor(breathe()); break; + case OCEAN: + strip->showColor(ocean()); + break; + case FOREST: + strip->showColor(forest()); + break; + case DUSK: + strip->showColor(dusk()); + break; + case FIRE_FLICKER: + strip->showColor(fireFlicker()); + break; default: debugFkt("The Selected Mode is not possible with RGB/RGBW/RGBWW Strips",ERROR); break; From 3ca17c0bb527a50538dcad4d8e9306c597217755 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:00:01 +0200 Subject: [PATCH 07/39] 1 Part F: split project layout into config/ (tunables) and lib/ (code) 2 3 Move PinDefinitions.h and config.h out of lib/Definitions and include/ 4 into a new top-level config/, split into board_config.h (fixed ESPLED 5 board GPIO wiring, git-tracked) and device_config.h (WiFi/MQTT secrets 6 and strip settings, git-ignored, template in device_config.h.example). 7 lib/Definitions now holds only TypeDefinitions.h - shared type/enum code, 8 not settings. 9 10 Note the settings file is named device_config.h rather than 11 user_config.h: the ESP8266 NONOS SDK's osapi.h does 12 `#include "user_config.h"` to pull in its own framework-level config 13 header, so a project file with that exact name shadows it and breaks 14 the build - discovered by actually building after the rename attempt. 15 16 main.cpp now fails the build with an actionable #error (via 17 __has_include) if device_config.h hasn't been created from the example 18 yet, instead of a bare "file not found". platformio.ini gains 19 `[platformio] include_dir = config` plus an explicit `-Iconfig` build 20 flag, since PlatformIO's per-library dependency finder builds each 21 lib/* file with its own scoped include path and doesn't automatically 22 add include_dir to those - only to src/-level compiles. 23 24 Co-Authored-By: Claude Sonnet 5 --- software/.gitignore | 2 +- software/config/board_config.h | 17 ++++++ software/config/device_config.h.example | 58 +++++++++++++++++++ software/include/README | 39 ------------- software/include/config.example.h | 21 ------- .../lib/AnimationHandler/AnimationHandler.h | 2 +- .../AnimationHandlerBus/AnimationHandlerBus.h | 2 +- software/lib/Definitions/PinDefinitions.h | 14 ----- software/lib/StripControle/StripControle.h | 2 +- software/platformio.ini | 8 +++ software/src/main.cpp | 14 +++-- 11 files changed, 96 insertions(+), 83 deletions(-) create mode 100644 software/config/board_config.h create mode 100644 software/config/device_config.h.example delete mode 100644 software/include/README delete mode 100644 software/include/config.example.h delete mode 100644 software/lib/Definitions/PinDefinitions.h diff --git a/software/.gitignore b/software/.gitignore index 7533fe0..7fa6258 100644 --- a/software/.gitignore +++ b/software/.gitignore @@ -4,4 +4,4 @@ .clang_complete .gcc-flags.json .vscode -include/config.h +config/device_config.h diff --git a/software/config/board_config.h b/software/config/board_config.h new file mode 100644 index 0000000..0891552 --- /dev/null +++ b/software/config/board_config.h @@ -0,0 +1,17 @@ +#ifndef BOARD_CONFIG_H +#define BOARD_CONFIG_H + +// Hardware pin wiring for the ESPLED board itself (ESP12E/ESP8266 GPIOs). +// These are fixed by the PCB/wiring, not user-tunable - do not edit unless +// you're building different hardware. Secrets/network settings live in +// user_config.h instead. +#define pinR 5 +#define pinG 16 +#define pinB 14 +#define pinWW 12 +#define pinCW 13 +#define pinM 2 +#define pinData 5 // Addressable strip data line (WS2812/APA102), shares GPIO with pinR since only one strip type is active at a time +#define pinClock 3 // APA102 clock line only + +#endif diff --git a/software/config/device_config.h.example b/software/config/device_config.h.example new file mode 100644 index 0000000..4bd37a0 --- /dev/null +++ b/software/config/device_config.h.example @@ -0,0 +1,58 @@ +/* + * device_config.h.example — template for software/config/device_config.h + * + * This project splits build-time configuration into two files under config/: + * - board_config.h Fixed hardware pin wiring for the ESPLED board itself. + * Safe to commit; only change it if you're building + * different hardware. + * - device_config.h Your WiFi/MQTT credentials, network topic, TLS + * fingerprint, and which strip you've wired up. + * Git-ignored — never commit this file, it holds + * secrets. + * + * (Deliberately not named "user_config.h": the ESP8266 NONOS SDK's own + * osapi.h does `#include "user_config.h"` to pull in a framework-provided + * SDK-level config header, so a project file with that exact name would + * shadow it and break the build.) + * + * Setup: copy this file to device_config.h (same folder) and fill in your + * real values below. If device_config.h is missing, the build fails with + * an error pointing back here (see the __has_include check in src/main.cpp). + */ +#pragma once + +#include + +#define WIFI_SSID "YourNetwork" +#define WIFI_PASSWORD "YourPassword" + +#define MQTT_SERVER "" +#define MQTT_PORT "8080" +#define MQTT_USERNAME "esp" +#define MQTT_PASSWORD "supersecurepassword" +#define MQTT_SSL "no" + +// Base MQTT topic this device publishes/subscribes under (its MAC address +// is appended at runtime, e.g. "/ESPLED/AA:BB:CC:DD:EE:FF"). +#define MQTT_TOPIC_PREFIX "/ESPLED/" + +// SHA-1 fingerprint of your MQTT broker's TLS certificate, only used when +// MQTT_SSL is "yes". WiFiClientSecure::setFingerprint() pins this exact +// certificate rather than validating a CA chain, so it must be regenerated +// whenever the broker's certificate is renewed/rotated. +// +// To generate it from a server.crt you already have: +// openssl x509 -in server.crt -noout -fingerprint -sha1 +// Or, to fetch the cert directly from a running broker first: +// openssl s_client -connect your.broker.example:8883 -showcerts /dev/null \ +// | openssl x509 -outform PEM > server.crt +// Either way this prints something like: +// SHA1 Fingerprint=A6:AE:85:65:63:DD:D8:7C:70:F7:92:73:DE:8F:18:2B:9F:DA:0A:76 +// Strip the "SHA1 Fingerprint=" prefix and replace the colons with spaces: +#define MQTT_SSL_FINGERPRINT "A6 AE 85 65 63 DD D8 7C 70 F7 92 73 DE 8F 18 2B 9F DA 0A 76" + +// One of: RGB_STRIP, RGBW_STRIP, RGBWW_STRIP, WS2812_STRIP, APA102_STRIP +#define STRIP_TYPE RGB_STRIP + +// Number of LEDs on the strip +#define STRIP_LENGTH 60 diff --git a/software/include/README b/software/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/software/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/software/include/config.example.h b/software/include/config.example.h deleted file mode 100644 index 1180c69..0000000 --- a/software/include/config.example.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copy this file to config.h and fill in real values. -// config.h is gitignored and must never be committed. - -#pragma once - -#include - -#define WIFI_SSID "YourNetwork" -#define WIFI_PASSWORD "YourPassword" - -#define MQTT_SERVER "" -#define MQTT_PORT "8080" -#define MQTT_USERNAME "esp" -#define MQTT_PASSWORD "supersecurepassword" -#define MQTT_SSL "no" - -// One of: RGB_STRIP, RGBW_STRIP, RGBWW_STRIP, WS2812_STRIP, APA102_STRIP -#define STRIP_TYPE RGB_STRIP - -// Number of LEDs on the strip -#define STRIP_LENGTH 60 diff --git a/software/lib/AnimationHandler/AnimationHandler.h b/software/lib/AnimationHandler/AnimationHandler.h index 3166ae3..5074dc9 100644 --- a/software/lib/AnimationHandler/AnimationHandler.h +++ b/software/lib/AnimationHandler/AnimationHandler.h @@ -3,7 +3,7 @@ #include #include -#include +#include #define ringBufferSize 64 diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h index 552a9f2..623a7a6 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/software/lib/Definitions/PinDefinitions.h b/software/lib/Definitions/PinDefinitions.h deleted file mode 100644 index 517ba56..0000000 --- a/software/lib/Definitions/PinDefinitions.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PINDEFINITIONS_H -#define PINDEFINITIONS_H - -//--PinDefines------------------------------------------------------------------ -#define pinR 5 -#define pinG 16 -#define pinB 14 -#define pinWW 12 -#define pinCW 13 -#define pinM 2 -#define pinData 5 //Addressable strip data line (WS2812/APA102), shares GPIO with pinR since only one strip type is active at a time -#define pinClock 3 //APA102 clock line only -//------------------------------------------------------------------------------ -#endif diff --git a/software/lib/StripControle/StripControle.h b/software/lib/StripControle/StripControle.h index cbafaaa..1cb2acd 100644 --- a/software/lib/StripControle/StripControle.h +++ b/software/lib/StripControle/StripControle.h @@ -3,7 +3,7 @@ #include #include -#include +#include class StripControle{ diff --git a/software/platformio.ini b/software/platformio.ini index 8a8bccd..5df1422 100644 --- a/software/platformio.ini +++ b/software/platformio.ini @@ -8,11 +8,19 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html +[platformio] +include_dir = config + [env:esp12e] platform = espressif8266 board = esp12e framework = arduino +; include_dir alone only covers src/-level compiles; lib/* files build with +; their own LDF-scoped include paths, so config/ needs to be added explicitly +; here for board_config.h/user_config.h to resolve from every lib too. +build_flags = -Iconfig + lib_deps = # Using a library name diff --git a/software/src/main.cpp b/software/src/main.cpp index dcd4025..d9bba55 100644 --- a/software/src/main.cpp +++ b/software/src/main.cpp @@ -3,13 +3,18 @@ #include #include #include -#include #include #include #include #include #include -#include + +#if __has_include() + #include +#else + #error "config/device_config.h not found! Copy config/device_config.h.example to config/device_config.h and fill in your WiFi/MQTT settings before building. See config/device_config.h.example for details." +#endif +#include //--Includes-------------------------------------------------------------------- @@ -29,12 +34,11 @@ char mqtt_password[40] = MQTT_PASSWORD; const char* wifi_default_ssid = WIFI_SSID; const char* wifi_default_password = WIFI_PASSWORD; -char mainTopic[80] = "/ESPLED/"; +char mainTopic[80] = MQTT_TOPIC_PREFIX; char debugTopic[80]; char pixelTopic[90]; -//Fingerprint of odroid -const char* fingerprint = "A6 AE 85 65 63 DD D8 7C 70 F7 92 73 DE 8F 18 2B 9F DA 0A 76"; +const char* fingerprint = MQTT_SSL_FINGERPRINT; stripType type = STRIP_TYPE; From 67d016619fb900fc1db2bbbc9dbd9790989d3cac Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:07:14 +0200 Subject: [PATCH 08/39] 1 Docs: rewrite README Modes docs to match actual code, add HTML table 2 3 The Modes table and Example payloads section had drifted far from the 4 real implementation (swapped mode numbers, a fabricated duration field 5 and BLINK_COLOR state machine, modes that don't exist in the enum at 6 all). Rewrite it to describe exactly what's implemented today, 7 including all of Parts A-D's new modes (OCEAN/FOREST/DUSK/FIRE_FLICKER, 8 FIRE/VU_METER/STROBE_PARTS/MOVING_PARTS/RAINBOW_CYCLE/THEATER_CHASE/ 9 COMET/NIGHT_SKY/PIXEL_ARRAY), and fix the parameter-usage table to match. 10 11 Switch the Modes table to raw HTML so each row can hold its full 12 multi-line JSON example directly, rather than splitting a compact 13 one-liner in the table from full examples in a separate section. 14 GitHub's copy-button only attaches to fenced code blocks and can't 15 appear inside a table cell (plain or HTML), so this trades that button 16 away in exchange for one scrollable reference instead of two. PIXEL_ARRAY 17 keeps a real fenced/copyable snippet right after the table since its 18 actual pixel data is a separate binary payload that doesn't fit a 19 single JSON example. 20 21 Also document the Modes/ one-file-per-mode convention and the new 22 config/ vs lib/ layout in DEVNOTES.md. 23 24 Co-Authored-By: Claude Sonnet 5 --- software/DEVNOTES.md | 38 +++++++ software/README.md | 230 +++++++++++++++++++++++-------------------- 2 files changed, 162 insertions(+), 106 deletions(-) diff --git a/software/DEVNOTES.md b/software/DEVNOTES.md index 3fb481b..acab36c 100644 --- a/software/DEVNOTES.md +++ b/software/DEVNOTES.md @@ -33,3 +33,41 @@ else * For Timing-Measurements we use the millis-command * For Accessing the LEDs both AnimationHandlers hold attributes of the Type FastLedEndpoint and StripControleEndpoint which do the lower Level Stuff * All Modes implemented in the AnimationHandlerPWM should also be Implemented in the AnimationHandlerBus +* Uniform-color modes (mode < 100, shared by both handlers) are implemented as `CRGBWW`-returning + methods on the `AnimationHandler` base class. Addressable-only modes (mode >= 100, Bus only) are + implemented as `void` methods on `AnimationHandlerBus` that write directly into its `leds[]` + buffer. Either way, **one file per mode** under that class's `Modes/` folder + (`lib/AnimationHandler/Modes/*.cpp`, `lib/AnimationHandlerBus/Modes/*.cpp`) - never add a new mode + body directly inside `AnimationHandler.cpp`/`AnimationHandlerBus.cpp` themselves, those files are + reserved for the handler's own dispatch/lifecycle code. +* `AnimationHandlerBus::handle()` samples audio into `audioRingBuffer` every tick (via the inherited + `recordAudioSample()`), the same way `AnimationHandlerPWM::handle()` already did - needed for any + addressable audio-reactive mode (`VU_METER`). +* `PIXEL_ARRAY` (mode 109) is the odd one out: its per-LED data doesn't come through `varSilo`/the + JSON control channel at all, since a 500-LED payload is too big for that. It arrives as a raw + binary payload on a separate `/pixels` MQTT topic, handled by + `AnimationHandlerBus::setPixelData()` and rendered by `Modes/pixelArray.cpp`. + +## Project layout: `config/` vs `lib/` +* `config/` holds only things a user needs to tune for their own build: `board_config.h` (fixed + ESPLED board GPIO wiring, git-tracked) and `device_config.h` (WiFi/MQTT secrets + strip settings, + git-ignored, template in `device_config.h.example`). `lib/` holds only code/classes/algorithms - + `lib/Definitions/TypeDefinitions.h` is the one exception living there since it's shared type/enum + code, not a setting. +* The settings file is deliberately **not** called `user_config.h` - the ESP8266 NONOS SDK's own + `osapi.h` does `#include "user_config.h"` to pull in a framework-level config header, so a project + file with that exact name on the include path shadows it and breaks the build. Hence + `device_config.h`. +* `platformio.ini` needs both `[platformio] include_dir = config` *and* an explicit + `build_flags = -Iconfig`: PlatformIO's Library Dependency Finder builds each `lib/*` source with + its own scoped include path and does not automatically add `include_dir` to those, only to + `src/`-level compiles - discovered by building, not just reading the docs. +* `src/main.cpp` guards its `device_config.h` include with `__has_include` so a fresh checkout + fails the build with an actionable message (copy the `.example`) instead of a bare compiler + "file not found". + +## Testing +* No hardware is required to run `pio test -e native` - it exercises the deterministic math each + mode leans on (guards, phase/index math, color interpolation), extracted into hardware-independent + helpers under `lib/ModeMath/`. It does not exercise FastLED rendering, MQTT, or the + inherently-randomized effects' actual appearance - those still need a real strip. diff --git a/software/README.md b/software/README.md index a1484da..4a9e3bc 100644 --- a/software/README.md +++ b/software/README.md @@ -23,13 +23,12 @@ The README historically listed three interfaces (MQTT, REST API, On-Board-Button current firmware only __MQTT__ is actually implemented for runtime control. The on-board "mode" button (`pinM`) is only read once at boot to decide whether to enter configuration mode (see [Configuration](#configuration)) — it is not wired up to change modes while running. No REST -API/webserver for LED control exists in the code; `initWifi()` only starts WiFiManager's setup -portal, which is torn down after Wi-Fi credentials are captured. +API/webserver for LED control exists in the code. ### MQTT The different functions of the controller are available under the following MQTT topic: -*/ESPLED/FF:FF:FF:FF:FF:FF* +*/ESPLED/FF:FF:FF:FF:FF:FF* (replace with MAC of your device, visible in the setup routine) The payload contais json in the following format: @@ -51,104 +50,68 @@ The payload contais json in the following format: Any subset of fields can be sent — only keys present in the JSON payload overwrite the corresponding value; everything else keeps its last value. +Addressable strips also accept a second, binary payload on a dedicated sub-topic +(`*/ESPLED/FF:FF:FF:FF:FF:FF/pixels*`) for the `PIXEL_ARRAY` mode — see mode 109 in the +[Modes](#modes) table below. + | Function | Topic | Values | Used by modes | |--------------------------------------------|--------------------------|---------------------|---------------| | Change Mode | mode | see [Modes](#modes) below | all | -| Color amplitudes | color[ R,G,B,WW,CW ] | 10 bit integer (0-1023) | 0,1,2,4,6,100,101,103 | -| Timeframe in milliseconds (ex. fade time) | time | unsigned integer | 0, 1 (fade legs), 4 (period), 100 | -| Frequency in hertz | frequency | unsigned integer, 1-60 | 2, 101 | -| Relative sensitivity | sensitivity | __unsigned char (0-255)__ — see note | 103 | -| Number of leds (mode specific) | length | unsigned integer | 1 (blink repeat count) | -| Select start led (mode specific) | position | unsigned integer | 103 (render style 0/1/2) | -| Lower brightness bound | minBrightnes | unsigned integer (0-1023) | 4 | -| Upper brightness bound | maxBrightnes | unsigned integer (0-1023) | 4 | +| Color amplitudes | color[ R,G,B,WW,CW ] | 10 bit integer (0-1023) | 0, 2, 4, 100, 102, 103, 104, 105, 107, 108 | +| Timeframe in milliseconds (speed, mode specific) | time | unsigned integer | 0 (fade), 4 (period), 5/6/7 (gradient cycle), 100 (traversal), 105 (traversal), 106 (hue cycle), 107 (step interval), 108 (traversal) | +| Frequency in hertz | frequency | unsigned integer, 1-60 | 2, 8, 101, 102, 103, 104, 110 | +| Relative sensitivity / gain | sensitivity | __unsigned char (0-255)__ — see note | 103 | +| Number of LEDs / max count (mode specific) | length | unsigned integer | 104 (block size), 105 (block size), 110 (max concurrent stars) | +| Select side/anchor (mode specific) | position | unsigned integer | 101 (`0`=start of strip, non-zero=end of strip) | +| Lower brightness bound | minBrightnes | unsigned integer (0-1023) | 4, 110 | +| Upper brightness bound | maxBrightnes | unsigned integer (0-1023) | 4, 110 | | Random jitter on `time` | timeVariance | unsigned integer (ms) | 4 | | Random jitter on `maxBrightnes` | maxBrightnesVariance | unsigned integer | 4 | -| Hold time / recovery probability (mode specific) | duration | unsigned integer | 1 (hold ms), 6 (probability 0-65535) | -> __Note on `sensitivity`:__ the README used to describe this as a `float` (0.0-1.0), and that is how -> `vuMeter()` uses it conceptually (`amplitude * (1 + sensitivity * 0.09)`). However `varSilo.sensitivity` -> is declared as `unsigned char` ([TypeDefinitions.h](/lib/Definitions/TypeDefinitions.h)) and the MQTT -> callback assigns the JSON value to it directly, so any fractional value sent over MQTT is truncated -> to an integer 0-255 before use. Send whole numbers until this is fixed in firmware. +> __Note on `sensitivity`:__ `varSilo.sensitivity` is declared as `unsigned char` +> ([TypeDefinitions.h](/lib/Definitions/TypeDefinitions.h)) and the MQTT callback assigns the JSON +> value to it directly, so send a whole number 0-255, not a fraction. -> __Note on `length` / `position`:__ these are documented generically as "mode specific" and are *not* -> generic strip-geometry controls — `length` is only read by mode 1 (`blinkColor`, as a repeat count) -> and `position` is only read by mode 103 (`vuMeter`, as a layout-style selector). No mode currently -> uses them to mean "number of LEDs" or "start LED index". +> __Note on `length` / `position`:__ these are *not* generic strip-geometry controls that every mode +> understands — each mode that reads them assigns its own meaning (see the table above and the +> per-mode descriptions below). Modes that don't list `length`/`position` ignore them entirely. ### Modes Which modes are available depends on the strip type selected during [configuration](#configuration): - __Uniform strips__ (`RGB`, `RGBW`, `RGBWW`) are driven by `AnimationHandlerPWM` and only support the - *uniform color* modes (0-6). Sending an addressable-only mode (100+) is rejected (logged as an error, + *uniform color* modes (0-8). Sending an addressable-only mode (100+) is rejected (logged as an error, outputs black). - __Addressable strips__ (`WS2812`, `APA102`) are driven by `AnimationHandlerBus` and support both the uniform modes (rendered by filling the whole strip with one calculated color) and the addressable modes (100+, which control individual pixels). -| # | Mode | Strip support | Status | Parameters used | Description | -|---|------|----------------|--------|------------------|--------------| -| 0 | FADE_2_COLOR | uniform + addressable | Implemented | `color`, `time` | Linearly fades every channel from the previous color to `color` over `time` ms, then holds. | -| 1 | BLINK_COLOR | uniform + addressable | Implemented | `color`, `time`, `duration`, `length` | State machine: fades up to `color` over `time`, holds for `duration`, fades back down over `time`, holds off for `duration`, repeating `length` times (a `length` ≤ 1 skips the fade-to-min leg, giving a single blink). After the last cycle it fades back into whatever mode/color was active before this one was triggered (stored in `oldVarSilo`). While mode 1 is already active, a new `mode: 1` MQTT message is ignored/dismissed rather than restarting the sequence (see `callback()` in [initFunctions.h](/src/initFunctions.h)). | -| 2 | STROBE | uniform + addressable | Implemented | `color`, `frequency` | Square-wave toggles the strip between off and `color` at `frequency` Hz. `frequency` of 0 or >60 is rejected (logged as error, outputs black). | -| 3 | SOUND_2_LIGHT | uniform + addressable | Stub only | — | Currently just triggers an FFT calculation and dumps the frequency vector to the debug log every 200ms; does __not__ drive any LED color yet (always returns black). Placeholder for a future audio-reactive uniform mode — mode 103 (`vuMeter`) is the working audio-reactive mode today. | -| 4 | BREATHE | uniform + addressable | Implemented | `color`, `time`, `minBrightnes`, `maxBrightnes`, `timeVariance`, `maxBrightnesVariance` | Cosine "breathing" brightness oscillation of `color` between `minBrightnes` and `maxBrightnes` with period `time`. Each cycle, the period and peak brightness are randomly jittered by ±`timeVariance`/±`maxBrightnesVariance` for a more organic look. Guards: `timeVariance` is reset to 0 if ≥ `time`; `maxBrightnes` and `maxBrightnesVariance` are reset to 1023/0 if their sum would exceed 1023. | -| 5 | TEMPVIS | — | __Reserved, not implemented__ | — | Defined in the `Mode` enum but has no handler function and no `switch` case in either `AnimationHandlerPWM` or `AnimationHandlerBus`. Selecting it logs an error and outputs black. | -| 6 | INDUSTRIAL_FLICKER | uniform + addressable | Implemented | `color`, `duration` | Simulates a failing/flickering light via a random-walk state machine between "flash" (on), "old color" (dim/previous color), and "permanent on". `duration` (0-65535) is the probability threshold that a flicker recovers into another flash rather than settling permanently on `color`; 0 or values above `UINT16_MAX` default to ~43690 (2/3 of the range). | -| 100 | WIPE | addressable only | Implemented | `color`, `time` | Lights the strip LED-by-LED from index 0 to the end over `time` ms total (`time`/stripLength per LED), then holds `color` once fully lit. Does not use `length`/`position`. | -| 101 | NOISE | addressable only | Implemented | `color`, `frequency` | Randomly (50/50 per LED, per refresh) sets each LED to `color` or off, refreshed at `frequency` Hz. `frequency` of 0 or >60 is rejected the same way as mode 2. | -| 102 | FIRE | addressable only | __Reserved, not implemented__ | — | Declared on `AnimationHandlerBus` and has a source file ([fire.cpp](/lib/AnimationHandlerBus/AdressableModes/fire.cpp)), but that file is currently empty and there is no `switch` case for it in `getNewStripBuffer()`. Selecting it logs "mode not implemented" and leaves the strip buffer unchanged. | -| 103 | VU_METER | addressable only | Implemented | `color`, `sensitivity`, `position` | Audio-reactive bar driven by the microphone's average amplitude (scaled by `sensitivity`), plus a slow-decaying red peak-hold pixel. `position` selects the render style: `0` = bar grows from the start of the strip, `1` = symmetric bar growing outward from the center, `2` = bar grows backward from the end of the strip. | -| 104 | STROBE_PARTS | addressable only | __Reserved, not implemented__ | — | Defined in the enum only — no handler function, no `switch` case. | -| 105 | MOVING_PARTS | addressable only | __Reserved, not implemented__ | — | Defined in the enum only — no handler function, no `switch` case. | - -### Example payloads -One MQTT payload to activate each implemented mode, each using a different color so the -effects are easy to tell apart. Modes 5, 102, 104 and 105 are omitted — they are reserved but -not implemented, so there is no meaningful payload for them (any `color`/`time`/etc. sent -alongside them is simply ignored). - -__0 — FADE_2_COLOR__ (amber, 2s fade) -```json -{ +The table below embeds the full JSON for every mode directly in its row (as an HTML table, so the +formatting survives) — one scrollable reference, nothing to jump to further down the page. The +trade-off: GitHub's one-click copy icon only attaches to fenced ``` code blocks, and those can't +live inside a table cell, so these examples aren't individually copy-buttoned — select-and-copy +still works fine. `PIXEL_ARRAY` (109) is the one exception with a real fenced/copyable snippet, +right after the table, since its actual pixel data is a separate binary payload that doesn't fit +a single JSON example. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#ModeStrip supportParameters usedExampleDescription
0FADE_2_COLORuniform + addressablecolor, time
{
   "mode": 0,
   "color": [1023, 400, 60, 0, 0],
   "time": 2000
-}
-```
-
-__1 — BLINK_COLOR__ (cyan, 3 blinks, 300ms fade legs, 400ms hold)
-```json
-{
-  "mode": 1,
-  "color": [0, 700, 1023, 0, 0],
-  "time": 300,
-  "duration": 400,
-  "length": 3
-}
-```
-
-__2 — STROBE__ (magenta, 10 Hz)
-```json
-{
+}
Linearly fades every channel from the previous color to color over time ms, then holds.
1BLINK_COLORuniform + addressable
{ "mode": 1 }
Stub only — the handler is unimplemented and always returns black regardless of parameters.
2STROBEuniform + addressablecolor, frequency
{
   "mode": 2,
   "color": [1023, 0, 850, 0, 0],
   "frequency": 10
-}
-```
-
-__3 — SOUND_2_LIGHT__ (teal — stub only, currently has no visible effect)
-```json
-{
-  "mode": 3,
-  "color": [0, 1023, 650, 0, 0]
-}
-```
-
-__4 — BREATHE__ (violet, 4s base period, brightness 100-900 ±150 jitter)
-```json
-{
+}
Square-wave toggles the strip between off and color at frequency Hz. frequency of 0 or >60 is rejected.
3SOUND_2_LIGHTuniform + addressable
{ "mode": 3 }
Stub only — runs an FFT over the mic ring buffer and logs it every cycle, but always returns black. VU_METER (103) is the working audio-reactive mode today.
4BREATHEuniform + addressablecolor, time, minBrightnes, maxBrightnes, timeVariance, maxBrightnesVariance
{
   "mode": 4,
   "color": [550, 0, 1023, 0, 0],
   "time": 4000,
@@ -156,42 +119,97 @@ __4 — BREATHE__ (violet, 4s base period, brightness 100-900 ±150 jitter)
   "maxBrightnes": 900,
   "timeVariance": 500,
   "maxBrightnesVariance": 100
-}
-```
-
-__6 — INDUSTRIAL_FLICKER__ (warm white, ~2/3 recovery probability)
-```json
-{
+}
Cosine "breathing" brightness oscillation of color between minBrightnes and maxBrightnes with period time, jittered each cycle by ±timeVariancemaxBrightnesVariance.
5OCEANuniform + addressabletime
{
+  "mode": 5,
+  "time": 6000
+}
Fixed gradient loop, no color input: Deep Blue → Teal → Cyan → repeat, one full loop every time ms.
6FORESTuniform + addressabletime
{
   "mode": 6,
-  "color": [900, 500, 100, 300, 0],
-  "duration": 43690
-}
-```
-
-__100 — WIPE__ (green, addressable strips only, 1.5s total wipe)
-```json
-{
+  "time": 6000
+}
Fixed gradient loop, no color input: Emerald Green → Soft Yellow-Green → Deep Green → repeat.
7DUSKuniform + addressabletime
{
+  "mode": 7,
+  "time": 6000
+}
Fixed gradient loop, no color input: Deep Purple → Magenta → Warm Orange → repeat.
8FIRE_FLICKERuniform + addressablefrequency
{
+  "mode": 8,
+  "frequency": 15
+}
Whole-strip flame flicker across a fixed red/orange/yellow palette, no color input. frequency of 0 or >60 is rejected.
100WIPEaddressable onlycolor, time
{
   "mode": 100,
   "color": [50, 1023, 150, 0, 0],
   "time": 1500
-}
-```
-
-__101 — NOISE__ (blue-white sparkle, addressable strips only, 20 Hz refresh)
-```json
-{
+}
Lights the strip LED-by-LED from index 0 to the end over time ms total, then holds color.
101FIREaddressable onlyfrequency, position
{
   "mode": 101,
+  "frequency": 30,
+  "position": 0
+}
Directional flame anchored at one end of the strip — position: 0 = start, non-zero = end. Occasional blue tint near the base and dim smoke near the tip on top of the usual heat-color ramp. No color input.
102NOISEaddressable onlycolor, frequency
{
+  "mode": 102,
   "color": [200, 220, 1023, 0, 0],
   "frequency": 20
-}
-```
-
-__103 — VU_METER__ (red-orange, addressable strips only, high sensitivity, centered bar)
-```json
-{
+}
Randomly (50/50 per LED, per refresh) sets each LED to color or off, refreshed at frequency Hz.
103VU_METERaddressable onlycolor, sensitivity, frequency
{
   "mode": 103,
   "color": [1023, 250, 0, 0, 0],
   "sensitivity": 200,
-  "position": 1
-}
+  "frequency": 30
+}
Audio-reactive bar-graph growing from index 0, based on the mic's rectified average amplitude. sensitivity is the gain, frequency the smoothing/refresh rate.
104STROBE_PARTSaddressable onlycolor, length, frequency
{
+  "mode": 104,
+  "color": [1023, 0, 0, 0, 0],
+  "length": 5,
+  "frequency": 4
+}
Strip divided into length-LED blocks; all blocks invert together (checkerboard flip) at frequency Hz.
105MOVING_PARTSaddressable onlycolor, length, time
{
+  "mode": 105,
+  "color": [0, 1023, 0, 0, 0],
+  "length": 8,
+  "time": 2000
+}
A solid length-LED block sweeps the strip once every time ms, wrapping around at the end.
106RAINBOW_CYCLEaddressable onlytime
{
+  "mode": 106,
+  "time": 4000
+}
Continuous hue-shift across the whole strip; one full rainbow cycle every time ms.
107THEATER_CHASEaddressable onlycolor, time
{
+  "mode": 107,
+  "color": [1023, 1023, 1023, 0, 0],
+  "time": 100
+}
Classic marquee/theater chase (fixed spacing of 3), shifting one step every time ms.
108COMETaddressable onlycolor, time
{
+  "mode": 108,
+  "color": [0, 600, 1023, 0, 0],
+  "time": 1500
+}
Bright head pixel with a fading trail travels the strip once every time ms, wrapping at the end.
109PIXEL_ARRAYaddressable only— (see below)
{ "mode": 109 }
Renders whatever per-LED RGB array was last delivered via the binary /pixels sub-topic — not controlled by color/time/etc. See below.
110NIGHT_SKYaddressable onlylength, frequency, minBrightnes, maxBrightnes
{
+  "mode": 110,
+  "length": 6,
+  "frequency": 20,
+  "minBrightnes": 100,
+  "maxBrightnes": 800
+}
Up to length stars twinkle at once, refreshed at frequency Hz, each spawned with a random brightness between minBrightnes and maxBrightnes.
+ +#### 109 — PIXEL_ARRAY, sending the actual pixel data +Switch into the mode with the JSON message from the table above on the main topic, then publish +the actual per-LED colors as a raw binary payload — 3 bytes per LED (`R,G,B`, each 0-255, no +WW/CW), in strip order, on `/pixels`. The payload length must be exactly +`stripLength * 3` bytes or it's rejected outright (logged as an error, strip unchanged) rather than +partially applied. Example for a 60-LED strip, lighting only LEDs 10-14 red and leaving the rest +off, using Python to build the payload and `mosquitto_pub` to send it: +```python +strip_length = 60 +payload = bytearray(strip_length * 3) +for led in range(10, 15): + payload[led * 3 : led * 3 + 3] = bytes([255, 0, 0]) # R, G, B + +with open("pixels.bin", "wb") as f: + f.write(payload) +``` +```sh +mosquitto_pub -h -t "/ESPLED//pixels" -f pixels.bin ``` From ac9654f38ded79c96063edca22dd97a986266745 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:13:00 +0200 Subject: [PATCH 09/39] 1 Part E: extract ModeMath helpers, add native unit tests 2 3 Pull the deterministic math several modes lean on (rate/length guards, 4 directional index mapping, traveling-head position, keyframe-color 5 interpolation) into plain functions under lib/ModeMath - zero Arduino/ 6 FastLED dependency, so they build and test on the host with no hardware. 7 fire/vuMeter/strobeParts/movingParts/comet/nightSky/noise/strobe/ 8 fireFlicker/cycleColors now call these instead of inlining the same 9 logic six times over; behavior is unchanged. 10 11 Add a [env:native] PlatformIO environment and Unity tests in 12 software/test/test_modemath covering guard boundaries, both directions 13 of the index mapping across a few strip lengths (including 500), 14 wrap-at-exact-period behavior, and the ocean() keyframes' interpolated 15 colors at each segment midpoint - all hand-computed and verified against 16 the implementation (`pio test -e native`, 22/22 passing). 17 18 This intentionally doesn't cover FastLED rendering, MQTT, or the 19 inherently-randomized effects' actual appearance - those still need a 20 real strip once hardware is available. 21 22 Co-Authored-By: Claude Sonnet 5 --- .../lib/AnimationHandler/AnimationHandler.cpp | 17 +- .../AnimationHandler/Modes/fireFlicker.cpp | 3 +- .../lib/AnimationHandler/Modes/strobe.cpp | 3 +- .../lib/AnimationHandlerBus/Modes/comet.cpp | 4 +- .../lib/AnimationHandlerBus/Modes/fire.cpp | 5 +- .../AnimationHandlerBus/Modes/movingParts.cpp | 6 +- .../AnimationHandlerBus/Modes/nightSky.cpp | 5 +- .../lib/AnimationHandlerBus/Modes/noise.cpp | 3 +- .../AnimationHandlerBus/Modes/strobeParts.cpp | 5 +- .../lib/AnimationHandlerBus/Modes/vuMeter.cpp | 3 +- software/lib/ModeMath/ModeMath.cpp | 40 ++++ software/lib/ModeMath/ModeMath.h | 33 ++++ software/platformio.ini | 6 + software/test/test_modemath/test_modemath.cpp | 171 ++++++++++++++++++ 14 files changed, 274 insertions(+), 30 deletions(-) create mode 100644 software/lib/ModeMath/ModeMath.cpp create mode 100644 software/lib/ModeMath/ModeMath.h create mode 100644 software/test/test_modemath/test_modemath.cpp diff --git a/software/lib/AnimationHandler/AnimationHandler.cpp b/software/lib/AnimationHandler/AnimationHandler.cpp index 7173400..c95de22 100644 --- a/software/lib/AnimationHandler/AnimationHandler.cpp +++ b/software/lib/AnimationHandler/AnimationHandler.cpp @@ -1,4 +1,5 @@ #include +#include AnimationHandler::AnimationHandler(varSilo* silo, bool* varSiloChanged){ this->silo = silo; @@ -86,19 +87,5 @@ CRGBWW AnimationHandler::cycleColors(const CRGBWW colors[], unsigned int count){ return CRGBWW{0,0,0,0,0}; } - unsigned long cyclePos = (millis() - lastChange) % silo->time; - float segmentFloat = (float)cyclePos / silo->time * count; - unsigned int segment = (unsigned int)segmentFloat; - float t = segmentFloat - segment; - - const CRGBWW &from = colors[segment % count]; - const CRGBWW &to = colors[(segment + 1) % count]; - - CRGBWW out; - out.R = from.R + (int)(to.R - from.R) * t; - out.G = from.G + (int)(to.G - from.G) * t; - out.B = from.B + (int)(to.B - from.B) * t; - out.WW = from.WW + (int)(to.WW - from.WW) * t; - out.CW = from.CW + (int)(to.CW - from.CW) * t; - return out; + return interpolateCycle(colors, count, millis() - lastChange, silo->time); } diff --git a/software/lib/AnimationHandler/Modes/fireFlicker.cpp b/software/lib/AnimationHandler/Modes/fireFlicker.cpp index 96444e9..3989791 100644 --- a/software/lib/AnimationHandler/Modes/fireFlicker.cpp +++ b/software/lib/AnimationHandler/Modes/fireFlicker.cpp @@ -1,12 +1,13 @@ #include #include +#include // Whole-strip fire flicker (uniform color, shared by PWM and Bus). No color // input needed - only silo->frequency (flicker rate) is tunable. Smoothly // lerps toward a newly-picked random fire-hued target each pick, for a // natural flicker instead of a hard strobe. CRGBWW AnimationHandler::fireFlicker(){ - if(silo->frequency == 0 || silo->frequency > 60){ + if(!isValidRateHz(silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return CRGBWW{0,0,0,0,0}; } diff --git a/software/lib/AnimationHandler/Modes/strobe.cpp b/software/lib/AnimationHandler/Modes/strobe.cpp index 6765002..4d07137 100644 --- a/software/lib/AnimationHandler/Modes/strobe.cpp +++ b/software/lib/AnimationHandler/Modes/strobe.cpp @@ -1,9 +1,10 @@ #include +#include CRGBWW AnimationHandler::strobe(){ debugFkt("Called strobe mode function", VERBOSE); - if(this->silo->frequency == 0 || this->silo->frequency > 60){ + if(!isValidRateHz(this->silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return CRGBWW{0,0,0,0,0}; } diff --git a/software/lib/AnimationHandlerBus/Modes/comet.cpp b/software/lib/AnimationHandlerBus/Modes/comet.cpp index 4a040ff..ee45199 100644 --- a/software/lib/AnimationHandlerBus/Modes/comet.cpp +++ b/software/lib/AnimationHandlerBus/Modes/comet.cpp @@ -1,4 +1,5 @@ #include +#include // Bright head pixel with a fading trail, traveling along the strip and // wrapping at the end. Position is derived from (now - lastChange), same @@ -20,8 +21,7 @@ void AnimationHandlerBus::comet(){ fill_solid(this->leds, this->stripLength, CRGB::Black); } - unsigned long elapsed = (now - this->lastChange) % this->silo->time; - unsigned int headPos = (unsigned int)(elapsed * this->stripLength / this->silo->time); + unsigned int headPos = headPositionFor(now - this->lastChange, this->silo->time, this->stripLength); fadeToBlackBy(this->leds, this->stripLength, FADE_AMOUNT); this->leds[headPos] = color; diff --git a/software/lib/AnimationHandlerBus/Modes/fire.cpp b/software/lib/AnimationHandlerBus/Modes/fire.cpp index 6b1a652..28d4383 100644 --- a/software/lib/AnimationHandlerBus/Modes/fire.cpp +++ b/software/lib/AnimationHandlerBus/Modes/fire.cpp @@ -1,4 +1,5 @@ #include +#include // Directional single-end flame: logical index 0 is always "the base" (closest // to the fire's origin); silo->position selects which physical end that maps @@ -6,7 +7,7 @@ // (cool -> diffuse -> spark), with an occasional blue tint at the base and // occasional dim smoke near the tip layered on top of the usual HeatColor(). void AnimationHandlerBus::fire(){ - if(this->silo->frequency == 0 || this->silo->frequency > 60){ + if(!isValidRateHz(this->silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return; } @@ -65,7 +66,7 @@ void AnimationHandlerBus::fire(){ color = HeatColor(h); } - unsigned int physicalIndex = reversed ? (this->stripLength - 1 - logicalIndex) : logicalIndex; + unsigned int physicalIndex = mapLogicalToPhysical(logicalIndex, this->stripLength, reversed); this->leds[physicalIndex] = color; } } diff --git a/software/lib/AnimationHandlerBus/Modes/movingParts.cpp b/software/lib/AnimationHandlerBus/Modes/movingParts.cpp index b2fdc51..bb73cfb 100644 --- a/software/lib/AnimationHandlerBus/Modes/movingParts.cpp +++ b/software/lib/AnimationHandlerBus/Modes/movingParts.cpp @@ -1,4 +1,5 @@ #include +#include // A single hard-edged solid block of silo->length LEDs translates along the // strip and wraps around at the end. silo->time is the ms for one full-strip @@ -6,7 +7,7 @@ // frame from (now - lastChange) rather than stored, so it self-restarts // whenever the mode/params change. void AnimationHandlerBus::movingParts(){ - if(this->silo->length == 0 || this->silo->length > this->stripLength){ + if(!isValidBlockLength(this->silo->length, this->stripLength)){ debugFkt("Length was set to 0 or larger than the strip, this is not possible", ERROR); return; } @@ -22,8 +23,7 @@ void AnimationHandlerBus::movingParts(){ color = CRGBWW2FastLedCRGB(silo->colorValue); } - unsigned long elapsed = (now - this->lastChange) % this->silo->time; - unsigned int headPos = (unsigned int)(elapsed * this->stripLength / this->silo->time); + unsigned int headPos = headPositionFor(now - this->lastChange, this->silo->time, this->stripLength); for(unsigned int i = 0; i < this->stripLength; i++){ this->leds[i] = CRGB::Black; diff --git a/software/lib/AnimationHandlerBus/Modes/nightSky.cpp b/software/lib/AnimationHandlerBus/Modes/nightSky.cpp index 61c2625..bcc52b0 100644 --- a/software/lib/AnimationHandlerBus/Modes/nightSky.cpp +++ b/software/lib/AnimationHandlerBus/Modes/nightSky.cpp @@ -1,15 +1,16 @@ #include +#include // Stars sparkle at tunable positions, count, brightness and frequency. // silo->length caps the number of concurrently active stars; silo-> // minBrightnes/maxBrightnes bound the brightness newly-spawned stars are // randomly assigned within, matching how breathe() already uses that pair. void AnimationHandlerBus::nightSky(){ - if(this->silo->frequency == 0 || this->silo->frequency > 60){ + if(!isValidRateHz(this->silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return; } - if(this->silo->length == 0 || this->silo->length > this->stripLength){ + if(!isValidBlockLength(this->silo->length, this->stripLength)){ debugFkt("Length was set to 0 or larger than the strip, this is not possible", ERROR); return; } diff --git a/software/lib/AnimationHandlerBus/Modes/noise.cpp b/software/lib/AnimationHandlerBus/Modes/noise.cpp index 2739c2d..1742f6f 100644 --- a/software/lib/AnimationHandlerBus/Modes/noise.cpp +++ b/software/lib/AnimationHandlerBus/Modes/noise.cpp @@ -1,7 +1,8 @@ #include +#include void AnimationHandlerBus::noise(){ - if(this->silo->frequency == 0 || this->silo->frequency > 60){ + if(!isValidRateHz(this->silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return; } diff --git a/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp b/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp index d74ca25..8a1d1cd 100644 --- a/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp +++ b/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp @@ -1,15 +1,16 @@ #include +#include // Alternating-block checkerboard strobe: the strip is divided into blocks of // silo->length LEDs; on each tick every block inverts together (even blocks // lit / odd blocks off, then swapped). Distinct from the uniform strobe() // (mode < 100), which flashes the whole strip at once. void AnimationHandlerBus::strobeParts(){ - if(this->silo->frequency == 0 || this->silo->frequency > 60){ + if(!isValidRateHz(this->silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return; } - if(this->silo->length == 0 || this->silo->length > this->stripLength){ + if(!isValidBlockLength(this->silo->length, this->stripLength)){ debugFkt("Length was set to 0 or larger than the strip, this is not possible", ERROR); return; } diff --git a/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp b/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp index f1471b5..2023e04 100644 --- a/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp +++ b/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp @@ -1,11 +1,12 @@ #include +#include // Simple rectified-amplitude envelope bar-graph (not FFT/spectrum - cheaper // on the ESP8266, and a mono mic doesn't justify a per-band spectrum on a // short strip). Depends on AnimationHandlerBus::handle() sampling audio into // audioRingBuffer every tick. void AnimationHandlerBus::vuMeter(){ - if(this->silo->frequency == 0 || this->silo->frequency > 60){ + if(!isValidRateHz(this->silo->frequency)){ debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); return; } diff --git a/software/lib/ModeMath/ModeMath.cpp b/software/lib/ModeMath/ModeMath.cpp new file mode 100644 index 0000000..bbbbbc4 --- /dev/null +++ b/software/lib/ModeMath/ModeMath.cpp @@ -0,0 +1,40 @@ +#include + +bool isValidRateHz(unsigned int frequency){ + return frequency != 0 && frequency <= 60; +} + +bool isValidBlockLength(unsigned int length, unsigned int stripLength){ + return length != 0 && length <= stripLength; +} + +unsigned int mapLogicalToPhysical(unsigned int logicalIndex, unsigned int stripLength, bool reversed){ + if(!reversed) return logicalIndex; + return stripLength - 1 - logicalIndex; +} + +unsigned int headPositionFor(unsigned long elapsedMs, unsigned long periodMs, unsigned int stripLength){ + if(periodMs == 0) return 0; + unsigned long phase = elapsedMs % periodMs; + return (unsigned int)(phase * stripLength / periodMs); +} + +CRGBWW interpolateCycle(const CRGBWW colors[], unsigned int count, unsigned long elapsedMs, unsigned long periodMs){ + if(periodMs == 0 || count == 0) return CRGBWW{0,0,0,0,0}; + + unsigned long cyclePos = elapsedMs % periodMs; + float segmentFloat = (float)cyclePos / periodMs * count; + unsigned int segment = (unsigned int)segmentFloat; + float t = segmentFloat - segment; + + const CRGBWW &from = colors[segment % count]; + const CRGBWW &to = colors[(segment + 1) % count]; + + CRGBWW out; + out.R = from.R + (int)(to.R - from.R) * t; + out.G = from.G + (int)(to.G - from.G) * t; + out.B = from.B + (int)(to.B - from.B) * t; + out.WW = from.WW + (int)(to.WW - from.WW) * t; + out.CW = from.CW + (int)(to.CW - from.CW) * t; + return out; +} diff --git a/software/lib/ModeMath/ModeMath.h b/software/lib/ModeMath/ModeMath.h new file mode 100644 index 0000000..7159c8a --- /dev/null +++ b/software/lib/ModeMath/ModeMath.h @@ -0,0 +1,33 @@ +#ifndef MODEMATH_H +#define MODEMATH_H + +#include + +// Pure, hardware-independent helpers shared by multiple AnimationHandler/ +// AnimationHandlerBus modes. No Arduino/FastLED dependency - safe to build +// and unit-test on the host (see software/test/test_modemath). + +// The "0 or >60 Hz" guard used by every rate-based mode (noise, strobe, +// strobeParts, fire, nightSky, fireFlicker). +bool isValidRateHz(unsigned int frequency); + +// The "0 or larger than the strip" guard used by block-sized modes +// (strobeParts, movingParts, nightSky). +bool isValidBlockLength(unsigned int length, unsigned int stripLength); + +// Maps a logical index (0 = the "base"/anchor point) to a physical LED +// index, optionally reversing direction. Used by fire()'s directional +// heat-to-pixel mapping. +unsigned int mapLogicalToPhysical(unsigned int logicalIndex, unsigned int stripLength, bool reversed); + +// Position of a traveling head/block within [0, stripLength), given how far +// into the current periodMs-long cycle elapsedMs is. Used by movingParts()/ +// comet() to derive position from elapsed time instead of storing it. +unsigned int headPositionFor(unsigned long elapsedMs, unsigned long periodMs, unsigned int stripLength); + +// Loops through the given keyframe colors over periodMs, linearly +// interpolating between them based on how far into the cycle elapsedMs is. +// Used by AnimationHandler::cycleColors() (ocean/forest/dusk). +CRGBWW interpolateCycle(const CRGBWW colors[], unsigned int count, unsigned long elapsedMs, unsigned long periodMs); + +#endif diff --git a/software/platformio.ini b/software/platformio.ini index 5df1422..f9a084a 100644 --- a/software/platformio.ini +++ b/software/platformio.ini @@ -38,3 +38,9 @@ upload_speed = 115200 monitor_speed = 115200 monitor_port = /dev/cu.usbserial-141420 + +; Native (host-machine) environment for pio test - runs the pure ModeMath +; helpers' unit tests without any ESP8266 hardware or toolchain. Does not +; build src/main.cpp (Arduino-only) or the FastLED-dependent libs. +[env:native] +platform = native diff --git a/software/test/test_modemath/test_modemath.cpp b/software/test/test_modemath/test_modemath.cpp new file mode 100644 index 0000000..eed3cb1 --- /dev/null +++ b/software/test/test_modemath/test_modemath.cpp @@ -0,0 +1,171 @@ +#include +#include + +void setUp(void) {} +void tearDown(void) {} + +// ---- isValidRateHz ---- + +void test_isValidRateHz_zero_is_invalid(void){ + TEST_ASSERT_FALSE(isValidRateHz(0)); +} + +void test_isValidRateHz_one_is_valid(void){ + TEST_ASSERT_TRUE(isValidRateHz(1)); +} + +void test_isValidRateHz_sixty_is_valid(void){ + TEST_ASSERT_TRUE(isValidRateHz(60)); +} + +void test_isValidRateHz_sixtyone_is_invalid(void){ + TEST_ASSERT_FALSE(isValidRateHz(61)); +} + +// ---- isValidBlockLength ---- + +void test_isValidBlockLength_zero_is_invalid(void){ + TEST_ASSERT_FALSE(isValidBlockLength(0, 60)); +} + +void test_isValidBlockLength_one_is_valid(void){ + TEST_ASSERT_TRUE(isValidBlockLength(1, 60)); +} + +void test_isValidBlockLength_exactly_stripLength_is_valid(void){ + TEST_ASSERT_TRUE(isValidBlockLength(60, 60)); +} + +void test_isValidBlockLength_stripLength_plus_one_is_invalid(void){ + TEST_ASSERT_FALSE(isValidBlockLength(61, 60)); +} + +// ---- mapLogicalToPhysical ---- + +void test_mapLogicalToPhysical_not_reversed_is_identity(void){ + TEST_ASSERT_EQUAL_UINT(0, mapLogicalToPhysical(0, 60, false)); + TEST_ASSERT_EQUAL_UINT(59, mapLogicalToPhysical(59, 60, false)); + TEST_ASSERT_EQUAL_UINT(30, mapLogicalToPhysical(30, 60, false)); +} + +void test_mapLogicalToPhysical_reversed_even_stripLength(void){ + TEST_ASSERT_EQUAL_UINT(59, mapLogicalToPhysical(0, 60, true)); + TEST_ASSERT_EQUAL_UINT(0, mapLogicalToPhysical(59, 60, true)); + TEST_ASSERT_EQUAL_UINT(29, mapLogicalToPhysical(30, 60, true)); +} + +void test_mapLogicalToPhysical_reversed_odd_stripLength(void){ + TEST_ASSERT_EQUAL_UINT(60, mapLogicalToPhysical(0, 61, true)); + TEST_ASSERT_EQUAL_UINT(0, mapLogicalToPhysical(60, 61, true)); + TEST_ASSERT_EQUAL_UINT(30, mapLogicalToPhysical(30, 61, true)); +} + +void test_mapLogicalToPhysical_reversed_500_leds(void){ + TEST_ASSERT_EQUAL_UINT(499, mapLogicalToPhysical(0, 500, true)); + TEST_ASSERT_EQUAL_UINT(0, mapLogicalToPhysical(499, 500, true)); + TEST_ASSERT_EQUAL_UINT(250, mapLogicalToPhysical(250, 500, false)); +} + +// ---- headPositionFor ---- + +void test_headPositionFor_start_of_cycle(void){ + TEST_ASSERT_EQUAL_UINT(0, headPositionFor(0, 1000, 100)); +} + +void test_headPositionFor_mid_cycle(void){ + TEST_ASSERT_EQUAL_UINT(50, headPositionFor(500, 1000, 100)); +} + +void test_headPositionFor_near_end_of_cycle(void){ + TEST_ASSERT_EQUAL_UINT(99, headPositionFor(999, 1000, 100)); +} + +void test_headPositionFor_wraps_exactly_at_period(void){ + // elapsed == period must wrap back to phase 0, not run off the end + TEST_ASSERT_EQUAL_UINT(0, headPositionFor(1000, 1000, 100)); + TEST_ASSERT_EQUAL_UINT(50, headPositionFor(1500, 1000, 100)); +} + +void test_headPositionFor_stripLength_not_a_multiple_of_period(void){ + TEST_ASSERT_EQUAL_UINT(30, headPositionFor(500, 1000, 60)); + TEST_ASSERT_EQUAL_UINT(59, headPositionFor(999, 1000, 60)); + TEST_ASSERT_EQUAL_UINT(0, headPositionFor(16, 1000, 60)); +} + +// ---- interpolateCycle ---- +// Uses the exact same keyframes as AnimationHandler::ocean() (Deep Blue -> +// Teal -> Cyan), period split into 3 equal 1000ms segments (period=3000). + +static const CRGBWW oceanColors[3] = { + {0, 10, 500, 0, 0}, // Deep Blue + {0, 350, 350, 0, 0}, // Teal + {0, 700, 800, 0, 0} // Cyan +}; + +void test_interpolateCycle_phase_zero_is_first_keyframe_exactly(void){ + CRGBWW out = interpolateCycle(oceanColors, 3, 0, 3000); + TEST_ASSERT_EQUAL_UINT(0, out.R); + TEST_ASSERT_EQUAL_UINT(10, out.G); + TEST_ASSERT_EQUAL_UINT(500, out.B); +} + +void test_interpolateCycle_wraps_exactly_at_period(void){ + CRGBWW out = interpolateCycle(oceanColors, 3, 3000, 3000); + TEST_ASSERT_EQUAL_UINT(0, out.R); + TEST_ASSERT_EQUAL_UINT(10, out.G); + TEST_ASSERT_EQUAL_UINT(500, out.B); +} + +void test_interpolateCycle_midpoint_segment0_deepblue_to_teal(void){ + CRGBWW out = interpolateCycle(oceanColors, 3, 500, 3000); + TEST_ASSERT_EQUAL_UINT(0, out.R); + TEST_ASSERT_EQUAL_UINT(180, out.G); + TEST_ASSERT_EQUAL_UINT(425, out.B); +} + +void test_interpolateCycle_midpoint_segment1_teal_to_cyan(void){ + CRGBWW out = interpolateCycle(oceanColors, 3, 1500, 3000); + TEST_ASSERT_EQUAL_UINT(0, out.R); + TEST_ASSERT_EQUAL_UINT(525, out.G); + TEST_ASSERT_EQUAL_UINT(575, out.B); +} + +void test_interpolateCycle_midpoint_segment2_cyan_to_deepblue_wraparound(void){ + CRGBWW out = interpolateCycle(oceanColors, 3, 2500, 3000); + TEST_ASSERT_EQUAL_UINT(0, out.R); + TEST_ASSERT_EQUAL_UINT(355, out.G); + TEST_ASSERT_EQUAL_UINT(650, out.B); +} + +int main(int argc, char **argv){ + UNITY_BEGIN(); + + RUN_TEST(test_isValidRateHz_zero_is_invalid); + RUN_TEST(test_isValidRateHz_one_is_valid); + RUN_TEST(test_isValidRateHz_sixty_is_valid); + RUN_TEST(test_isValidRateHz_sixtyone_is_invalid); + + RUN_TEST(test_isValidBlockLength_zero_is_invalid); + RUN_TEST(test_isValidBlockLength_one_is_valid); + RUN_TEST(test_isValidBlockLength_exactly_stripLength_is_valid); + RUN_TEST(test_isValidBlockLength_stripLength_plus_one_is_invalid); + + RUN_TEST(test_mapLogicalToPhysical_not_reversed_is_identity); + RUN_TEST(test_mapLogicalToPhysical_reversed_even_stripLength); + RUN_TEST(test_mapLogicalToPhysical_reversed_odd_stripLength); + RUN_TEST(test_mapLogicalToPhysical_reversed_500_leds); + + RUN_TEST(test_headPositionFor_start_of_cycle); + RUN_TEST(test_headPositionFor_mid_cycle); + RUN_TEST(test_headPositionFor_near_end_of_cycle); + RUN_TEST(test_headPositionFor_wraps_exactly_at_period); + RUN_TEST(test_headPositionFor_stripLength_not_a_multiple_of_period); + + RUN_TEST(test_interpolateCycle_phase_zero_is_first_keyframe_exactly); + RUN_TEST(test_interpolateCycle_wraps_exactly_at_period); + RUN_TEST(test_interpolateCycle_midpoint_segment0_deepblue_to_teal); + RUN_TEST(test_interpolateCycle_midpoint_segment1_teal_to_cyan); + RUN_TEST(test_interpolateCycle_midpoint_segment2_cyan_to_deepblue_wraparound); + + return UNITY_END(); +} From 6f2c96a4dc19c877aaf179038b04f4f17db55541 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:21:21 +0200 Subject: [PATCH 10/39] 1 Part G: track the MAX4466's DC bias instead of assuming 0.5 2 3 Confirmed via the schematic (hardware/ESPLED.net) that the MIC header 4 (J4) wires directly to the ESP module's ADC pin (U2 pin 2 = A0) - the 5 existing analogRead(A0) path was already reading the right pin, it just 6 assumed the mic's silence point sits at exactly 0.5 on the normalized 7 0-1 scale. A MAX4466 centers its output around VCC/2, but the exact 8 point drifts with its onboard trimmer and component tolerance, so track 9 it instead: a slow (0.1%/sample) exponential moving average in 10 recordAudioSample(), used by vuMeter() in place of the hardcoded 0.5f. 11 12 No separate HAS_MAX4466 compile flag: there's nothing to gate - A0 is a 13 fixed ADC pin either way, and the bias tracker degrades harmlessly 14 (settles on whatever floating/noise A0 reads) if no mic is populated. 15 16 Co-Authored-By: Claude Sonnet 5 --- software/lib/AnimationHandler/AnimationHandler.cpp | 8 +++++++- software/lib/AnimationHandler/AnimationHandler.h | 8 ++++++++ software/lib/AnimationHandlerBus/Modes/vuMeter.cpp | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/software/lib/AnimationHandler/AnimationHandler.cpp b/software/lib/AnimationHandler/AnimationHandler.cpp index c95de22..f23a501 100644 --- a/software/lib/AnimationHandler/AnimationHandler.cpp +++ b/software/lib/AnimationHandler/AnimationHandler.cpp @@ -77,8 +77,14 @@ void AnimationHandler::hsv2rgb(unsigned int hsvContainer[], CRGBWW &rgbContainer } void AnimationHandler::recordAudioSample(){ - audioRingBuffer[ringBufferCounter++] = analogRead(A0)/1024.0; + float sample = analogRead(A0)/1024.0; + audioRingBuffer[ringBufferCounter++] = sample; if(ringBufferCounter == ringBufferSize) ringBufferCounter = 0; + + // Exponential moving average, deliberately slow (0.1% per sample) so + // it tracks the mic's silence bias point without following the audio + // signal itself. + audioBias = audioBias * 0.999f + sample * 0.001f; } CRGBWW AnimationHandler::cycleColors(const CRGBWW colors[], unsigned int count){ diff --git a/software/lib/AnimationHandler/AnimationHandler.h b/software/lib/AnimationHandler/AnimationHandler.h index 5074dc9..30c5166 100644 --- a/software/lib/AnimationHandler/AnimationHandler.h +++ b/software/lib/AnimationHandler/AnimationHandler.h @@ -22,6 +22,7 @@ class AnimationHandler{ CRGBWW forest(); CRGBWW dusk(); CRGBWW fireFlicker(); + CRGBWW bassReact(); void rgb2hsv(CRGBWW &rgbContainer, unsigned int hsvContainer[]); void hsv2rgb(unsigned int hsvContainer[], CRGBWW &rgbContainer); @@ -40,6 +41,13 @@ class AnimationHandler{ float audioRingBuffer[ringBufferSize]; unsigned int ringBufferCounter = 0; + // Slow-moving estimate of the mic's silence/DC bias point (a MAX4466 + // centers its output around VCC/2, i.e. ~0.5 on this 0-1 scale, but the + // exact point drifts with its onboard trimmer and component tolerance). + // Tracked in recordAudioSample(); audio-reactive modes should measure + // deviation from this instead of a hardcoded 0.5. + float audioBias = 0.5f; + unsigned int UPDATE_TIME = 16; // Shared helper for ocean()/forest()/dusk(): loops through the given diff --git a/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp b/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp index 2023e04..3e7be1d 100644 --- a/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp +++ b/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp @@ -26,7 +26,7 @@ void AnimationHandlerBus::vuMeter(){ float sumAbs = 0.0f; for(unsigned int i = 0; i < ringBufferSize; i++){ - sumAbs += fabsf(audioRingBuffer[i] - 0.5f); + sumAbs += fabsf(audioRingBuffer[i] - this->audioBias); } float rawAmplitude = sumAbs / ringBufferSize; float gain = 1.0f + (this->silo->sensitivity / 255.0f) * 4.0f; From b3fefe854656bfe4d8ceba320660cb9b75ece109 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:24:06 +0200 Subject: [PATCH 11/39] 1 Part H: add BASS_REACT and VU_METER_PEAK modes 2 3 BASS_REACT (shared, PWM+Bus, mode 9): scales colorValue's brightness by 4 a bass envelope extracted from the audio ring buffer via a one-pole 5 low-pass filter (rejects mid/treble wiggle), same FFT-avoidance 6 rationale as vuMeter(). Tunable via sensitivity (gain) and frequency 7 (update rate). 8 9 VU_METER_PEAK (addressable-only, mode 111): vuMeter()'s bar-graph body 10 plus a white peak-hold LED that jumps to the highest recent level and 11 decays back down at a fixed rate - classic VU-meter behavior, sibling 12 to the plain VU_METER rather than a replacement. 13 14 Co-Authored-By: Claude Sonnet 5 --- .../lib/AnimationHandler/Modes/bassReact.cpp | 55 ++++++++++++++++ .../AnimationHandlerBus.cpp | 5 ++ .../AnimationHandlerBus/AnimationHandlerBus.h | 1 + .../AnimationHandlerBus/Modes/vuMeterPeak.cpp | 65 +++++++++++++++++++ .../AnimationHandlerPWM.cpp | 3 + software/lib/Definitions/TypeDefinitions.h | 4 +- 6 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 software/lib/AnimationHandler/Modes/bassReact.cpp create mode 100644 software/lib/AnimationHandlerBus/Modes/vuMeterPeak.cpp diff --git a/software/lib/AnimationHandler/Modes/bassReact.cpp b/software/lib/AnimationHandler/Modes/bassReact.cpp new file mode 100644 index 0000000..f23eab0 --- /dev/null +++ b/software/lib/AnimationHandler/Modes/bassReact.cpp @@ -0,0 +1,55 @@ +#include +#include + +// Low-frequency/bass envelope reactive brightness scaling of colorValue. +// Shared uniform mode (PWM + Bus). Uses a one-pole low-pass filter over the +// raw audio samples (not a full FFT band-split) to approximate the bass +// envelope - same FFT-avoidance rationale as vuMeter(). silo->sensitivity is +// the gain, silo->frequency the update rate. +CRGBWW AnimationHandler::bassReact(){ + if(!isValidRateHz(silo->frequency)){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return CRGBWW{0,0,0,0,0}; + } + + const float LOWPASS_ALPHA = 0.15f; + + unsigned long now = millis(); + static unsigned long lastStep = 0; + static float lowPassed = 0.0f; + static float smoothedEnvelope = 0.0f; + + if(now < lastChange + UPDATE_TIME){ + lowPassed = audioBias; + smoothedEnvelope = 0.0f; + lastStep = 0; + } + + long period = 1000 / silo->frequency; + if(now >= lastStep + period){ + lastStep = now; + + // low-pass the ring buffer (in chronological order) to isolate the + // slow/bass-frequency component, rejecting fast midrange/treble wiggle + for(unsigned int i = 0; i < ringBufferSize; i++){ + unsigned int idx = (ringBufferCounter + i) % ringBufferSize; + lowPassed += (audioRingBuffer[idx] - lowPassed) * LOWPASS_ALPHA; + } + + float rawEnvelope = fabsf(lowPassed - audioBias); + float gain = 1.0f + (silo->sensitivity / 255.0f) * 6.0f; + float target = rawEnvelope * gain * 3.0f; + if(target > 1.0f) target = 1.0f; + if(target < 0.0f) target = 0.0f; + + smoothedEnvelope = smoothedEnvelope * 0.6f + target * 0.4f; + } + + CRGBWW out; + out.R = silo->colorValue.R * smoothedEnvelope; + out.G = silo->colorValue.G * smoothedEnvelope; + out.B = silo->colorValue.B * smoothedEnvelope; + out.WW = silo->colorValue.WW * smoothedEnvelope; + out.CW = silo->colorValue.CW * smoothedEnvelope; + return out; +} diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp index 08075c0..0cac04a 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp @@ -117,6 +117,8 @@ CRGBWW AnimationHandlerBus::getNewColor(){ return dusk(); case FIRE_FLICKER: return fireFlicker(); + case BASS_REACT: + return bassReact(); default: debugFkt("The Selected Mode is not a uniform color mode", ERROR); return CRGBWW{0,0,0,0,0}; @@ -158,6 +160,9 @@ void AnimationHandlerBus::getNewStripBuffer(){ case PIXEL_ARRAY: this->pixelArray(); break; + case VU_METER_PEAK: + this->vuMeterPeak(); + break; default: debugFkt("The Selected Mode is not implemented yet", ERROR); break; diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h index 623a7a6..06eb35d 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h @@ -41,4 +41,5 @@ class AnimationHandlerBus : AnimationHandler{ void comet(); void nightSky(); void pixelArray(); + void vuMeterPeak(); }; diff --git a/software/lib/AnimationHandlerBus/Modes/vuMeterPeak.cpp b/software/lib/AnimationHandlerBus/Modes/vuMeterPeak.cpp new file mode 100644 index 0000000..b63d421 --- /dev/null +++ b/software/lib/AnimationHandlerBus/Modes/vuMeterPeak.cpp @@ -0,0 +1,65 @@ +#include +#include + +// Same rectified-amplitude bar-graph body as vuMeter() (see that file), plus +// a single white peak-hold LED: it jumps to the highest recent bar level and +// slowly falls back down whenever the current level drops below it - the +// classic VU-meter "peak hold" behavior. The fall rate is a fixed constant +// (no varSilo field obviously maps to it, matching the precedent set by +// comet()'s fixed FADE_AMOUNT). +void AnimationHandlerBus::vuMeterPeak(){ + if(!isValidRateHz(this->silo->frequency)){ + debugFkt("Frequency was set to 0 or over 60 this is not possible", ERROR); + return; + } + + const float PEAK_FALL_PER_TICK = 0.3f; + + unsigned long now = millis(); + static unsigned long lastStep = 0; + static float smoothedAmplitude = 0.0f; + static float peakPosition = 0.0f; + + if(now < this->lastChange + UPDATE_TIME){ + smoothedAmplitude = 0.0f; + peakPosition = 0.0f; + lastStep = 0; + } + + long period = 1000 / this->silo->frequency; + if(now >= lastStep + period){ + lastStep = now; + + float sumAbs = 0.0f; + for(unsigned int i = 0; i < ringBufferSize; i++){ + sumAbs += fabsf(audioRingBuffer[i] - this->audioBias); + } + float rawAmplitude = sumAbs / ringBufferSize; + float gain = 1.0f + (this->silo->sensitivity / 255.0f) * 4.0f; + float target = rawAmplitude * gain * 2.0f; + if(target > 1.0f) target = 1.0f; + if(target < 0.0f) target = 0.0f; + + smoothedAmplitude = smoothedAmplitude * 0.7f + target * 0.3f; + + float currentLevel = smoothedAmplitude * this->stripLength; + if(currentLevel > peakPosition){ + peakPosition = currentLevel; + }else{ + peakPosition -= PEAK_FALL_PER_TICK; + if(peakPosition < 0.0f) peakPosition = 0.0f; + } + + unsigned int litCount = (unsigned int)currentLevel; + if(litCount > this->stripLength) litCount = this->stripLength; + + CRGB color = CRGBWW2FastLedCRGB(silo->colorValue); + for(unsigned int i = 0; i < this->stripLength; i++){ + this->leds[i] = (i < litCount) ? color : CRGB::Black; + } + + unsigned int peakIndex = (unsigned int)peakPosition; + if(peakIndex >= this->stripLength) peakIndex = this->stripLength - 1; + this->leds[peakIndex] = CRGB::White; + } +} diff --git a/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp b/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp index 1af517a..ba91111 100644 --- a/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp +++ b/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.cpp @@ -58,6 +58,9 @@ void AnimationHandlerPWM::handle(){ case FIRE_FLICKER: strip->showColor(fireFlicker()); break; + case BASS_REACT: + strip->showColor(bassReact()); + break; default: debugFkt("The Selected Mode is not possible with RGB/RGBW/RGBWW Strips",ERROR); break; diff --git a/software/lib/Definitions/TypeDefinitions.h b/software/lib/Definitions/TypeDefinitions.h index ba3213c..a032e42 100644 --- a/software/lib/Definitions/TypeDefinitions.h +++ b/software/lib/Definitions/TypeDefinitions.h @@ -40,10 +40,10 @@ enum stripType {RGB_STRIP = 3, RGBW_STRIP, RGBWW_STRIP, WS2812_STRIP, APA102_STR //LED Strip Modes enum Mode {FADE_2_COLOR, BLINK_COLOR, STROBE, SOUND_2_LIGHT, BREATHE, - OCEAN, FOREST, DUSK, FIRE_FLICKER, + OCEAN, FOREST, DUSK, FIRE_FLICKER, BASS_REACT, WIPE = 100, FIRE = 101, NOISE, VU_METER, STROBE_PARTS, MOVING_PARTS, RAINBOW_CYCLE = 106, THEATER_CHASE = 107, COMET = 108, PIXEL_ARRAY = 109, - NIGHT_SKY = 110}; + NIGHT_SKY = 110, VU_METER_PEAK = 111}; //Log LEVELS enum LogLevel {VERBOSE, DEBUG, INFO, WARNING, ERROR}; From a80e3e726f561dab0f66dd898b7a7a49c9d4352a Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:29:11 +0200 Subject: [PATCH 12/39] 1 Part I: add DS18B20 one-wire temperature sensor support 2 3 Confirmed via the schematic (hardware/ESPLED.net) that the DS18B20 (U4) 4 data pin wires to the ESP module's GPIO4 (U2 pin 13), with a 4.7K 5 pull-up (R8) to 3.3V already on the PCB and VDD tied to 3.3V rather than 6 DQ - normal (non-parasitic) power mode, no special timing needed. 7 8 Adds OneWire/DallasTemperature, a non-blocking request-then-poll-later 9 read cycle (12-bit conversion takes up to ~750ms and must not block 10 FastLED.show()/the animation loop, same throttle idiom as audioTimer/ 11 fpsTimer), and publishes Celsius to one decimal place on a new 12 /temperature MQTT topic, analogous to how debugTopic/ 13 pixelTopic are built. 14 15 No compile-time enable flag: the pull-up is passive and always present 16 regardless of whether U4 itself is populated, and an absent sensor just 17 reads back DallasTemperature's -127.0 disconnected sentinel - same 18 "degrades gracefully, no flag needed" call made for the MAX4466 mic. 19 20 Co-Authored-By: Claude Sonnet 5 --- software/config/board_config.h | 1 + .../{fade2Color.cpp => 0_fade2Color.cpp} | 0 .../{blinkColor.cpp => 1_blinkColor.cpp} | 0 .../Modes/{strobe.cpp => 2_strobe.cpp} | 0 .../{sound2Light.cpp => 3_sound2Light.cpp} | 0 .../Modes/{breathe.cpp => 4_breathe.cpp} | 0 .../Modes/{ocean.cpp => 5_ocean.cpp} | 0 .../Modes/{forest.cpp => 6_forest.cpp} | 0 .../Modes/{dusk.cpp => 7_dusk.cpp} | 0 .../{fireFlicker.cpp => 8_fireFlicker.cpp} | 0 .../Modes/{bassReact.cpp => 9_bassReact.cpp} | 0 .../Modes/{wipe.cpp => 100_wipe.cpp} | 0 .../Modes/{fire.cpp => 101_fire.cpp} | 0 .../Modes/{noise.cpp => 102_noise.cpp} | 0 .../Modes/{vuMeter.cpp => 103_vuMeter.cpp} | 0 .../{strobeParts.cpp => 104_strobeParts.cpp} | 0 .../{movingParts.cpp => 105_movingParts.cpp} | 0 ...{rainbowCycle.cpp => 106_rainbowCycle.cpp} | 0 ...{theaterChase.cpp => 107_theaterChase.cpp} | 0 .../Modes/{comet.cpp => 108_comet.cpp} | 0 .../{pixelArray.cpp => 109_pixelArray.cpp} | 0 .../Modes/{nightSky.cpp => 110_nightSky.cpp} | 0 .../{vuMeterPeak.cpp => 111_vuMeterPeak.cpp} | 0 software/platformio.ini | 2 ++ software/src/main.cpp | 34 +++++++++++++++++++ 25 files changed, 37 insertions(+) rename software/lib/AnimationHandler/Modes/{fade2Color.cpp => 0_fade2Color.cpp} (100%) rename software/lib/AnimationHandler/Modes/{blinkColor.cpp => 1_blinkColor.cpp} (100%) rename software/lib/AnimationHandler/Modes/{strobe.cpp => 2_strobe.cpp} (100%) rename software/lib/AnimationHandler/Modes/{sound2Light.cpp => 3_sound2Light.cpp} (100%) rename software/lib/AnimationHandler/Modes/{breathe.cpp => 4_breathe.cpp} (100%) rename software/lib/AnimationHandler/Modes/{ocean.cpp => 5_ocean.cpp} (100%) rename software/lib/AnimationHandler/Modes/{forest.cpp => 6_forest.cpp} (100%) rename software/lib/AnimationHandler/Modes/{dusk.cpp => 7_dusk.cpp} (100%) rename software/lib/AnimationHandler/Modes/{fireFlicker.cpp => 8_fireFlicker.cpp} (100%) rename software/lib/AnimationHandler/Modes/{bassReact.cpp => 9_bassReact.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{wipe.cpp => 100_wipe.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{fire.cpp => 101_fire.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{noise.cpp => 102_noise.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{vuMeter.cpp => 103_vuMeter.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{strobeParts.cpp => 104_strobeParts.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{movingParts.cpp => 105_movingParts.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{rainbowCycle.cpp => 106_rainbowCycle.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{theaterChase.cpp => 107_theaterChase.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{comet.cpp => 108_comet.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{pixelArray.cpp => 109_pixelArray.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{nightSky.cpp => 110_nightSky.cpp} (100%) rename software/lib/AnimationHandlerBus/Modes/{vuMeterPeak.cpp => 111_vuMeterPeak.cpp} (100%) diff --git a/software/config/board_config.h b/software/config/board_config.h index 0891552..458aa10 100644 --- a/software/config/board_config.h +++ b/software/config/board_config.h @@ -13,5 +13,6 @@ #define pinM 2 #define pinData 5 // Addressable strip data line (WS2812/APA102), shares GPIO with pinR since only one strip type is active at a time #define pinClock 3 // APA102 clock line only +#define pinTemp 4 // DS18B20 one-wire data (U4 pin2 -> U2 pin13 per hardware/ESPLED.net); 4.7K pull-up to 3.3V (R8) already on the PCB, normal (non-parasitic) power mode #endif diff --git a/software/lib/AnimationHandler/Modes/fade2Color.cpp b/software/lib/AnimationHandler/Modes/0_fade2Color.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/fade2Color.cpp rename to software/lib/AnimationHandler/Modes/0_fade2Color.cpp diff --git a/software/lib/AnimationHandler/Modes/blinkColor.cpp b/software/lib/AnimationHandler/Modes/1_blinkColor.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/blinkColor.cpp rename to software/lib/AnimationHandler/Modes/1_blinkColor.cpp diff --git a/software/lib/AnimationHandler/Modes/strobe.cpp b/software/lib/AnimationHandler/Modes/2_strobe.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/strobe.cpp rename to software/lib/AnimationHandler/Modes/2_strobe.cpp diff --git a/software/lib/AnimationHandler/Modes/sound2Light.cpp b/software/lib/AnimationHandler/Modes/3_sound2Light.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/sound2Light.cpp rename to software/lib/AnimationHandler/Modes/3_sound2Light.cpp diff --git a/software/lib/AnimationHandler/Modes/breathe.cpp b/software/lib/AnimationHandler/Modes/4_breathe.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/breathe.cpp rename to software/lib/AnimationHandler/Modes/4_breathe.cpp diff --git a/software/lib/AnimationHandler/Modes/ocean.cpp b/software/lib/AnimationHandler/Modes/5_ocean.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/ocean.cpp rename to software/lib/AnimationHandler/Modes/5_ocean.cpp diff --git a/software/lib/AnimationHandler/Modes/forest.cpp b/software/lib/AnimationHandler/Modes/6_forest.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/forest.cpp rename to software/lib/AnimationHandler/Modes/6_forest.cpp diff --git a/software/lib/AnimationHandler/Modes/dusk.cpp b/software/lib/AnimationHandler/Modes/7_dusk.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/dusk.cpp rename to software/lib/AnimationHandler/Modes/7_dusk.cpp diff --git a/software/lib/AnimationHandler/Modes/fireFlicker.cpp b/software/lib/AnimationHandler/Modes/8_fireFlicker.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/fireFlicker.cpp rename to software/lib/AnimationHandler/Modes/8_fireFlicker.cpp diff --git a/software/lib/AnimationHandler/Modes/bassReact.cpp b/software/lib/AnimationHandler/Modes/9_bassReact.cpp similarity index 100% rename from software/lib/AnimationHandler/Modes/bassReact.cpp rename to software/lib/AnimationHandler/Modes/9_bassReact.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/wipe.cpp b/software/lib/AnimationHandlerBus/Modes/100_wipe.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/wipe.cpp rename to software/lib/AnimationHandlerBus/Modes/100_wipe.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/fire.cpp b/software/lib/AnimationHandlerBus/Modes/101_fire.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/fire.cpp rename to software/lib/AnimationHandlerBus/Modes/101_fire.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/noise.cpp b/software/lib/AnimationHandlerBus/Modes/102_noise.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/noise.cpp rename to software/lib/AnimationHandlerBus/Modes/102_noise.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/vuMeter.cpp b/software/lib/AnimationHandlerBus/Modes/103_vuMeter.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/vuMeter.cpp rename to software/lib/AnimationHandlerBus/Modes/103_vuMeter.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/strobeParts.cpp b/software/lib/AnimationHandlerBus/Modes/104_strobeParts.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/strobeParts.cpp rename to software/lib/AnimationHandlerBus/Modes/104_strobeParts.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/movingParts.cpp b/software/lib/AnimationHandlerBus/Modes/105_movingParts.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/movingParts.cpp rename to software/lib/AnimationHandlerBus/Modes/105_movingParts.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/rainbowCycle.cpp b/software/lib/AnimationHandlerBus/Modes/106_rainbowCycle.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/rainbowCycle.cpp rename to software/lib/AnimationHandlerBus/Modes/106_rainbowCycle.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/theaterChase.cpp b/software/lib/AnimationHandlerBus/Modes/107_theaterChase.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/theaterChase.cpp rename to software/lib/AnimationHandlerBus/Modes/107_theaterChase.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/comet.cpp b/software/lib/AnimationHandlerBus/Modes/108_comet.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/comet.cpp rename to software/lib/AnimationHandlerBus/Modes/108_comet.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/pixelArray.cpp b/software/lib/AnimationHandlerBus/Modes/109_pixelArray.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/pixelArray.cpp rename to software/lib/AnimationHandlerBus/Modes/109_pixelArray.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/nightSky.cpp b/software/lib/AnimationHandlerBus/Modes/110_nightSky.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/nightSky.cpp rename to software/lib/AnimationHandlerBus/Modes/110_nightSky.cpp diff --git a/software/lib/AnimationHandlerBus/Modes/vuMeterPeak.cpp b/software/lib/AnimationHandlerBus/Modes/111_vuMeterPeak.cpp similarity index 100% rename from software/lib/AnimationHandlerBus/Modes/vuMeterPeak.cpp rename to software/lib/AnimationHandlerBus/Modes/111_vuMeterPeak.cpp diff --git a/software/platformio.ini b/software/platformio.ini index f9a084a..72220f5 100644 --- a/software/platformio.ini +++ b/software/platformio.ini @@ -28,6 +28,8 @@ lib_deps = FastLED arduinoFFT ArduinoJson + OneWire + DallasTemperature #upload_port = 192.168.178.67 #upload_protocol = espota diff --git a/software/src/main.cpp b/software/src/main.cpp index d9bba55..bc63f02 100644 --- a/software/src/main.cpp +++ b/software/src/main.cpp @@ -15,6 +15,8 @@ #error "config/device_config.h not found! Copy config/device_config.h.example to config/device_config.h and fill in your WiFi/MQTT settings before building. See config/device_config.h.example for details." #endif #include +#include +#include //--Includes-------------------------------------------------------------------- @@ -37,6 +39,7 @@ const char* wifi_default_password = WIFI_PASSWORD; char mainTopic[80] = MQTT_TOPIC_PREFIX; char debugTopic[80]; char pixelTopic[90]; +char tempTopic[90]; const char* fingerprint = MQTT_SSL_FINGERPRINT; @@ -56,6 +59,9 @@ StripControle* simpleStrip; AnimationHandlerPWM* pwmHandler; AnimationHandlerBus* busHandler; +OneWire oneWire(pinTemp); +DallasTemperature tempSensor(&oneWire); + void debugFkt(String message, LogLevel LevelOfMessage){ if(LOGLEVEL <= LevelOfMessage){ @@ -203,6 +209,8 @@ void initMQTT() { strcat(debugTopic, "/debug"); strcpy(pixelTopic, mainTopic); strcat(pixelTopic, "/pixels"); + strcpy(tempTopic, mainTopic); + strcat(tempTopic, "/temperature"); debugFkt("Now Connected - Main Topic of this device: ", INFO); debugFkt(mainTopic, INFO); @@ -291,6 +299,27 @@ void runAnimationHandler(){ } } +unsigned long tempLastRequest = 0; +bool tempConversionPending = false; +const unsigned long TEMP_READ_INTERVAL = 10000; // ms between readings +const unsigned long TEMP_CONVERSION_TIME = 750; // ms, worst case at 12-bit resolution + +void handleTempSensor(){ + unsigned long now = millis(); + if(!tempConversionPending && now - tempLastRequest > TEMP_READ_INTERVAL){ + tempSensor.requestTemperatures(); + tempLastRequest = now; + tempConversionPending = true; + } + if(tempConversionPending && now - tempLastRequest > TEMP_CONVERSION_TIME){ + tempConversionPending = false; + float celsius = tempSensor.getTempCByIndex(0); + char buf[8]; + dtostrf(celsius, 4, 1, buf); // one decimal place, e.g. "20.3" + client.publish(tempTopic, buf); + } +} + void setup(){ initPins(); @@ -305,6 +334,9 @@ void setup(){ initMQTT(); initStrip(); + tempSensor.begin(); + tempSensor.setWaitForConversion(false); + debugFkt("Ready", INFO); debugFkt("IP address: " + WiFi.localIP().toString(), INFO); if(type < 6){ @@ -323,6 +355,8 @@ void loop() { //Run PWM Handler handle runAnimationHandler(); + handleTempSensor(); + //if(str) //TODO: Reconnect client.loop(); From 2bd2d6229ec07b008884f8f8c6fb02ae9cd81cbc Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:29:40 +0200 Subject: [PATCH 13/39] 1 Add class-level doc comments across the core library headers 2 3 AnimationHandler, AnimationHandlerBus, AnimationHandlerPWM, StripControle, 4 and CRGBWW each get a short block comment above their definition 5 explaining their responsibility and how they relate to each other, 6 matching the plain // prose style already used throughout this codebase 7 (no Doxygen tags). Comment-only, no code changes. 8 9 Co-Authored-By: Claude Sonnet 5 --- software/lib/AnimationHandler/AnimationHandler.h | 8 ++++++++ software/lib/AnimationHandlerBus/AnimationHandlerBus.h | 6 ++++++ software/lib/AnimationHandlerPWM/AnimationHandlerPWM.h | 5 +++++ software/lib/Definitions/TypeDefinitions.h | 5 ++++- software/lib/StripControle/StripControle.h | 6 ++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/software/lib/AnimationHandler/AnimationHandler.h b/software/lib/AnimationHandler/AnimationHandler.h index 30c5166..6e2d26c 100644 --- a/software/lib/AnimationHandler/AnimationHandler.h +++ b/software/lib/AnimationHandler/AnimationHandler.h @@ -9,6 +9,14 @@ extern void debugFkt(String, LogLevel); +// Shared base class for the "uniform color" strip modes (Mode 0-99): each +// mode method below computes a single CRGBWW value per frame from the +// current silo settings. Both AnimationHandlerPWM (PWM-driven strips) and +// AnimationHandlerBus (addressable strips, which also add their own +// per-pixel modes on top) inherit from this. Holds the timing state shared +// across modes, the audio sample ring buffer for the audio-reactive modes, +// and RGB/HSV conversion helpers. Each mode's implementation lives in its +// own file under Modes/. class AnimationHandler{ public: AnimationHandler(varSilo* silo, bool* varSiloChanged); diff --git a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h index 06eb35d..95b3e22 100644 --- a/software/lib/AnimationHandlerBus/AnimationHandlerBus.h +++ b/software/lib/AnimationHandlerBus/AnimationHandlerBus.h @@ -9,6 +9,12 @@ // unlike CRGBWW there's nothing to carry for those here. struct PixelBytes { uint8_t r, g, b; }; +// Drives addressable strips (WS2812/APA102) via FastLED. Owns the per-pixel +// "leds" buffer and dispatches to the per-pixel modes (Mode >= 100, e.g. +// wipe(), fire(), rainbowCycle()) in addition to inheriting the shared +// uniform-color modes from AnimationHandler. Also owns the pixelTargets +// buffer and setPixelData() for PIXEL_ARRAY mode, which pushes raw per-LED +// RGB over a separate MQTT topic, bypassing the normal JSON control channel. class AnimationHandlerBus : AnimationHandler{ public: AnimationHandlerBus(stripType* type, unsigned int stripLength, varSilo* silo, bool* varSiloChanged); diff --git a/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.h b/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.h index f8092c0..020c7c2 100644 --- a/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.h +++ b/software/lib/AnimationHandlerPWM/AnimationHandlerPWM.h @@ -2,6 +2,11 @@ #include #include +// Drives a uniform (non-addressable) RGB/RGBW/RGBWW strip: each call to +// handle() computes one CRGBWW via the inherited uniform-color modes and +// pushes it through the attached StripControle to the PWM output channels. +// Only supports Mode < 100 - selecting an addressable-only mode is rejected +// and logged as an error. class AnimationHandlerPWM : AnimationHandler{ public: AnimationHandlerPWM(StripControle* strip, varSilo* silo, bool* varSiloChanged); diff --git a/software/lib/Definitions/TypeDefinitions.h b/software/lib/Definitions/TypeDefinitions.h index a032e42..123a3b3 100644 --- a/software/lib/Definitions/TypeDefinitions.h +++ b/software/lib/Definitions/TypeDefinitions.h @@ -1,7 +1,10 @@ #ifndef TYPEDEFINITIONS_H #define TYPEDEFINITIONS_H -//Struct for Storing Color Values +//Struct for storing color values as this project's canonical 5-channel +//R/G/B/warm-white/cool-white color, with each channel in the 10-bit range +//0-1023. This is distinct from FastLED's own CRGB, which only has 3 +//channels at 8-bit (0-255) each. class CRGBWW{ public: unsigned int R, G, B, WW, CW; diff --git a/software/lib/StripControle/StripControle.h b/software/lib/StripControle/StripControle.h index 1cb2acd..3e57616 100644 --- a/software/lib/StripControle/StripControle.h +++ b/software/lib/StripControle/StripControle.h @@ -6,6 +6,12 @@ #include +// Low-level driver for a uniform (non-addressable) strip. Holds the current +// CRGBWW channel values, converts them down to the strip's actual channel +// count (RGB/RGBW/RGBWW) depending on stripType, and writes the result to +// the PWM output pins. Used exclusively by AnimationHandlerPWM - addressable +// strips bypass this entirely and talk to FastLED directly via +// AnimationHandlerBus. class StripControle{ public: From fafecd11ebcfbaba30f7854dbecb572058fd9e8d Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:29:46 +0200 Subject: [PATCH 14/39] 1 Add top-level Makefile with build/upload/uploadAndMonitor/doc-gifs 2 3 Thin wrapper around PlatformIO (software/) plus a doc-gifs target for 4 the per-mode animated-GIF documentation pipeline. 5 6 Co-Authored-By: Claude Sonnet 5 --- Makefile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ba4371a --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +# Top-level convenience targets wrapping PlatformIO (software/) and the +# doc-gif generation pipeline (tools/gifgen/). + +PIO := pio +PIO_ENV := esp12e +SOFTWARE_DIR := software + +.PHONY: build upload uploadAndMonitor doc-gifs + +build: + cd $(SOFTWARE_DIR) && $(PIO) run -e $(PIO_ENV) + +upload: + cd $(SOFTWARE_DIR) && $(PIO) run -e $(PIO_ENV) -t upload + +uploadAndMonitor: + cd $(SOFTWARE_DIR) && $(PIO) run -e $(PIO_ENV) -t upload -t monitor + +doc-gifs: + python3 tools/gifgen/generate.py From 10639325a095e0f58ae0fa60107ee8bf7866fb2d Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:31:41 +0200 Subject: [PATCH 15/39] 1 Part N: add mermaid class + sequence diagrams to DEVNOTES.md 2 3 A full class diagram covering AnimationHandler/AnimationHandlerBus/ 4 AnimationHandlerPWM/StripControle/CRGBWW/PixelBytes/varSilo and how 5 they relate, plus two sequence diagrams walking an MQTT message through 6 to the strip: an addressable-strip WIPE (mode 100) example through 7 AnimationHandlerBus/FastLED, and a non-addressable-strip FADE_2_COLOR 8 (mode 0) example through AnimationHandlerPWM/StripControle. 9 10 Also fixes a stale Modes/pixelArray.cpp reference left over from the 11 mode-file rename (now 109_pixelArray.cpp), and documents the 12 _.cpp file-naming convention. 13 14 Co-Authored-By: Claude Sonnet 5 --- software/DEVNOTES.md | 195 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 1 deletion(-) diff --git a/software/DEVNOTES.md b/software/DEVNOTES.md index acab36c..eaeb9f3 100644 --- a/software/DEVNOTES.md +++ b/software/DEVNOTES.md @@ -46,7 +46,10 @@ else * `PIXEL_ARRAY` (mode 109) is the odd one out: its per-LED data doesn't come through `varSilo`/the JSON control channel at all, since a 500-LED payload is too big for that. It arrives as a raw binary payload on a separate `/pixels` MQTT topic, handled by - `AnimationHandlerBus::setPixelData()` and rendered by `Modes/pixelArray.cpp`. + `AnimationHandlerBus::setPixelData()` and rendered by `Modes/109_pixelArray.cpp`. +* Every `Modes/*.cpp` file is named `_.cpp` (e.g. `109_pixelArray.cpp`), + matching the mode's numeric value in the `Mode` enum (`lib/Definitions/TypeDefinitions.h`) - makes + it possible to eyeball which mode numbers exist/are free at a glance from a directory listing. ## Project layout: `config/` vs `lib/` * `config/` holds only things a user needs to tune for their own build: `board_config.h` (fixed @@ -66,6 +69,196 @@ else fails the build with an actionable message (copy the `.example`) instead of a bare compiler "file not found". +## Architecture diagrams + +### Class diagram + +```mermaid +classDiagram + class AnimationHandler { + <> + -varSilo* silo + -bool* varSiloChanged + -long lastChange + -CRGBWW oldColor + -unsigned int fpsTimer + -unsigned int audioTimer + -float[] audioRingBuffer + -unsigned int ringBufferCounter + -float audioBias + -unsigned int UPDATE_TIME + +AnimationHandler(silo, varSiloChanged) + +fade2Color() CRGBWW + +blinkColor() CRGBWW + +strobe() CRGBWW + +sound2Light() CRGBWW + +breathe() CRGBWW + +ocean() CRGBWW + +forest() CRGBWW + +dusk() CRGBWW + +fireFlicker() CRGBWW + +bassReact() CRGBWW + +recordAudioSample() void + +rgb2hsv(rgb, hsv) void + +hsv2rgb(hsv, rgb) void + #cycleColors(colors, count) CRGBWW + } + + class AnimationHandlerBus { + <> + -CRGB* leds + -unsigned int stripLength + -PixelBytes* pixelTargets + +AnimationHandlerBus(type, stripLength, silo, varSiloChanged) + +handle() void + +setPixelData(data, length) void + -getNewColor() CRGBWW + -getNewStripBuffer() void + -CRGBWW2FastLedCRGB(color) CRGB + -FastLedCRGB2CRGBWW(color) CRGBWW + -wipe() void + -fire() void + -noise() void + -vuMeter() void + -vuMeterPeak() void + -strobeParts() void + -movingParts() void + -rainbowCycle() void + -theaterChase() void + -comet() void + -nightSky() void + -pixelArray() void + } + + class AnimationHandlerPWM { + <> + -StripControle* strip + +AnimationHandlerPWM(strip, silo, varSiloChanged) + +handle() void + } + + class StripControle { + <> + -stripType type + -CRGBWW channelValue + +StripControle(type) + +showColor(CRGBWW) void + +off() void + +getColor() CRGBWW + -RGBW2RGB() CRGBWW + -RGBWW2RGBW() CRGBWW + -RGBWW2RGB() CRGBWW + -recalculateColor() void + -setChannels() void + } + + class CRGBWW { + <> + +unsigned int R + +unsigned int G + +unsigned int B + +unsigned int WW + +unsigned int CW + +operator==(CRGBWW) bool + } + + class PixelBytes { + <<3-byte raw color for PIXEL_ARRAY>> + +uint8_t r + +uint8_t g + +uint8_t b + } + + class varSilo { + <> + +unsigned char mode + +CRGBWW colorValue + +unsigned int time + +unsigned int frequency + +unsigned char sensitivity + +unsigned int position + +unsigned int length + +unsigned int minBrightnes + +unsigned int maxBrightnes + +unsigned int timeVariance + +unsigned int maxBrightnesVariance + } + + AnimationHandler <|-- AnimationHandlerBus : inherits + AnimationHandler <|-- AnimationHandlerPWM : inherits + AnimationHandlerPWM --> StripControle : drives + AnimationHandler ..> varSilo : reads/writes via pointer + varSilo *-- CRGBWW : colorValue + AnimationHandler *-- CRGBWW : oldColor + AnimationHandlerBus *-- PixelBytes : pixelTargets[] + StripControle ..> CRGBWW : showColor()/getColor() +``` + +Both handlers are constructed once in `src/main.cpp`'s `initStrip()` (whichever one matches the compile-time `STRIP_TYPE`) and driven every `loop()` iteration via `runAnimationHandler()` — `main.cpp` itself isn't a class, so it's omitted above; see the sequence diagrams below for how it fits in. + +### Sequence: addressable strip, WIPE (mode 100) + +```mermaid +sequenceDiagram + participant Broker as MQTT Broker + participant Main as main.cpp + participant Silo as varSilo (Silo) + participant Bus as AnimationHandlerBus + participant FastLED + + Broker->>Main: publish {"mode":100,"color":[...],"time":1500} on mainTopic + Main->>Main: callback() deserializes JSON + Main->>Silo: mode=WIPE, colorValue=..., time=1500 + Main->>Main: *varSiloChanged = true + + loop every loop() iteration + Main->>Bus: runAnimationHandler() -> busHandler->handle() + alt first tick after change + Bus->>Bus: *varSiloChanged true -> lastChange=now, oldColor=leds[0] + end + Bus->>Bus: recordAudioSample() (inherited, always runs) + alt UPDATE_TIME elapsed + Bus->>Bus: mode >= 100 -> getNewStripBuffer() + Bus->>Bus: case WIPE -> wipe() + Bus->>Bus: light leds[0..N) LED-by-LED based on elapsed time + Bus->>FastLED: FastLED.show() + FastLED->>FastLED: push leds[] out over the WS2812/APA102 data line + end + end +``` + +### Sequence: non-addressable strip, FADE_2_COLOR (mode 0) + +```mermaid +sequenceDiagram + participant Broker as MQTT Broker + participant Main as main.cpp + participant Silo as varSilo (Silo) + participant PWM as AnimationHandlerPWM + participant Strip as StripControle + + Broker->>Main: publish {"mode":0,"color":[...],"time":2000} on mainTopic + Main->>Main: callback() deserializes JSON + Main->>Silo: mode=FADE_2_COLOR, colorValue=..., time=2000 + Main->>Main: *varSiloChanged = true + + loop every loop() iteration + Main->>PWM: runAnimationHandler() -> pwmHandler->handle() + alt first tick after change + PWM->>Strip: getColor() + Strip-->>PWM: oldColor + end + PWM->>PWM: recordAudioSample() (inherited, always runs) + alt UPDATE_TIME elapsed + PWM->>PWM: switch(mode) -> case FADE_2_COLOR -> fade2Color() + PWM->>PWM: interpolate oldColor -> colorValue over time + PWM->>Strip: showColor(newColor) + Strip->>Strip: recalculateColor() (RGBWW -> RGBW/RGB per stripType) + Strip->>Strip: setChannels() -> analogWrite() per PWM pin + end + end +``` + ## Testing * No hardware is required to run `pio test -e native` - it exercises the deterministic math each mode leans on (guards, phase/index math, color interpolation), extracted into hardware-independent From df2540988fa80225b1104be42f3a2085a7c749a2 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:52:01 +0200 Subject: [PATCH 16/39] 1 Part M: real code-driven animated GIF previews per mode 2 3 tools/gifgen/ compiles the ACTUAL AnimationHandler/AnimationHandlerBus 4 mode source (unmodified) into a host shared library against a small 5 Arduino.h/FastLED.h shim (millis()/analogRead() driven by controllable 6 globals; real reimplementations of HeatColor/blend/fadeToBlackBy/ 7 fill_rainbow/qsub8/qadd8/random8/random16/cos16), then drives it via 8 ctypes + Pillow to render a 15s/20fps GIF per mode (100 LEDs, one 8x8 box 9 per LED stacked into an 8x800 image) - not a random-color stand-in. 10 11 19 of 21 modes render from the real production code as-is. BLINK_COLOR 12 (1) and SOUND_2_LIGHT (3) are skipped - both are genuine stubs that 13 always return black, so a GIF would show nothing. SOUND_2_LIGHT's real 14 source needs arduinoFFT, which isn't worth vendoring in just to render 15 permanent black; the harness supplies its own black-returning 16 sound2Light() purely to satisfy the linker. PIXEL_ARRAY (109) is driven 17 by a one-off setPixelData() call instead of silo fields, since that's 18 how it actually receives data. 19 20 `make doc-gifs` / `python3 tools/gifgen/generate.py` rebuilds the shared 21 library automatically if missing or stale and regenerates every GIF; 22 verified end to end (clean rebuild, full regeneration, frame count and 23 total playback duration checked per file). Adds a Preview column to 24 the README's modes table wired up to the generated GIFs. 25 26 Co-Authored-By: Claude Sonnet 5 --- doc/gifs/0_fade2Color.gif | Bin 0 -> 6716 bytes doc/gifs/100_wipe.gif | Bin 0 -> 1976 bytes doc/gifs/101_fire.gif | Bin 0 -> 349206 bytes doc/gifs/102_noise.gif | Bin 0 -> 74389 bytes doc/gifs/103_vuMeter.gif | Bin 0 -> 10446 bytes doc/gifs/104_strobeParts.gif | Bin 0 -> 13931 bytes doc/gifs/105_movingParts.gif | Bin 0 -> 29553 bytes doc/gifs/106_rainbowCycle.gif | Bin 0 -> 539433 bytes doc/gifs/107_theaterChase.gif | Bin 0 -> 39191 bytes doc/gifs/108_comet.gif | Bin 0 -> 164733 bytes doc/gifs/109_pixelArray.gif | Bin 0 -> 267 bytes doc/gifs/110_nightSky.gif | Bin 0 -> 44587 bytes doc/gifs/111_vuMeterPeak.gif | Bin 0 -> 14714 bytes doc/gifs/2_strobe.gif | Bin 0 -> 24483 bytes doc/gifs/4_breathe.gif | Bin 0 -> 46162 bytes doc/gifs/5_ocean.gif | Bin 0 -> 48933 bytes doc/gifs/6_forest.gif | Bin 0 -> 48933 bytes doc/gifs/7_dusk.gif | Bin 0 -> 48933 bytes doc/gifs/8_fireFlicker.gif | Bin 0 -> 47629 bytes doc/gifs/9_bassReact.gif | Bin 0 -> 47303 bytes tools/gifgen/.gitignore | 6 + tools/gifgen/build.sh | 53 ++++++++ tools/gifgen/generate.py | 192 +++++++++++++++++++++++++++++ tools/gifgen/harness.cpp | 176 +++++++++++++++++++++++++++ tools/gifgen/requirements.txt | 1 + tools/gifgen/shim/Arduino.h | 100 ++++++++++++++++ tools/gifgen/shim/FastLED.h | 220 ++++++++++++++++++++++++++++++++++ 27 files changed, 748 insertions(+) create mode 100644 doc/gifs/0_fade2Color.gif create mode 100644 doc/gifs/100_wipe.gif create mode 100644 doc/gifs/101_fire.gif create mode 100644 doc/gifs/102_noise.gif create mode 100644 doc/gifs/103_vuMeter.gif create mode 100644 doc/gifs/104_strobeParts.gif create mode 100644 doc/gifs/105_movingParts.gif create mode 100644 doc/gifs/106_rainbowCycle.gif create mode 100644 doc/gifs/107_theaterChase.gif create mode 100644 doc/gifs/108_comet.gif create mode 100644 doc/gifs/109_pixelArray.gif create mode 100644 doc/gifs/110_nightSky.gif create mode 100644 doc/gifs/111_vuMeterPeak.gif create mode 100644 doc/gifs/2_strobe.gif create mode 100644 doc/gifs/4_breathe.gif create mode 100644 doc/gifs/5_ocean.gif create mode 100644 doc/gifs/6_forest.gif create mode 100644 doc/gifs/7_dusk.gif create mode 100644 doc/gifs/8_fireFlicker.gif create mode 100644 doc/gifs/9_bassReact.gif create mode 100644 tools/gifgen/.gitignore create mode 100755 tools/gifgen/build.sh create mode 100644 tools/gifgen/generate.py create mode 100644 tools/gifgen/harness.cpp create mode 100644 tools/gifgen/requirements.txt create mode 100644 tools/gifgen/shim/Arduino.h create mode 100644 tools/gifgen/shim/FastLED.h diff --git a/doc/gifs/0_fade2Color.gif b/doc/gifs/0_fade2Color.gif new file mode 100644 index 0000000000000000000000000000000000000000..4394aaf112857feac9b21711ca8a05a1e1209df6 GIT binary patch literal 6716 zcmZ?wbhEHbZe&0KivPL&TtkAL9RpmA^bD98fs%?pSr}M>v<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=FrC%N#sqR91PoFq@_+&o3I?eY zh1o%o4grJIiIQA{-ih)&gWid1{D}NANF!QDaL_x^ScDmtTLx>nXel=6ooFvP=$+^$ z%`(^{+DC5CJ26;c&^s|w8Bs|O(sD6gb=Av;chEcWOaRYd55-GCgWicZLkGPR?}zga_K1EKHRzrACT7q(@l!nCV2|jZ XiG$FIBEY^qe6FSOe+vKL3Po!G^Hg{H literal 0 HcmV?d00001 diff --git a/doc/gifs/100_wipe.gif b/doc/gifs/100_wipe.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7908813bf6ef45ea844132935299e37093282d8 GIT binary patch literal 1976 zcmZ?wbhEHbZe&0KivPL&TtkAL9RpmA^bD98fs%?pSr}M>v<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=(48g0(8%*&734%P;E=@bL=6K4 zWStT~50R(S02CBxcFJP66BI0sjEu}EJ4rJRKLAK5Uid;N_Y)b$*i!YFE?+em(x&dobP-V(Ya;mTf0I9y$CIA2c literal 0 HcmV?d00001 diff --git a/doc/gifs/101_fire.gif b/doc/gifs/101_fire.gif new file mode 100644 index 0000000000000000000000000000000000000000..fffca8c174ff6c750ed728d6f6588f01f35209a6 GIT binary patch literal 349206 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
Z=+u5-L#5@;Ft77Q3_<)KLHIqC~dK(9psS*zab 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 z

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

%MF7X6<=#XDfh;tDytE06*N8+XMi% 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 H-fs3U4gRDX literal 0 HcmV?d00001 diff --git a/doc/gifs/103_vuMeter.gif b/doc/gifs/103_vuMeter.gif new file mode 100644 index 0000000000000000000000000000000000000000..095ea76146cb0496db001c7686a3de6c35bfdd84 GIT binary patch literal 10446 zcmbW5O^91n6vtnhDvws^gDOPmXi68Rtw@}1BBDe}HS>W4>LQC)A})+|6X+((3|$y1 z=s*_+Y-M!(NT+HuleUxM!jVBHGgD!th$-!8q!fm(21+5W>b>MVz4P*anS0J`vY6lb zyyu*I&wFF!_0&u6xK2De;W&?8b^iO?|7iD{$KE=A^tJ4<;TMw8i2BF=e|9>Lso&={ zq(vOJ;Y8ehnflbvXWYGqPPFP@EPm)67(Jhv{qmQOVnCp?L zS7&~|lxv(?U%7hekIVVRvqNLozPr^Z+?+YNdhPq$^ToR>7slp)SpTu~;QspR{N=xX zDo1xeGv2KKy;#|M`0X3b*}F@V2gW`hzdm>xb{AKz)pFDUs~K>legpV%5fTP(S$B;A0`J*Lg^m}mOfRlFDApECJg@w=3nUA;DO zqn1`4_IS^hr#8fV^#7I&MBym?{ZSbF)+oqIN5viw#6F}{g*5&|Bw}W+1b|czRcuHOuoqE3rs%G*Fs-zid`sk2QzTUrN$IBrKW~#tigP*@ zCSPXqMNt%akyKVBl@>{*l$2GTY1$-2R^ql+{JFv8U6EH^6*<2$^+Vh$V-(AVEx)Jt zvg+9Kq`%GN*O+{Z$uHRQR8dV^{>ff`FmEh({;P@diFxqK8t4zuPdttn@Z=B9C*bLP z@p*;wxE{iJU2pweVDRvzjk~~*@=t-H=)zM5JZ05^69Dj}Ur&Jkt_nS2U0W;uY=QfQ(Jy{~`LhM?7X}aeOYc6M{)&sN=sk{OC1uO|v&ELD zTxFO%-gb@L2F?O+(|{-c@wN_lx}EXY0KgCTUL!?jyqE{C5y~g_2k-;q4d-z_0Z;zm z^9tv2J%sbRKKoxI1`m5J2~WY03RDs9HG_v%VoWO@lXscC{_fG=`$iOjsPUW(=kYW) zc$lR&oZ;I^>HEbh7OHc6i*0A6X={b5UEi=)UJ;LPaKo#>iBv_os)(dYBB>%X0|h3Z zXYx5FpJnoC#S7+-NGf6L8`XSFWW}?!LN)9%d56j4O)$JiHdF`lPsI8w3gs4W&A=<- z@m3Ca%4$nR!I>oZs{+tZ{xq5T>$W`U$2@o!4fF@_1HbBkcqyMaUZ9_NoKL`$Klr== zKd>GEPyXn7>#u5qhj**)h5jlsqyqPg{z}8Qf;&3g3Z59@Jf2A5yqCR7FxXkyMiz(Spdz8q-Rf$#+CvZ8EKN zMOO4q#P3bKsfAav-Um6AoM7^JKMnT>Z@~r+ZwI_<8&ZMWLGSYX+**H8p_{J2%vF)e Wmuz{usmr!J`CqZ+N&ln`|MI_13Uadm literal 0 HcmV?d00001 diff --git a/doc/gifs/104_strobeParts.gif b/doc/gifs/104_strobeParts.gif new file mode 100644 index 0000000000000000000000000000000000000000..42f3c35e6a218e74e99bc21b45a29bb518b1e1fa GIT binary patch literal 13931 zcmZ?wbhEHbZe&0KivPL&TtkAL9RpmA^bD98fs%?pSr|lsv<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=z|N9{I7(RlG0gcFUbVNR4(f;n+o55$T4vmj1PI}CARYsTYKbG^6go!nmW z`PJRqm)G6j-@vT=)O*KzDg0gqn>m8e(o-S3-zISG(=Ckt)oWtMx z?Ansq&B%!CKS;2n`tQh)_TQr5)p37~6bO5g8FxC&fAgTt{PaG$w~o!82M<4wvLQ8k3_j zIfM$H(Ry;YB-hcH9F55#RPc<}lfxysj>hC@Ob(%fXSALiF3EK?CP!m(2o*e|_2h6# zuA?zI8k0k);2Etahf8uDjmgoN96|-pXgxVxlIv(pj>hB=DtJcg$>EY*M`Lm{CI?r+ R!wTH51m9RS9C!Fw0{{rq*s%Zr literal 0 HcmV?d00001 diff --git a/doc/gifs/105_movingParts.gif b/doc/gifs/105_movingParts.gif new file mode 100644 index 0000000000000000000000000000000000000000..7deda5c2998d68cc7e98eb84d74451079b5d673e GIT binary patch literal 29553 zcmeI5J!lhQ7{@QUDu-PHT{5(i;u7iyp)M&RL`pSDMFJJf&`SLnLMOo`V@n4^9a^Z+ z!4^}aHl}LRrfmWaB0dp(ETlL!2u&mjB*B~aRz|2_Qfec#{R zd+(hJo%HuyFf@-orfJ%?`uX+g+-^P7cXpunM5M3#h);K@Uw8g!(e|kCL*}2D|DqZ5 zn!{)hW|L3Hjkd1AQg*(0&2=C=8(hBq?7I8t$YyCd^?cH$C)z_RcgoY=fy`iehqvz%Labt^EwuOqygev=ALcMVlm?{6$bQsKGqTITIyG&fSKtS!D< z8ZJ(B^shhokc(|(hN|liKjyD|t<3f3AJrbmzirj3`K3=!M)lVHrwiFH#YEe|^Dm;8 z12lC+8*4mFqes)}5g3jjIRa1b1UUka?rdz?rRotSEgx@g*{qG%HQG>{=9YJA)9q<& z-K$!c$?X@-9TCetESftmmOCMuJ1LesE1J6`mixVE?z&iR)vXHlCvMfcOn>4P%^eWS z9TCkP6U!YJ%{?WSJ1LsGAeOr%n)|a@?z(7h!ztCDxK+z?^D3WM?tp0Ss95fpXzo$5 z+*6{t(_*;`qPbs-UH!*tR?I#GT;ST%QWZrhO_Lo8ttIO*w&M zbDRXk?(@O1xq8E~>3Ipq<~V_4Q%>O694ByW$_X6X;slNj$HrRme_7)W$EJNM9Ge?^ z;n}9NRiC;n;9&I5r#` zj&0xLV)yp+gJaXN7mm%%iQ(9k6F4@<2^^bp0>|b!fn!rn;Mg1|X|cV-;Mi8Z;n;9& zI5r#`jt$4Q@99?;+d~nK&CPY-*mO<|$L2VJV^dDx*c>NtY|057o8ttIO*z57;u0^$ m!k%Z?^XzZmIfm!4Y2Spk;@lX9``DBdI5x)#9D9e8V?O~GQ<$Lu literal 0 HcmV?d00001 diff --git a/doc/gifs/106_rainbowCycle.gif b/doc/gifs/106_rainbowCycle.gif new file mode 100644 index 0000000000000000000000000000000000000000..d5efc5c947edb7070526e497bac4a6e679e8bdda GIT binary patch literal 539433 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

|pkU4kqajf$wdRz!!}->wzWOpAgW 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 literal 0 HcmV?d00001 diff --git a/doc/gifs/107_theaterChase.gif b/doc/gifs/107_theaterChase.gif new file mode 100644 index 0000000000000000000000000000000000000000..a037f72f8ee233378889db0d672d92526c4d44e0 GIT binary patch literal 39191 zcmeHQYe-vX7(OnIoGArC*g{G0(v6PP3}@=9IKfe~nv0t=X%k&yB1#cihfrA8p;&9< zJu4zZ(5SJ|sL{AwjMi>LicQ)?O{t-dS+%tIqg4x=sI(QyPGX^6mi51T4uk}f!26x= zyx;p=-t(Q){4bJ{^GPC_Rzd7KVtnCW@+9I@pJ(wBK8~k_P+!KpJVel`_c;F#{eL0I zD?|v%%rNV2Rg#fx`CW78cy+{4fi}Z(-BHir7SG+a=htzw=>=^9yYWH4%vL<_w)g+> zi)y@%B^)03(^lj)Dkg?a4@XKGLk|VQ3fm5gq{1R;6+WNOA7bDjAMFfL#L(>tQG3Ho zg&1`*5F)=ZT5J?u3WS(EsO5WAlT?W323$6Srz5R=gK12lLgdu4*K4Q{+l2bqQh}YF z-X{ysofjnbO9}aS>{iQ}fgD|-rCm|aHA#j`ls7d;Mh0D@!sko8+UBPVV~ovLbdk)U zYF9@pQyXNK0;h&`tZGHPTIl9-luo&Xo9{WES{^!;y{4S*&Rpgl&R)-(iBUXMPf5O4 z%(Biua+M*-lL`{c~$S9BEttR z>xaUhsVQoBW;JBia;Yim`^#{z^|Q*bsh75*iO!6smJ@DC*K|+T`=7S`_z5*dA-%=w z8vC->qzd_gm2zU`thMN3%Y&9-)1+N8?^e7!@@($csO4G5gjAnrD5D9tzLA(8S6&T| z%8QHt`zvPyYxC-FvV<&m73bk?ZH`Uoxk8P9Ub^=6bZO>Tx<;DFpD`&?)Tz>qZ)d+d zUwxY+9pNpEmPzS9olSCF-gySLFU;Lnz~Vu^0z6qSa-Wd2ciw&y4)kU4qU1@z?vvnO z3y=%cy1r{QL@rP(#NxqT5|In23v|?l06ai0AQzAe+fW&~fLuT>AQ!-$U#lm;NWe(Y zk+zjYbAfG>bAfG_N{Tu~QL7f=^a7f=^a7f=__kF={J4LTBZ zBIwGqv(>gd!ji$c~HyuswP{LE}R>1*$keJwDJw6F`@Uqo>R+SuNms|wh8sI zr2;!Uy-yaNJ1v*sYc`139`vOS__;Ymy9?C~s|AoDIH^u95x+ zZG_hbuMJ)syf%1k@Y>+D!E1xp2CofX8@#q)v=Mv(d;xp`d;xp`d;xqR2w$KR1QAEQ X2$G1VRrq{9|L4F#E)xF-O*Q2o@xnP) literal 0 HcmV?d00001 diff --git a/doc/gifs/108_comet.gif b/doc/gifs/108_comet.gif new file mode 100644 index 0000000000000000000000000000000000000000..04bbca9a3baf8a0194360ecc57eebc602879b80d GIT binary patch literal 164733 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 literal 0 HcmV?d00001 diff --git a/doc/gifs/109_pixelArray.gif b/doc/gifs/109_pixelArray.gif new file mode 100644 index 0000000000000000000000000000000000000000..54e96188f0750be6cbfc8cfbb1afd7df06886060 GIT binary patch literal 267 zcmZ?wbhEHbZe(Eizls446#sMkxrPKgI|jHK=@~FH0wolGvM}6XWnj<&DFSI> z;5f;^$RXpgVZp&>4q+`Hi3JM}w+kqH&GFc{=xDcuan_v^8y6q%S8%q9@z}J)bFxzK zs+g0TmY$w&U^s7%XK~t@*%rmG?wq`wbauW2|2G-0Eh{cA7HZbw?b@>P^6~&jy}4e- ztFEq&SR8aW%4qfV^$CSVvZoE!+}xaDIVm>UVD0Vg1=5@5ax1L6yF2dXrlY5~=Lhf2 z{>vq|N7x|pP>1k#6PvJ&kB`eq7PtEBEOI>=t($#MhQT=W+ycewc~ZMd9$obIT`krV N_43vA3T7q-YXCp~YV`mB literal 0 HcmV?d00001 diff --git a/doc/gifs/110_nightSky.gif b/doc/gifs/110_nightSky.gif new file mode 100644 index 0000000000000000000000000000000000000000..e4adf12e619da08fdd9b3c6c4b9f9e8f75951da9 GIT binary patch literal 44587 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 PvLK~%Pmx{>Ngw}zn(3!- literal 0 HcmV?d00001 diff --git a/doc/gifs/111_vuMeterPeak.gif b/doc/gifs/111_vuMeterPeak.gif new file mode 100644 index 0000000000000000000000000000000000000000..a97d3cbb8469260f1af80a2d235e8038b79a4a06 GIT binary patch literal 14714 zcmc&*eQZ-z6o1`@c?=0fAQ_)2sL%~U##b^Fu{vO78>2GN{sCAZV1Yy{XfiRzB8fH- zwnd^0<)iW;V<-$ZU`Py8Lg>cGFi4mRIzxzq#AJyvnI;C$U2k9Sy}MoCxvvfTXUTHT zJLh-4?m6e)6)jv)Fng7*IWo6u+C%u6t3`jtKO9sxe`$H)3!eGYr{-tc;IHHV$4EmI%kt`C2=O&^xGJW~I~rH|}S7VmYRI(T_U&WsJWBc~2ssd5xds`ci-8kww zRJ^bFOx?}n-i8f#TF)H6b<%ff``D7RU;WhJzfrg1>e;VbaA@T?}Rp8dus>|NEuTu*oainoixlQvGDf{?hZO?_I5#vGLco^9_HrhYNR%Tl7ui z`U^H2i>Vth)oWW>Bk0BI_;QB^WB87?@8?C;*mSKz5H%MmsxqtDFy-cTE*6QNp=(~@ z^95!MzvZ+C;~`qf!|X`SXS(4tc0rrbtTv^3*hrWOmxC;l9^lOpc*nE6(PYzY zZX?;+a-w$4j;5%dsUZFDD6d_GmzD;?s|%VB(FVlJL@CuXR!StYMzHi0X=Vm%pH7L3 z#`fik6{D@ZgCoG*H$fO36PL2NSuUfLZ93wv;y>IZad~nu^}vNOSs3WW^6`9P@Ulug zGQ(?B;@lbc_~0WciP5JTNgo3GkPsq;IQ`)yxo;1~Pm<53T!zESh009#AL(e^6sgIFWFYr=oI4z9iE zK*EbC!D|98rvPtxir^8~{i%mZpS>$@MQdYjd6+-IYL!$b{Vd*()xd>`mJrZ;1jDRK zp<$u}NS4hBhKUX!JF{nU0T4uL98j{054ZvX&b2AW2?4NZVAvS6@|Fpa;8D`urNmVL zT-5?%e>xC@XV<@^#YfAN8H4rSu7RF7P9^mnz=a9q9H6fi;BHJ4T;kwq88yZvT{pt- zV*4ar32_hL#V0(Oup#P?7m_{ zEu|+Dj+h@wJ>Rb^W;l(>qIL_WTvlRS#7ANVZ(-LGrA$Plc7UX}Hg8r&Cv#$YQfO*~YJ%e-yvy?1UTDrTldoSubLAZ~(pHMH96W z*|&;y#q2d#feLTz^ibiYI=e0KdMxmgZ9Cdl6t7Q(cS!U?&#%HeJ<2O@l$lESfG+e3_0^L5kq$RG|gG z38^9JwJ?Ze{a`w-cS&C>+90`qLP}f}z!ec9EsYnc0i?v^{T<>L!sjJUZeK`bQaqM1Fyg1MAsshSE04 z*wGj-TF8@+V>dq54jNCZSFaewy~dSCoWydpuaZZ!gq{wf9TvPwGSx0vX>A&;RF~Ck zJV1ZDZi$UQqDj3H^FR4Qoz&94nJ=*uwQDy}cL~kM8Wt;lYeyg38!0?N&ZKeo@C zb)SC*DnG0e>nuME6VsE!wpqaFWieWa`bzE{*E{@>L;4DgGaN{I(&vN)U@x=4RGn8o zF&MukUGQ!tzpg9*vG~YzD{*;|Ch-BiPcTW5nn@h|^H=^~9|B0dDvDwfcYj)||Y+3qs3(`9*@OE0(T;A2NHL{=o z39&4lEWNDxT|Qiy)1T}K#RxYWGfoS<`4)J|2GyFy+!myhwXrqnJ`2+Q7I*^|cq>$R VY3CnQ;iWxSNQIZmt;X^``#+L{)4Kow literal 0 HcmV?d00001 diff --git a/doc/gifs/2_strobe.gif b/doc/gifs/2_strobe.gif new file mode 100644 index 0000000000000000000000000000000000000000..a9809d80937b5c6bfa14905a76ba12e4d6f8ca95 GIT binary patch literal 24483 zcmeI4JxfAi7>18%AvP4WG$a@;ArVoF(Nc(|1|ihYpis1gQ_wFchoFXthK7tj>{E+0 zKbj+=R3gG6BKrgVgC^6UsO=rz;UTWGoZ)!j9)ZnLTSuM&CcL$a_4HXsofv-rgpEF zTYAIg+f?jk#o=CR^_}nK*E+`H!TkAtalL!G5cQ=G?lxR=@8x{@@P2C`Vzc`*M-MUY znln_$9G4CQG5@AN8-Genq{DB8Y~uNB@@mOGk~?`x&y?b!V(#?yVs^FO@^viR?_Ii{61doF7${{#6=RVTskCLM_ix?MJc6&i@1o3$^(#nQAb>$2t_HSgNwL` zi^>C#eNjhTpa?}NrGtyOh>OYtkbO}{T%ZU=DW!vpxQL6&1CV`DM_ix?MJc6&i@1o3 z$^(#nQAb>$2t_HSgNwL`i^>C#eNjhTpa?}NrGtyOh>OYtkbO}{T%ZU=DW!vpxQL6& z1CV`DM_ix?MJc6&i@1o3$^(#nQAb>$2t_HSgNwL`i^>C#eNjhTpa?}NrGtyOh>OYt wkbO}{T%ZU=DW!vpxQL6&1CV`DM_ix?MJc6&i~rWey6S)X^GSPo-;VG91iu0VyZ`_I literal 0 HcmV?d00001 diff --git a/doc/gifs/4_breathe.gif b/doc/gifs/4_breathe.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d8a325be8d8279a595484fc61812b22fd608b7d GIT binary patch literal 46162 zcmeI*{ZG|Z90%~XlN_TV2&8i5Du{w!RBlj;qQyfzT^yhgp*+MLDpwu^MN6#KkXjB~ zjcBVSmWGL3a6DWt_OMz;CR|c8MvRcHhu``S{HZQ9qx<{);r-t3{e_Le_S)y1?>YB- z&gXMZR!(NpPOCp6m$m?b2*;yO)ZdTiWfT>rrxs)+Y%?!i;{JWqLq7z#e{PxooB4l% z|5+^YkH{XlbhFhz)KoS$aC!8t;Al%{_TZ=v(-no#}^w)!NNB6x?Qd$Fymf>snyRth><*wnL$?k$K%SDURKGj>| zsF`y)d#C#=N860KBYiUt+oZjGV&wYljmGw6ehaL}{?BR&gkhez@F68G$C^h%)+h$S z$WB~=NOocfb?Ufl2yA8(?OSq7mEKiIGTVCq^Tcofv~`cA^RS?8I#- zW+x_~oSnEGhuMj{P{&Su1}E8xX?T^Ln2A<)q6O#KiTUVYC+^2b?8IVRW+xuRHFjbJ z`q_zAIN6DZ@D)3;8sD-LYw!a*u?{YFVgv576OZF(cH#+4u@jpx%}zXt8Fu0+{K`l4 z*d=H=g;_qL=Z*no6g`OoeNo_v78n-=W*31ux}N`=j==ZDYTRTWx&_`{1l|Az-lGLp zBLvoT3i(&Y1lAXG`B!N(@do?QEwE!CuoxlPa(uEwHOEkQ)(=H1;Pt z61&-n0@+RmJjotKfy_IB{KZggU~g!FTv~yQWP!Zy<&4?!^Mwch)fKoC_!kQiNYi}< z8afCO?1N4)*0K{jzAeiEymdU;!%9hP86ur zIE=5^qgaK{*@=}HW+w_1la!)|J&Gl`!cKf1AF~tp;X`&}9^PXo=HhL3Viw+HCq9SQ z*@-DQ%}(5d6YRvDsAVTgl;l*fM=>5H?8GhD&raNgz3jw|$Ydw3M+!S}9slXR5>-P9 z>C8Cl&ib=4s6L;e{J24f_ z?8FS5WhYwD#!eJCmah;O*rWIYy4Z;VWe}AZVvnLgje*3S8n@XSx*k8W69qDooA3*J z6a_8`co}o-Q9O;`*on>fosSsgCM_-`pTVDeM9=K_X8gfU6zGcrPqe_eC@{MST>BwV z?@|l;?~69yof;jca@TOrWOqTA<)X!DpXx1f)Xce@z0>`bqix3Ak-iy+ZPH#oF>-zO zMq~RjKSVwBgXiobPzF(kKK2PvpvIsGo$OH*IKxEZ!irY*hEBy9cA`Lbd=iebM^WIk zws;(1k76A5u@hrqVJG@-gYZWFqCkd8ILz#QQ6Sq%B58U(dqW3f9XnAV3)Gj9?2Vy2 zknzF_&(#Qt+aQeWPqe_G69W37TOw(izV=F>g3SQ>IzS_Kun#%{H`xii0mdMUy`eYz zu3GTIzKa>9>1X_bz>>}_UO}846{151Q B4SxUt literal 0 HcmV?d00001 diff --git a/doc/gifs/5_ocean.gif b/doc/gifs/5_ocean.gif new file mode 100644 index 0000000000000000000000000000000000000000..e6b7c1b5b242ce2bb871b49452487c49aad32367 GIT binary patch literal 48933 zcmeI4>rc&b9LG;eJJT%IOt!LeTbd{h(bgiRPDWN%QR%LWP?1!kLL|CLT16^dPNmD~ zGG=ax%FL{pnfwF(1CJrcA_ff3;WyTbyvZuYdcnt#>xhmB$J{PU)TcPxCwU@SFQ8J&U$TVIwL z9o%E41|Lk6FI#JB4jyWoyy57bF*h~T{Q^6BW*( zV|`yNX|v|ocVqou$4}ST+We1IVz4P%K>WS2BH9-IC8V`zETBiUJ5P_eG@l;P{v18x z@;rJ(hqLsEE6&g(uFR!JT$MwQ=#)*5xcW3bqRT0I#5E`B5!dk}Zpfmy=yrl0(LIwM z(IbN%aZ5TqqE{L{qW5un#BHhch&xi~5qBojBl;%MBl;!MBl;)MBkqZ(N8Edi9x;d? zF*uIiqA8XhaeoXw;=!Zzh=-2QBZf!QBOZ>TM~sZ5M~vqGE*|CoUyS2F0LJs5FDCL| zyCm~pN2l`N(@E#QznIB?uRDu>-Q^Vj8elg6dUP)TY(!o${h3bw!nn+zjdjAL;PPKW z+6j}Qa(cw#3VOtnN_xbyDtg2#we*PP_4J6>@6sbyHqj&AYN1E0Zly=8ZKp@P-ARvl zr-vS~v6mjP=@C6*%Md-{{SkV^2jldJ9gpb|JD<`cc0Z>_G{2%p?3<)V9GId^OV`ZcCJNlx99p6JOZ{{+y~UJndc*|&J7cjO^cJJq=n*4Y=@G;3(IbX7(|Db;MGgF+{CRoiT((b;b}D)fq!rRA&rfQJpb_MRmpy7S$O;SX5^WVNsnighh46 z5Ej)LLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D)fq!rRA&rfQJpb_MRmpy z7S$O;SX5^WVNsnighh465Ej)LLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D z)fq!rRA&rfQJpb_MRmpy7S$O;SX5^WVNsnighh465Ej)LLs(R23}I27F@!~R#t;_O z8ADi9XAEIcoiT((b;b}D)fq!rRA&rfQJpb_MRmpy7S$O;SX5^WVNsnighh465Ej)L zLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D)fq!rRA&rfQJpb_MRmpy7S$O; zSX5^WVNsnighh465Ej)LLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D)fq!r eRA&rfQJpb_MRmpy7S$O;SX5^WVUevf=KBjr0er9EN|D$zYke=C0Xjqpq2n?KGNAnWYWdIGPQa6`_>0MOlOt(TS)mIv)^W zJj{%ay4yi_>0pP?5m6cuODxM${R906eQMQM2>N<|xIf(UVFrd7xVYZuW!{Z;xN~Yvt|}rGjaFzmi1*;ebwd$UuCe$v(!Cf+QhS2pW|%i#N(35S4_Ue9PKvE z;q>2+Jv-+}DQJ3if8hDWxjBJ||H0skt7*lpA6`8edU@03yW*^Q_}f_L;)da-v4_9E z?sD%MkJOCbdK2~@{`6sN^!D5SigO7Wfk$`#8uE7*G><>J`|fsdC=d-i9{zh|+i2^@ z@y8?o+}rv5N=EIIKmHxv`);`T^^-r}KW*!XkNY0$?DSCiB;wSK6frKe`hP-Ji}9f{ zc0@tgfS5$gxi*b##RKd~b=4E)HB*f^NVj<|Jj9y?-VEQKAhAxe)J4AUdlche)* zg??Zki-AshM1Kc8V$}_LMBlY!_OV!bnI3WN1$xBt^Yn;i?Q_}3qW3gCV(BS*#F7*A zh@N9f>|@b=gdVZzFg;>n8$DwF!8z<>F>gOTV(vbA#OytZ><8NQD?MUn3q7K92R&kX z6Fp+u_Sx*GOX^m7#FR#Q#N(yGq|MvFr4)8oNoK{IL%DaFTV>7qY&Mk j)EPt6+SD0CSX5^WVNsnighh46 z5Ej)LLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D)fq!rRA&rfQJpb_MRmpy z7S$O;SX5^WVNsnih(&eA0RNJs&KP1WsxyYLsLmL|qB>&;i|ULaEUGhxu&B-$!lF83 z2#e~BAuOshhOns47{a1DV+f1tj3F$lGlsCJ&KSa?I%5cn>Wm>QsxyYLsLmL|qNy_m zn0HZU3^Eqg8AFUkb;b}D)fq!rRA&rfQJpb_MRmpy7S$O;SX5^WVNsnighh465Ej)L zLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;bY|)fq#~7^pLbu&B-$!lF832#e~B zAuOshhOns47{a1DV+f1tj3F$lGlsCJ&KSa?I%5cn>Wm>QsxyYLsLmL|qB>&;i|ULa zEUGhxu&B-$!lF835R2-J0cNk%8AFUkb;b}D)fq!rRA&rfQJpb_MRmpy7S$O;SX5^W KVUeygR`wt5;m*wf literal 0 HcmV?d00001 diff --git a/doc/gifs/7_dusk.gif b/doc/gifs/7_dusk.gif new file mode 100644 index 0000000000000000000000000000000000000000..8e1803f916595f3729908a8ba2fb71e15fd538db GIT binary patch literal 48933 zcmeI5>rc&b9LK*o$tkUfh@EuPY9}SN?6ffLD5r9XTw6`?u^J1cEj9oPG-V)NVu{T&UjFD9-XxSZv=@uu2Q z`t3`U?;CULvum=u+#i}(c#6LcbTxl$E$Xcd&FOCW zJ}r`=FQdBQEDh%;!feFgw}T;wpZ`)%=L-Od0#2H}E5F=11IOcCin78$V(RKVqrb z%|7Tde#CNq#J#4Reb5K^5fAbs9_B|pV)n4F#bf-4$N3RYn!W6UKFyDKjvukg>|-DF z1%AX!{D{?NKl`9-_z`RQ5$ntW_CeQs(Z7tiZlQmUZt$jmBl(8U-;F}j-K)kCTiI`y zo4&>Dh)sSQ*%96TYv~aKir5jG0}I&^TSn)zBi;&H&W?C{>=Jgw*5F0#h;8E+up_pI z}EC zh!5w zi&S5B#FuG4?1-;sSlAK!{yw^}9^ijIV;H-|p0vUL9Qt#S?if5uwGI)o4*I@hBs*gF z^Z<55Ps%8E#Mb07?1(MX#<3$dB~D;RY)GJgFsO^4#BT9QTm(B}wS6)>;>Fk)cEs~B zc6P+G(ednvr=q5^BUVNxu_GQ0r+=@zB8+~=;9w~IzRP~wO!l={K5;fXV%Y>IJK~P< zne2$$g0t8Ww~VDfc(5^u{`kha(e#I4iUR465)}r}AIQr0U&($)FY_y4N6hnG#g4de z#2R+Qc|Pme5nbM!*by@<^yj+Mz35NJ{~IGC-7!#S3{h)SXAEIcoiT((b;b}D)fq!r zRA&rfQJpb_MRmpy7S$O;SX5^WVNsnighh465Ej)LLs(R23}I27F@!~R#t;_O8ADi9 zXAEIcoiT((b;b}D)fq!rRA&rfQJpb_MRmpy7TxNM0X{uUoiW5(RA&rfQJpb_MRmpy z7S$O;SX5^WVNsnigvER6i~(LRsxyXIi|ULaEUGhxu&B-$!lF832#e~BAuOshhOns4 z7{a1DV+f1tj3F$lGlsCJ&KSa?I%5cn>Wm>QsxyYLsLmL|qB>&;i|ULaEUGhxu&B-$ z!lF832#e~BAuOshhOns47{a1DV+f1tj3F$lGX}9}=s#}VX|}Ux`P3OhtVMOk5Ej)L zLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D)fq!rRA&rfQJpb_MRmpy7S$O; zSX5^WVNsnighh465Ej)LLs(R23}I27F@!~R#t;_O8ADi9XAEIcoiT((b;b}D)fq!r NRA&rfk*+hA_7lp;2J`>` literal 0 HcmV?d00001 diff --git a/doc/gifs/8_fireFlicker.gif b/doc/gifs/8_fireFlicker.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7b6ae7970a0ecc50deb720023f1d0ef09db4f89 GIT binary patch literal 47629 zcmeI5S!`5Q9L5J*v4RVVi9SFAF)@ZTgwU9@R#{rQ)6x}6J1sNQc9_x~+EQq$*2WEE zTzK$7j7wFtXjls9qXy9~&}o^abMN%d?cD2~xieF1)hC~n!C*yS`|!I-=arItIp=)e z|NAfZoSeMu)HG|7X+uK4$#nK^(?7qBf37adDlg02S)8?X^Ol4aH~(SdABm>;UnIx> zDE?neNiUjKB(2Lm_u+Q~NozNmN6vk8<&`y$=by?w|MAt=A4@qjGje|L$2T`*o>-T6 z;givmPnHdtM=yLj{_d8#u~T`&pIv`1^+i_1^INZN~ zP>A0?k#HL!brpX|Nu)!(wr%mmLN|KkDf}vazZriP$I|c{?aW+Br;Dc~i4M_UvziW3 zcHB>gsJ1^qhp05&hlgliMTe+1;vs6yct-1;ct%H$;~72o!WueV=3jb<4sqeNhv^W1 zePb;h;%{#~LWlVKJ9vnZK0IA!oAA0QRO6k_jUv2_a2Mip7jNM`bkUjKjZadA-S|{r z+K)er!FoKSwHCZC>RtHgBG=#i&J@cMqk^Gk1npld+7mCsKQqxqy~I7BG~#M zeWQa8ye=9bMhg{qM!WLxy6D@B4}g*lPnSR~eiZ}NcpIVcn;Kdh{w(U<_{1RAhcCy+ z`tUX))`#C{19VcwYP@vIcD(4QZTPbo>c%sAxv8-fBbEkeYDji|9^Hngi`I>|5jwF= z84q~L@gm8s+3E=2jLkOT=^|9)i+AFFe8I%O7oVj1%kgc>nKFEv(vyQ9J$F8fA3gW* zTjqYg=*abW=~i3t0Wj2s_luEUykCs;;#V3N9EO;BST#jFgAs7Rc*T8vL}ASd5=`a_{0#J7wV^PG{d0pR2v~ zgI@aT<3kj3@OLDOe2D&B{3^~?;B`^8;$yVdfbXP+9C(P4jBoaaI`KU~156}`JMksZPz#9xE(2Or63q^R*ab@B~=law5D(&c2Jj6-w7HeHph~y*F=CV!k#jWa1%; zyYLYGS$K%bP4lkX`>zZPZj5SfVXeNS8egj-nnByi1CNP{{`_l5aNGUu@?w2p7AZN z;(R~e=`6gAx3rAu0g#LLTnR@eYf7S34k((Nh5OSdx{Uv_dA;UP{};5XXOf1Fve;G;{R z27eX;e2LDs^~9Yt8rosCVKsz(^M#VmBV50j}i}_Td>F;1}-{{yV9n8J|bH z_TZh4#{jOo5bt!R_>*_zY5e)cO#J+!hd;l#d@IpX+QL h)QG1`xET-80Mqev{735zu!@lue0?$21*_7g{{_VxDDD6N literal 0 HcmV?d00001 diff --git a/doc/gifs/9_bassReact.gif b/doc/gifs/9_bassReact.gif new file mode 100644 index 0000000000000000000000000000000000000000..fc70cc2334aaf91deea89afe6c1ebc88b7e1e2cf GIT binary patch literal 47303 zcmeI*d2AGA7{~EFXJ==Rnb}1YY=wdr1ws%65g~w3X$v+;Eq9U2A{9ARP&{ZsP*9<* zh=ih)g%-+TOAins$WdsE$WcI13V0<((P)f`#whm4N;dvS`p5T4cK#tDkbLqy^UnM3 z?EC(9Xwt)d9+<3J+S{`%mJD^AC49wQ_oO5|mO6OQh=d;9y4$S{e;@a!!{TiCvuoqO zY5Xr1HQQoUV-ia?9$KOXJ5Q)CDLAs+=$M?JSh}fdc#MZ*Ezkmd|O@7h*0u| zbC;lD0Oeg*myuv45pQcCSH(!;+n#JX@g?^xIx$BQ5<9y;+Gvzku)IdGOv{5|+Nop>#9noiv0T}3CZ^DLti59(X##Ea%ZI`R9! zCp@CoK)Ue>@YldO9x?Lc)dk}Ko%ouzkWPFf?0cVr>qcDBwl1fJTp2hSM9}&(Vuc>|t+uGttC^?sn?$=uNL;ijqJl3Yc94 z%+bltLG(rsboQYW@3nWK6Fb;q>BRQ77&@^XpBTq)bUWMa^hV!e4bX``tA|eXSQ@`7 zYQCV0G1cM<3#nVrT^5B-RGN-Lpd0OOIHVE2qW9v>9wu>G9N{8Thf8!sx5TL-0mDVJ zxas$z-|D3ky~H_MZ>ZXh9VWl7bF^;tg@x1!P{4E1 z$A2!ivYPZp$JiRrVl`jT;nKl&M_5Q5F8A2)q!Z)q9q7ciw$^l_fP1l*qZ_@73C{j> zVw#dnCr)*ZrV}&OiFD!=*C;wM(K&!l?Ca=BCl2LTakTOXy^2rqM|74pmtMtO&tf`J zz)6j1{0VTpYXrT~^VDf{qJX`$0!~vF`SR$E7H|-LgLehJiUK|uEOO7JSFzal4xL!5 z@1_$4oR1c8RPl;gMQ`*0e<7VXm%q|kraecm;vRniop_F)?Ia*j?kfMGBj9{=h@S+r zFnaj-rZyf#287h;rS#|G74s;ac#R)G{7ayYUPS?qZUM`P7u`?O8=cR88*xs|S_lvJ;&(f12> z=t`wmQ9zu)0{0Ah6$`v?(TRKgo9M(6-+DSx!0#B$cW2P6C?I{KKR@y(MHxbG^b@YJ zbmA;^GMzZdl}0BD*r?jo-icmC0Vg#&+wY=RvA3f;ojAnVk4_XYq6GxXb+O0O8!aG} zC}=h4RYb-KM1I+eJRco-5I!25)DrI(1%%ZI$aWHNFA9hg@bc5z1Vmc|`JoK0_{o8W z)lXkWAm`}FWrTptI{~u`GTSM#(E^@}0)mqSJi7h-Y$pM+d;;(lVv(+i|Mi=^W>BQP-0C5Y%I189vR(oEi--`lvI}LL7rB`v7^C3Dh UlmAiwb!{QNig})F7V*J<0YeWfB>(^b literal 0 HcmV?d00001 diff --git a/tools/gifgen/.gitignore b/tools/gifgen/.gitignore new file mode 100644 index 0000000..d5ca8fa --- /dev/null +++ b/tools/gifgen/.gitignore @@ -0,0 +1,6 @@ +# Compiled host shared library - platform-specific build output of +# build.sh, not something to commit (generate.py rebuilds it automatically +# if missing or stale). +libmodes.so +libmodes.dylib +__pycache__/ diff --git a/tools/gifgen/build.sh b/tools/gifgen/build.sh new file mode 100755 index 0000000..9bc0fdc --- /dev/null +++ b/tools/gifgen/build.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# Compiles the REAL AnimationHandler/AnimationHandlerBus mode source (plus +# ModeMath and this directory's harness) into a host shared library, +# libmodes.so/.dylib, that generate.py loads via ctypes to render doc GIFs. +# +# Include order matters: tools/gifgen/shim/ must resolve `#include +# ` / `#include ` to OUR stand-ins, not any real +# Arduino core/FastLED - but since we never add a path to those, there's +# nothing to shadow, just something to provide. +# +# mode 3 (SOUND_2_LIGHT)'s real source depends on the arduinoFFT third-party +# library and is a stub that always returns black anyway - deliberately not +# compiled here; harness.cpp provides a matching black-returning definition +# of AnimationHandler::sound2Light() just to satisfy the linker (see the +# comment there). Mode 1 (BLINK_COLOR) is a dependency-free stub and IS +# compiled normally. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +SOFTWARE_LIB="$REPO_ROOT/software/lib" +SOFTWARE_CONFIG="$REPO_ROOT/software/config" + +OUT="$SCRIPT_DIR/libmodes.so" + +SOURCES=( + "$SCRIPT_DIR/harness.cpp" + "$SOFTWARE_LIB/ModeMath/ModeMath.cpp" + "$SOFTWARE_LIB/AnimationHandler/AnimationHandler.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/0_fade2Color.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/1_blinkColor.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/2_strobe.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/4_breathe.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/5_ocean.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/6_forest.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/7_dusk.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/8_fireFlicker.cpp" + "$SOFTWARE_LIB/AnimationHandler/Modes/9_bassReact.cpp" + "$SOFTWARE_LIB/AnimationHandlerBus/AnimationHandlerBus.cpp" + "$SOFTWARE_LIB"/AnimationHandlerBus/Modes/*.cpp +) + +g++ -shared -fPIC -std=gnu++17 -Wall \ + -I "$SCRIPT_DIR/shim" \ + -I "$SOFTWARE_LIB/Definitions" \ + -I "$SOFTWARE_CONFIG" \ + -I "$SOFTWARE_LIB/ModeMath" \ + -I "$SOFTWARE_LIB/AnimationHandler" \ + -I "$SOFTWARE_LIB/AnimationHandlerBus" \ + "${SOURCES[@]}" \ + -o "$OUT" + +echo "Built $OUT" diff --git a/tools/gifgen/generate.py b/tools/gifgen/generate.py new file mode 100644 index 0000000..03f6935 --- /dev/null +++ b/tools/gifgen/generate.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +"""Generates a real animated GIF preview per LED-strip mode, driven by the +ACTUAL C++ mode-rendering code in software/lib/AnimationHandler(Bus)/ - not +a stand-in. See tools/gifgen/shim/ (host stand-ins for Arduino.h/FastLED.h) +and tools/gifgen/harness.cpp (the ctypes entry point, render_mode()) for how +that real code gets compiled and driven on a plain host. + +Usage: python3 tools/gifgen/generate.py +(also wired up as `make doc-gifs` at the repo root) + +For each mode this script: + 1. Builds tools/gifgen/libmodes.so if it's missing/stale (via build.sh). + 2. Calls render_mode() via ctypes with the SAME example `silo` field values + already documented in software/README.md's per-mode JSON examples, for + a 100-LED strip, 15 simulated seconds at 20fps (300 frames). + 3. Lays out each frame's 100 RGB triples as 100 stacked 8x8 boxes in an + 8x800 image (one box per LED) and saves the animation to + doc/gifs/_.gif. + +Two modes are skipped entirely rather than producing a meaningless +all-black GIF: BLINK_COLOR (1) and SOUND_2_LIGHT (3) are both real stubs in +the source that always return black regardless of input (see their +Modes/*.cpp files and software/README.md's "Stub only" notes) - see +SKIPPED_STUB_MODES below. +""" +import ctypes +import os +import subprocess +import sys + +from PIL import Image, ImageDraw + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "..")) +LIB_PATH = os.path.join(SCRIPT_DIR, "libmodes.so") +BUILD_SCRIPT = os.path.join(SCRIPT_DIR, "build.sh") +OUT_DIR = os.path.join(REPO_ROOT, "doc", "gifs") + +# Preview render geometry: one LED == one 8x8 box, stacked vertically. +STRIP_LENGTH = 100 +WIDTH = 8 +BOX_SIZE = 8 +NUM_BOXES = STRIP_LENGTH +HEIGHT = BOX_SIZE * NUM_BOXES + +# 15 simulated seconds at 20fps. +FRAME_INTERVAL_MS = 50 +NUM_FRAMES = 300 +GIF_DURATION_MS = 50 + +# Stub modes that always render black regardless of input - see +# software/lib/AnimationHandler/Modes/1_blinkColor.cpp and +# .../3_sound2Light.cpp, and their "Stub only" notes in software/README.md. +SKIPPED_STUB_MODES = {1: "BLINK_COLOR", 3: "SOUND_2_LIGHT"} + +# Per-mode example silo values. Every entry's kwargs are copied verbatim +# from the JSON example already documented for that mode in +# software/README.md's big HTML modes table, so the generated GIF matches +# the documented example exactly. The two exceptions are BASS_REACT (9) and +# VU_METER_PEAK (111): as of this writing software/README.md's table has no +# row at all for either (only goes 0-8, then 100-110) - these are real, +# non-stub modes, so rather than skip them the values below were chosen by +# hand, following the style of their nearest sibling mode (VU_METER's +# color/sensitivity/frequency triple). +# +# `filename` matches the mode's own Modes/_.cpp convention. +MODES = [ + {"id": 0, "filename": "0_fade2Color", "color": (1023, 400, 60, 0, 0), "time": 2000}, + {"id": 2, "filename": "2_strobe", "color": (1023, 0, 850, 0, 0), "frequency": 10}, + {"id": 4, "filename": "4_breathe", "color": (550, 0, 1023, 0, 0), "time": 4000, + "minBrightnes": 100, "maxBrightnes": 900, "timeVariance": 500, "maxBrightnesVariance": 100}, + {"id": 5, "filename": "5_ocean", "time": 6000}, + {"id": 6, "filename": "6_forest", "time": 6000}, + {"id": 7, "filename": "7_dusk", "time": 6000}, + {"id": 8, "filename": "8_fireFlicker", "frequency": 15}, + # Not in software/README.md's table (see note above) - hand-chosen. + {"id": 9, "filename": "9_bassReact", "color": (1023, 80, 900, 0, 0), "frequency": 20, "sensitivity": 200}, + {"id": 100, "filename": "100_wipe", "color": (50, 1023, 150, 0, 0), "time": 1500}, + {"id": 101, "filename": "101_fire", "frequency": 30, "position": 0}, + {"id": 102, "filename": "102_noise", "color": (200, 220, 1023, 0, 0), "frequency": 20}, + {"id": 103, "filename": "103_vuMeter", "color": (1023, 250, 0, 0, 0), "sensitivity": 200, "frequency": 30}, + {"id": 104, "filename": "104_strobeParts", "color": (1023, 0, 0, 0, 0), "length": 5, "frequency": 4}, + {"id": 105, "filename": "105_movingParts", "color": (0, 1023, 0, 0, 0), "length": 8, "time": 2000}, + {"id": 106, "filename": "106_rainbowCycle", "time": 4000}, + {"id": 107, "filename": "107_theaterChase", "color": (1023, 1023, 1023, 0, 0), "time": 100}, + {"id": 108, "filename": "108_comet", "color": (0, 600, 1023, 0, 0), "time": 1500}, + # PIXEL_ARRAY isn't driven by silo fields at all - see harness.cpp's + # special-case, which feeds it a fixed every-5th-LED-lit pattern via + # setPixelData() instead. + {"id": 109, "filename": "109_pixelArray"}, + {"id": 110, "filename": "110_nightSky", "length": 6, "frequency": 20, "minBrightnes": 100, "maxBrightnes": 800}, + # Not in software/README.md's table (see note above) - hand-chosen, + # mirroring VU_METER's params since VU_METER_PEAK is the same bar-graph + # body plus a peak-hold LED (see its source comment). + {"id": 111, "filename": "111_vuMeterPeak", "color": (1023, 250, 0, 0, 0), "sensitivity": 200, "frequency": 30}, +] + + +def ensure_lib_built(): + need_build = True + if os.path.exists(LIB_PATH): + lib_mtime = os.path.getmtime(LIB_PATH) + src_mtimes = [os.path.getmtime(os.path.join(SCRIPT_DIR, "harness.cpp"))] + for root, _, files in os.walk(os.path.join(SCRIPT_DIR, "shim")): + for f in files: + src_mtimes.append(os.path.getmtime(os.path.join(root, f))) + need_build = lib_mtime < max(src_mtimes) + + if need_build: + print("Building tools/gifgen/libmodes.so ...") + subprocess.run(["bash", BUILD_SCRIPT], check=True) + + +def load_lib(): + lib = ctypes.CDLL(LIB_PATH) + lib.render_mode.restype = ctypes.c_int + lib.render_mode.argtypes = [ + ctypes.c_int, ctypes.c_uint, # modeId, stripLength + ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, # color r,g,b,ww,cw + ctypes.c_uint, ctypes.c_uint, ctypes.c_ubyte, # time, frequency, sensitivity + ctypes.c_uint, ctypes.c_uint, # position, length + ctypes.c_uint, ctypes.c_uint, # minBrightnes, maxBrightnes + ctypes.c_uint, ctypes.c_uint, # timeVariance, maxBrightnesVariance + ctypes.c_ulong, ctypes.c_uint, # frameIntervalMs, numFrames + ctypes.POINTER(ctypes.c_uint8), # outFrames + ] + return lib + + +def render_mode_frames(lib, mode): + color = mode.get("color", (0, 0, 0, 0, 0)) + buf_type = ctypes.c_uint8 * (STRIP_LENGTH * 3 * NUM_FRAMES) + buf = buf_type() + + ret = lib.render_mode( + mode["id"], STRIP_LENGTH, + color[0], color[1], color[2], color[3], color[4], + mode.get("time", 0), mode.get("frequency", 0), mode.get("sensitivity", 0), + mode.get("position", 0), mode.get("length", 0), + mode.get("minBrightnes", 0), mode.get("maxBrightnes", 0), + mode.get("timeVariance", 0), mode.get("maxBrightnesVariance", 0), + FRAME_INTERVAL_MS, NUM_FRAMES, + buf, + ) + if ret != 0: + raise RuntimeError(f"render_mode() failed for mode {mode['id']} ({mode['filename']}), ret={ret}") + return bytes(buf) + + +def frame_to_image(frame_bytes): + img = Image.new("RGB", (WIDTH, HEIGHT)) + draw = ImageDraw.Draw(img) + for i in range(NUM_BOXES): + r, g, b = frame_bytes[i*3], frame_bytes[i*3+1], frame_bytes[i*3+2] + y0 = i * BOX_SIZE + draw.rectangle([0, y0, WIDTH - 1, y0 + BOX_SIZE - 1], fill=(r, g, b)) + return img + + +def main(): + ensure_lib_built() + lib = load_lib() + os.makedirs(OUT_DIR, exist_ok=True) + + print(f"Skipping stub modes (always render black): {SKIPPED_STUB_MODES}") + + for mode in MODES: + print(f"Rendering mode {mode['id']} ({mode['filename']}) ...") + raw = render_mode_frames(lib, mode) + + frames = [] + for f in range(NUM_FRAMES): + off = f * STRIP_LENGTH * 3 + frames.append(frame_to_image(raw[off:off + STRIP_LENGTH * 3])) + + out_path = os.path.join(OUT_DIR, f"{mode['filename']}.gif") + frames[0].save( + out_path, + save_all=True, + append_images=frames[1:], + duration=GIF_DURATION_MS, + loop=0, + optimize=False, + ) + size_kb = os.path.getsize(out_path) / 1024.0 + print(f" -> {os.path.relpath(out_path, REPO_ROOT)} ({len(frames)} frames, {size_kb:.1f} KiB)") + + print("Done.") + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/gifgen/harness.cpp b/tools/gifgen/harness.cpp new file mode 100644 index 0000000..4763c4d --- /dev/null +++ b/tools/gifgen/harness.cpp @@ -0,0 +1,176 @@ +// Host-side harness that drives the REAL AnimationHandlerBus dispatch code +// (software/lib/AnimationHandlerBus/AnimationHandlerBus.cpp, which routes +// both uniform modes [<100, via getNewColor()+fill_solid] and addressable +// modes [>=100, via getNewStripBuffer()] through one real handle() call) to +// render each LED-strip mode's actual output, frame by frame, for +// tools/gifgen/generate.py to turn into a GIF via ctypes. +// +// Compiled together with the real mode source under +// software/lib/AnimationHandler(Bus)/{.,/Modes/*.cpp} and ModeMath against +// the host shim headers in tools/gifgen/shim/ (Arduino.h/FastLED.h), which +// stand in for the ESP8266 Arduino core / FastLED so this all builds with +// plain g++ - see tools/gifgen/build.sh. +#include +#include + +#include +#include +#include +#include +#include +#include + +// Defined here (not in the shim headers) since the harness owns the fake +// clock/ADC state that render_mode() drives per frame. +unsigned long g_fakeMillis = 0; +int g_fakeAnalogValue = 512; + +// The real debugFkt() lives in software/src/main.cpp, which isn't part of +// this build; AnimationHandler.h/AnimationHandlerBus.cpp both just +// `extern void debugFkt(String, LogLevel);`, so provide a definition here +// to satisfy the linker. Logs to stderr rather than being a pure no-op, so +// mode ERROR/WARNING logs (e.g. "frequency 0 rejected") are visible while +// iterating on the harness - doesn't affect the rendered frames either way. +void debugFkt(String message, LogLevel level){ + static const char* names[] = {"VERBOSE", "DEBUG", "INFO", "WARNING", "ERROR"}; + if(level >= WARNING){ + fprintf(stderr, "[%s] %s\n", names[level], message.c_str()); + } +} + +// AnimationHandler::sound2Light() (mode 3, SOUND_2_LIGHT) is a stub that +// always returns black regardless of input - see +// software/lib/AnimationHandler/Modes/3_sound2Light.cpp. Its real +// implementation depends on the arduinoFFT third-party library, which this +// harness deliberately does NOT link in (mode 3 is explicitly excluded from +// GIF generation - see generate.py/README - and the arduinoFFT dependency +// would add a whole extra library just to render permanent black). +// AnimationHandlerBus::getNewColor()'s switch statement still has a case +// that calls this symbol though, so the linker needs a definition for it +// even though no rendered mode ever reaches it. This reproduces the real +// stub's exact behavior (always black), just without the FFT machinery +// around it. +CRGBWW AnimationHandler::sound2Light(){ + return CRGBWW{0, 0, 0, 0, 0}; +} + +extern "C" { + +// Renders `numFrames` frames of `modeId` at `frameIntervalMs` simulated-time +// steps for a `stripLength`-LED WS2812 strip, writing stripLength*3 bytes +// (R,G,B per LED, 0-255) per frame into outFrames (caller-allocated, sized +// numFrames*stripLength*3). silo fields map 1:1 onto varSilo (see +// software/lib/Definitions/TypeDefinitions.h) so Python can pass the exact +// example values already documented per-mode in software/README.md. +// +// Every mode - uniform (<100) and addressable (>=100) alike - is routed +// through one real AnimationHandlerBus::handle() call per frame; that's the +// same dispatch the real firmware uses, so there's no special-casing needed +// beyond PIXEL_ARRAY (109), which needs an explicit setPixelData() payload +// since it isn't driven by the other silo fields at all. +int render_mode(int modeId, unsigned int stripLength, + unsigned int color_r, unsigned int color_g, unsigned int color_b, + unsigned int color_ww, unsigned int color_cw, + unsigned int time, unsigned int frequency, unsigned char sensitivity, + unsigned int position, unsigned int length, + unsigned int minBrightnes, unsigned int maxBrightnes, + unsigned int timeVariance, unsigned int maxBrightnesVariance, + unsigned long frameIntervalMs, unsigned int numFrames, + uint8_t* outFrames){ + if(stripLength == 0 || numFrames == 0 || outFrames == nullptr || frameIntervalMs == 0){ + return -1; + } + + varSilo silo; + memset(&silo, 0, sizeof(silo)); + silo.mode = (unsigned char)modeId; + silo.colorValue = CRGBWW{color_r, color_g, color_b, color_ww, color_cw}; + silo.time = time; + silo.frequency = frequency; + silo.sensitivity = sensitivity; + silo.position = position; + silo.length = length; + silo.minBrightnes = minBrightnes; + silo.maxBrightnes = maxBrightnes; + silo.timeVariance = timeVariance; + silo.maxBrightnesVariance = maxBrightnesVariance; + + bool varSiloChanged = true; // fires each mode's internal "just switched" reset logic + stripType st = WS2812_STRIP; + + g_fakeMillis = 0; + g_fakeAnalogValue = 512; + srand(1234); // fixed seed so re-running generate.py reproduces the same GIF bytes + + // Construct AnimationHandlerBus over explicitly-zeroed storage rather than + // a plain stack allocation. This matters because AnimationHandler (its + // private base) declares `float audioRingBuffer[ringBufferSize];` with NO + // default member initializer, and its constructor never touches it - on + // the real device that class is a static/global-duration object, so the + // C++ runtime zero-initializes its storage before the constructor runs + // (audioBias, by contrast, does have an in-class initializer, so it's + // fine either way). A raw stack object here would leave audioRingBuffer + // as indeterminate stack garbage, making the audio-reactive modes + // (BASS_REACT/VU_METER/VU_METER_PEAK) noticeably non-deterministic + // depending on what a *previous* render_mode() call happened to leave on + // the stack. calloc + placement-new reproduces the real zero-init + // semantics instead. + void* busStorage = calloc(1, sizeof(AnimationHandlerBus)); + AnimationHandlerBus* bus = new (busStorage) AnimationHandlerBus(&st, stripLength, &silo, &varSiloChanged); + + // PIXEL_ARRAY (109) doesn't animate from silo fields at all - it just + // replays whatever raw per-LED payload was last pushed via + // setPixelData() (normally delivered over the /pixels MQTT topic). Feed + // it a simple deterministic pattern - every 5th LED lit amber - purely so + // the preview isn't a blank frame; this is the one mode where the + // "silo example values" input model doesn't apply. + if(modeId == PIXEL_ARRAY){ + std::vector pattern(stripLength * 3, 0); + for(unsigned int i = 0; i < stripLength; i++){ + if(i % 5 == 0){ + pattern[i*3 + 0] = 255; + pattern[i*3 + 1] = 170; + pattern[i*3 + 2] = 0; + } + } + bus->setPixelData(pattern.data(), stripLength * 3); + } + + for(unsigned int f = 0; f < numFrames; f++){ + g_fakeMillis += frameIntervalMs; + + // Synthetic "simulated microphone" signal for the audio-reactive modes + // (BASS_REACT, VU_METER, VU_METER_PEAK): there's no real mic on a host + // machine, so drive analogRead() with a couple of summed sine waves + // plus jitter, scaled into the ESP8266 ADC's 0-1023 range. Modes that + // don't read analogRead() are unaffected. + double t = g_fakeMillis / 1000.0; + // Slow "loudness" envelope (6s period) on top of the two summed tones, + // so the audio-reactive modes visibly rise and fall over the 15s + // preview instead of saturating the gain in ~1s and holding flat. + double envelope = 0.5 + 0.5 * sin(t * 2.0 * M_PI / 6.0); + double wave = (sin(t * 2.0 * M_PI * 1.3) * 0.5 + sin(t * 2.0 * M_PI * 3.7) * 0.2) * envelope; + int jitter = (rand() % 41) - 20; // +/-20 + int analogValue = 512 + (int)(wave * 400.0) + jitter; + if(analogValue < 0) analogValue = 0; + if(analogValue > 1023) analogValue = 1023; + g_fakeAnalogValue = analogValue; + + bus->handle(); + + uint8_t* dst = outFrames + (size_t)f * stripLength * 3; + for(unsigned int i = 0; i < stripLength; i++){ + CRGB c = (gifgen_ledsPtr != nullptr && i < gifgen_ledsCount) ? gifgen_ledsPtr[i] : CRGB(0, 0, 0); + dst[i*3 + 0] = c.r; + dst[i*3 + 1] = c.g; + dst[i*3 + 2] = c.b; + } + } + + bus->~AnimationHandlerBus(); + free(busStorage); + + return 0; +} + +} // extern "C" diff --git a/tools/gifgen/requirements.txt b/tools/gifgen/requirements.txt new file mode 100644 index 0000000..7e2fba5 --- /dev/null +++ b/tools/gifgen/requirements.txt @@ -0,0 +1 @@ +Pillow diff --git a/tools/gifgen/shim/Arduino.h b/tools/gifgen/shim/Arduino.h new file mode 100644 index 0000000..5d226e5 --- /dev/null +++ b/tools/gifgen/shim/Arduino.h @@ -0,0 +1,100 @@ +// Minimal host-side stand-in for the Arduino core, just enough of a subset +// to compile the REAL AnimationHandler/AnimationHandlerBus mode code +// (software/lib/AnimationHandler, software/lib/AnimationHandlerBus) on a +// plain gcc/g++ host for tools/gifgen's doc-GIF renderer. Not a general +// Arduino emulation - only implements the exact symbols those files use +// (see tools/gifgen/README-ish notes in generate.py / the task that +// produced this). +// +// This header must resolve before any real Arduino core header could - +// tools/gifgen's build only ever puts this shim directory on the include +// path (never the real Arduino core), so there's nothing to shadow, just +// something to provide. +#ifndef GIFGEN_SHIM_ARDUINO_H +#define GIFGEN_SHIM_ARDUINO_H + +#include +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// Fake time base. Real millis() is wall-clock; here it reads a global the +// harness advances one simulated frame at a time (see harness.cpp), so a +// mode's "15 real-world seconds" plays out deterministically regardless of +// how long rendering actually takes on this machine. +// --------------------------------------------------------------------------- +extern unsigned long g_fakeMillis; +inline unsigned long millis() { return g_fakeMillis; } + +// --------------------------------------------------------------------------- +// Fake analog input. Real analogRead() reads the mic on A0; here it reads a +// global the harness drives with a synthetic "simulated microphone" signal +// each frame so the audio-reactive modes (BASS_REACT, VU_METER, +// VU_METER_PEAK) have something to react to. Defaults to ESP8266's ADC +// mid-scale (0-1023 range). +// --------------------------------------------------------------------------- +extern int g_fakeAnalogValue; +#define A0 0 +inline int analogRead(int /*pin*/) { return g_fakeAnalogValue; } + +// --------------------------------------------------------------------------- +// Arduino math helpers actually used by the mode code. +// --------------------------------------------------------------------------- +template +inline T constrain_(T x, T lo, T hi) { return x < lo ? lo : (x > hi ? hi : x); } + +inline long map(long x, long in_min, long in_max, long out_min, long out_max) { + if (in_max == in_min) return out_min; + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +// --------------------------------------------------------------------------- +// Minimal Arduino String. Only supports what this codebase actually does +// with it: building up log lines for debugFkt() out of numbers/strings via +// '+'/'+=', and .c_str(). Not a full reimplementation. +// --------------------------------------------------------------------------- +class String { + public: + String() : s_() {} + String(const char* cstr) : s_(cstr ? cstr : "") {} + String(char c) : s_(1, c) {} + String(const String& other) : s_(other.s_) {} + + String(int v) { s_ = std::to_string(v); } + String(unsigned int v) { s_ = std::to_string(v); } + String(long v) { s_ = std::to_string(v); } + String(unsigned long v) { s_ = std::to_string(v); } + + // Arduino's String(floatVal, decimalPlaces) - decimalPlaces defaults to 2. + explicit String(float v, unsigned int decimalPlaces = 2) { + char buf[64]; + snprintf(buf, sizeof(buf), "%.*f", decimalPlaces, (double)v); + s_ = buf; + } + explicit String(double v, unsigned int decimalPlaces = 2) { + char buf[64]; + snprintf(buf, sizeof(buf), "%.*f", decimalPlaces, v); + s_ = buf; + } + + const char* c_str() const { return s_.c_str(); } + size_t length() const { return s_.size(); } + + String& operator+=(const String& rhs) { s_ += rhs.s_; return *this; } + String& operator+=(const char* rhs) { s_ += rhs; return *this; } + + String operator+(const String& rhs) const { return String((s_ + rhs.s_).c_str()); } + String operator+(const char* rhs) const { return String((s_ + rhs).c_str()); } + + private: + std::string s_; +}; + +inline String operator+(const char* lhs, const String& rhs) { + return String((std::string(lhs) + rhs.c_str()).c_str()); +} + +#endif diff --git a/tools/gifgen/shim/FastLED.h b/tools/gifgen/shim/FastLED.h new file mode 100644 index 0000000..2f4ec99 --- /dev/null +++ b/tools/gifgen/shim/FastLED.h @@ -0,0 +1,220 @@ +// Minimal host-side stand-in for FastLED, just enough of a subset to compile +// the REAL AnimationHandlerBus mode code (software/lib/AnimationHandlerBus) +// on a plain gcc/g++ host for tools/gifgen's doc-GIF renderer. Reimplements +// the handful of FastLED primitives those files actually call - see the +// grep sweep in the task that produced this file for the exact symbol list. +// +// HeatColor() intentionally reimplements FastLED's real 3-stage +// black->red->orange->yellow->white ramp (scale8_video + the 3-band split) +// since fire.cpp's look depends on it. fill_rainbow()/blend()/etc. are +// "close enough for a documentation preview" reimplementations, not +// pixel-identical to FastLED's own approximations. +#ifndef GIFGEN_SHIM_FASTLED_H +#define GIFGEN_SHIM_FASTLED_H + +#include +#include +#include + +// --------------------------------------------------------------------------- +// CRGB +// --------------------------------------------------------------------------- +struct CRGB { + uint8_t r, g, b; + + CRGB() : r(0), g(0), b(0) {} + CRGB(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {} + + static const CRGB Black; + static const CRGB White; + static const CRGB Blue; + + bool operator==(const CRGB& o) const { return r == o.r && g == o.g && b == o.b; } + bool operator!=(const CRGB& o) const { return !(*this == o); } +}; + +inline const CRGB CRGB::Black{0, 0, 0}; +inline const CRGB CRGB::White{255, 255, 255}; +inline const CRGB CRGB::Blue{0, 0, 255}; + +// --------------------------------------------------------------------------- +// Dummy chipset / color-order tag types - only need to exist so the +// FastLED.addLeds(...) / +// template calls compile. Behavior-wise they're inert on the host: the +// "strip" is just the CRGB buffer itself, there's no real bus to drive. +// --------------------------------------------------------------------------- +struct WS2812 {}; +struct APA102 {}; +struct GRB {}; + +// --------------------------------------------------------------------------- +// scale8 / scale8_video - FastLED's actual 8-bit fixed-point scaling helpers, +// needed for a faithful HeatColor(). +// --------------------------------------------------------------------------- +inline uint8_t scale8(uint8_t i, uint8_t scale) { + return (uint8_t)(((uint16_t)i * (uint16_t)scale) >> 8); +} + +inline uint8_t scale8_video(uint8_t i, uint8_t scale) { + uint8_t j = (uint8_t)(((int)i * (int)scale) >> 8); + if (i && scale) j++; + return j; +} + +// --------------------------------------------------------------------------- +// qsub8 / qadd8 - saturating 8-bit subtract/add. +// --------------------------------------------------------------------------- +inline uint8_t qsub8(uint8_t a, uint8_t b) { return (a > b) ? (uint8_t)(a - b) : 0; } +inline uint8_t qadd8(uint8_t a, uint8_t b) { + unsigned int sum = (unsigned int)a + (unsigned int)b; + return sum > 255 ? 255 : (uint8_t)sum; +} + +// --------------------------------------------------------------------------- +// HeatColor - FastLED's real fire-palette ramp: black -> red -> orange -> +// yellow -> white, in three equal bands of the input range. +// --------------------------------------------------------------------------- +inline CRGB HeatColor(uint8_t temperature) { + CRGB heatcolor; + + uint8_t t192 = scale8_video(temperature, 191); + uint8_t heatramp = t192 & 0x3F; // 0..63 + heatramp <<= 2; // scale up to 0..252 + + if (t192 & 0x80) { + // hottest third: full red, full green, ramp blue + heatcolor.r = 255; + heatcolor.g = 255; + heatcolor.b = heatramp; + } else if (t192 & 0x40) { + // middle third: full red, ramp green, no blue + heatcolor.r = 255; + heatcolor.g = heatramp; + heatcolor.b = 0; + } else { + // coolest third: ramp red, no green, no blue + heatcolor.r = heatramp; + heatcolor.g = 0; + heatcolor.b = 0; + } + return heatcolor; +} + +// --------------------------------------------------------------------------- +// blend - linear per-channel interpolation between two colors. +// --------------------------------------------------------------------------- +inline CRGB blend(const CRGB& a, const CRGB& b, uint8_t amountOfB) { + uint16_t amt = amountOfB; + CRGB out; + out.r = (uint8_t)(((uint16_t)a.r * (255 - amt) + (uint16_t)b.r * amt) / 255); + out.g = (uint8_t)(((uint16_t)a.g * (255 - amt) + (uint16_t)b.g * amt) / 255); + out.b = (uint8_t)(((uint16_t)a.b * (255 - amt) + (uint16_t)b.b * amt) / 255); + return out; +} + +// --------------------------------------------------------------------------- +// fill_solid / fadeToBlackBy +// --------------------------------------------------------------------------- +inline void fill_solid(CRGB* leds, int count, const CRGB& color) { + for (int i = 0; i < count; i++) leds[i] = color; +} + +inline void fadeToBlackBy(CRGB* leds, int count, uint8_t fadeBy) { + uint8_t keep = 255 - fadeBy; + for (int i = 0; i < count; i++) { + leds[i].r = scale8(leds[i].r, keep); + leds[i].g = scale8(leds[i].g, keep); + leds[i].b = scale8(leds[i].b, keep); + } +} + +// --------------------------------------------------------------------------- +// fill_rainbow - reasonable hue sweep (full saturation/value color wheel). +// Not pixel-identical to FastLED's own HSV approximation, which is fine for +// a documentation preview. +// --------------------------------------------------------------------------- +inline CRGB gifgen_hueToRGB(uint8_t hue) { + uint8_t region = hue / 43; // 0..5 + uint8_t remainder = (hue - region * 43) * 6; + uint8_t q = 255 - remainder; + switch (region) { + case 0: return CRGB(255, remainder, 0); + case 1: return CRGB(q, 255, 0); + case 2: return CRGB(0, 255, remainder); + case 3: return CRGB(0, q, 255); + case 4: return CRGB(remainder, 0, 255); + default: return CRGB(255, 0, q); + } +} + +inline void fill_rainbow(CRGB* leds, int count, uint8_t startHue, uint8_t deltaHue) { + uint8_t hue = startHue; + for (int i = 0; i < count; i++) { + leds[i] = gifgen_hueToRGB(hue); + hue = (uint8_t)(hue + deltaHue); + } +} + +// --------------------------------------------------------------------------- +// cos16 - FastLED's 16-bit-angle cosine, used by breathe(). Doesn't need to +// bit-match FastLED's own lookup-table approximation, just be a proper +// cosine over the same [0, 65536) -> [-32767, 32767] mapping. +// --------------------------------------------------------------------------- +inline int16_t cos16(uint16_t theta) { + double rad = (theta / 65536.0) * 2.0 * M_PI; + return (int16_t)(cos(rad) * 32767.0); +} + +// --------------------------------------------------------------------------- +// random8 / random16 - thin wrappers over rand(), seeded once by the +// harness (see harness.cpp's render_mode(), which reseeds deterministically +// per render so GIFs are reproducible across runs). +// --------------------------------------------------------------------------- +inline uint8_t random8() { return (uint8_t)(rand() & 0xFF); } +inline uint8_t random8(uint8_t max) { + if (max == 0) return 0; + return (uint8_t)(rand() % max); +} +inline uint8_t random8(uint8_t min, uint8_t max) { + if (max <= min) return min; + return (uint8_t)(min + (rand() % (max - min))); +} +// Real FastLED signature is uint16_t random16(uint16_t, uint16_t); callers +// in this codebase sometimes pass negative int literals (e.g. +// random16(-silo->timeVariance, silo->timeVariance) in breathe.cpp), which +// wrap the same way here as they would against the real FastLED header. +inline uint16_t random16(uint16_t min, uint16_t max) { + if (max <= min) return min; + return (uint16_t)(min + (rand() % (uint16_t)(max - min))); +} + +// --------------------------------------------------------------------------- +// Dummy FastLED global object. addLeds<...>() just records the leds +// pointer/count for the harness to read directly (see gifgen_ledsPtr / +// gifgen_ledsCount below) - avoids needing any access to +// AnimationHandlerBus's private `leds` member. show() is a no-op; the +// harness reads the buffer straight out of memory after each handle() call. +// --------------------------------------------------------------------------- +inline CRGB* gifgen_ledsPtr = nullptr; +inline unsigned int gifgen_ledsCount = 0; + +struct CFastLED { + // WS2812-style clockless chipsets: addLeds + template + void addLeds(CRGB* leds, int count) { + gifgen_ledsPtr = leds; + gifgen_ledsCount = (unsigned int)count; + } + // APA102-style SPI chipsets: addLeds + template + void addLeds(CRGB* leds, int count) { + gifgen_ledsPtr = leds; + gifgen_ledsCount = (unsigned int)count; + } + + void show() { /* no-op: harness reads gifgen_ledsPtr directly */ } +}; + +inline CFastLED FastLED; + +#endif From 575245d7b0b5b6f1a0d4b3e84f9f7a05d9577103 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 02:52:11 +0200 Subject: [PATCH 17/39] 1 Add missing BASS_REACT/VU_METER_PEAK rows to README modes table 2 3 Part H (modes 9 and 111) landed after the README's mode table was 4 written, so it silently jumped 0-8 then 100-110 with no rows for either. 5 Add both, wired to the GIF-pipeline previews already generated for them, 6 and fix the parameter table's "used by modes" lists and the "uniform 7 modes (0-8)" range to include mode 9. 8 9 Co-Authored-By: Claude Sonnet 5 --- software/README.md | 62 +++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/software/README.md b/software/README.md index 4a9e3bc..3517497 100644 --- a/software/README.md +++ b/software/README.md @@ -57,10 +57,10 @@ Addressable strips also accept a second, binary payload on a dedicated sub-topic | Function | Topic | Values | Used by modes | |--------------------------------------------|--------------------------|---------------------|---------------| | Change Mode | mode | see [Modes](#modes) below | all | -| Color amplitudes | color[ R,G,B,WW,CW ] | 10 bit integer (0-1023) | 0, 2, 4, 100, 102, 103, 104, 105, 107, 108 | +| Color amplitudes | color[ R,G,B,WW,CW ] | 10 bit integer (0-1023) | 0, 2, 4, 9, 100, 102, 103, 104, 105, 107, 108, 111 | | Timeframe in milliseconds (speed, mode specific) | time | unsigned integer | 0 (fade), 4 (period), 5/6/7 (gradient cycle), 100 (traversal), 105 (traversal), 106 (hue cycle), 107 (step interval), 108 (traversal) | -| Frequency in hertz | frequency | unsigned integer, 1-60 | 2, 8, 101, 102, 103, 104, 110 | -| Relative sensitivity / gain | sensitivity | __unsigned char (0-255)__ — see note | 103 | +| Frequency in hertz | frequency | unsigned integer, 1-60 | 2, 8, 9, 101, 102, 103, 104, 110, 111 | +| Relative sensitivity / gain | sensitivity | __unsigned char (0-255)__ — see note | 9, 103, 111 | | Number of LEDs / max count (mode specific) | length | unsigned integer | 104 (block size), 105 (block size), 110 (max concurrent stars) | | Select side/anchor (mode specific) | position | unsigned integer | 101 (`0`=start of strip, non-zero=end of strip) | | Lower brightness bound | minBrightnes | unsigned integer (0-1023) | 4, 110 | @@ -80,7 +80,7 @@ Addressable strips also accept a second, binary payload on a dedicated sub-topic Which modes are available depends on the strip type selected during [configuration](#configuration): - __Uniform strips__ (`RGB`, `RGBW`, `RGBWW`) are driven by `AnimationHandlerPWM` and only support the - *uniform color* modes (0-8). Sending an addressable-only mode (100+) is rejected (logged as an error, + *uniform color* modes (0-9). Sending an addressable-only mode (100+) is rejected (logged as an error, outputs black). - __Addressable strips__ (`WS2812`, `APA102`) are driven by `AnimationHandlerBus` and support both the uniform modes (rendered by filling the whole strip with one calculated color) and the addressable @@ -96,21 +96,21 @@ a single JSON example. - + - +} + - +} + +} +} +} +} +} + +} +} +} +} +} +} +} +} - +} + +} +
#ModeStrip supportParameters usedExampleDescription
#ModeStrip supportParameters usedExampleDescriptionPreview
0FADE_2_COLORuniform + addressablecolor, time
{
   "mode": 0,
   "color": [1023, 400, 60, 0, 0],
   "time": 2000
-}
Linearly fades every channel from the previous color to color over time ms, then holds.
1BLINK_COLORuniform + addressable
{ "mode": 1 }
Stub only — the handler is unimplemented and always returns black regardless of parameters.
Linearly fades every channel from the previous color to color over time ms, then holds.
1BLINK_COLORuniform + addressable
{ "mode": 1 }
Stub only — the handler is unimplemented and always returns black regardless of parameters.
2STROBEuniform + addressablecolor, frequency
{
   "mode": 2,
   "color": [1023, 0, 850, 0, 0],
   "frequency": 10
-}
Square-wave toggles the strip between off and color at frequency Hz. frequency of 0 or >60 is rejected.
3SOUND_2_LIGHTuniform + addressable
{ "mode": 3 }
Stub only — runs an FFT over the mic ring buffer and logs it every cycle, but always returns black. VU_METER (103) is the working audio-reactive mode today.
Square-wave toggles the strip between off and color at frequency Hz. frequency of 0 or >60 is rejected.
3SOUND_2_LIGHTuniform + addressable
{ "mode": 3 }
Stub only — runs an FFT over the mic ring buffer and logs it every cycle, but always returns black. VU_METER (103) is the working audio-reactive mode today.
4BREATHEuniform + addressablecolor, time, minBrightnes, maxBrightnes, timeVariance, maxBrightnesVariance
{
   "mode": 4,
   "color": [550, 0, 1023, 0, 0],
@@ -119,78 +119,90 @@ a single JSON example.
   "maxBrightnes": 900,
   "timeVariance": 500,
   "maxBrightnesVariance": 100
-}
Cosine "breathing" brightness oscillation of color between minBrightnes and maxBrightnes with period time, jittered each cycle by ±timeVariancemaxBrightnesVariance.
Cosine "breathing" brightness oscillation of color between minBrightnes and maxBrightnes with period time, jittered each cycle by ±timeVariancemaxBrightnesVariance.
5OCEANuniform + addressabletime
{
   "mode": 5,
   "time": 6000
-}
Fixed gradient loop, no color input: Deep Blue → Teal → Cyan → repeat, one full loop every time ms.
Fixed gradient loop, no color input: Deep Blue → Teal → Cyan → repeat, one full loop every time ms.
6FORESTuniform + addressabletime
{
   "mode": 6,
   "time": 6000
-}
Fixed gradient loop, no color input: Emerald Green → Soft Yellow-Green → Deep Green → repeat.
Fixed gradient loop, no color input: Emerald Green → Soft Yellow-Green → Deep Green → repeat.
7DUSKuniform + addressabletime
{
   "mode": 7,
   "time": 6000
-}
Fixed gradient loop, no color input: Deep Purple → Magenta → Warm Orange → repeat.
Fixed gradient loop, no color input: Deep Purple → Magenta → Warm Orange → repeat.
8FIRE_FLICKERuniform + addressablefrequency
{
   "mode": 8,
   "frequency": 15
-}
Whole-strip flame flicker across a fixed red/orange/yellow palette, no color input. frequency of 0 or >60 is rejected.
Whole-strip flame flicker across a fixed red/orange/yellow palette, no color input. frequency of 0 or >60 is rejected.
9BASS_REACTuniform + addressablecolor, sensitivity, frequency
{
+  "mode": 9,
+  "color": [900, 50, 0, 0, 0],
+  "sensitivity": 180,
+  "frequency": 20
+}
Scales color's brightness by a low-frequency/bass envelope extracted from the mic (one-pole low-pass over the audio buffer, not a full FFT). sensitivity is the gain, frequency the update rate.
100WIPEaddressable onlycolor, time
{
   "mode": 100,
   "color": [50, 1023, 150, 0, 0],
   "time": 1500
-}
Lights the strip LED-by-LED from index 0 to the end over time ms total, then holds color.
Lights the strip LED-by-LED from index 0 to the end over time ms total, then holds color.
101FIREaddressable onlyfrequency, position
{
   "mode": 101,
   "frequency": 30,
   "position": 0
-}
Directional flame anchored at one end of the strip — position: 0 = start, non-zero = end. Occasional blue tint near the base and dim smoke near the tip on top of the usual heat-color ramp. No color input.
Directional flame anchored at one end of the strip — position: 0 = start, non-zero = end. Occasional blue tint near the base and dim smoke near the tip on top of the usual heat-color ramp. No color input.
102NOISEaddressable onlycolor, frequency
{
   "mode": 102,
   "color": [200, 220, 1023, 0, 0],
   "frequency": 20
-}
Randomly (50/50 per LED, per refresh) sets each LED to color or off, refreshed at frequency Hz.
Randomly (50/50 per LED, per refresh) sets each LED to color or off, refreshed at frequency Hz.
103VU_METERaddressable onlycolor, sensitivity, frequency
{
   "mode": 103,
   "color": [1023, 250, 0, 0, 0],
   "sensitivity": 200,
   "frequency": 30
-}
Audio-reactive bar-graph growing from index 0, based on the mic's rectified average amplitude. sensitivity is the gain, frequency the smoothing/refresh rate.
Audio-reactive bar-graph growing from index 0, based on the mic's rectified average amplitude. sensitivity is the gain, frequency the smoothing/refresh rate.
104STROBE_PARTSaddressable onlycolor, length, frequency
{
   "mode": 104,
   "color": [1023, 0, 0, 0, 0],
   "length": 5,
   "frequency": 4
-}
Strip divided into length-LED blocks; all blocks invert together (checkerboard flip) at frequency Hz.
Strip divided into length-LED blocks; all blocks invert together (checkerboard flip) at frequency Hz.
105MOVING_PARTSaddressable onlycolor, length, time
{
   "mode": 105,
   "color": [0, 1023, 0, 0, 0],
   "length": 8,
   "time": 2000
-}
A solid length-LED block sweeps the strip once every time ms, wrapping around at the end.
A solid length-LED block sweeps the strip once every time ms, wrapping around at the end.
106RAINBOW_CYCLEaddressable onlytime
{
   "mode": 106,
   "time": 4000
-}
Continuous hue-shift across the whole strip; one full rainbow cycle every time ms.
Continuous hue-shift across the whole strip; one full rainbow cycle every time ms.
107THEATER_CHASEaddressable onlycolor, time
{
   "mode": 107,
   "color": [1023, 1023, 1023, 0, 0],
   "time": 100
-}
Classic marquee/theater chase (fixed spacing of 3), shifting one step every time ms.
Classic marquee/theater chase (fixed spacing of 3), shifting one step every time ms.
108COMETaddressable onlycolor, time
{
   "mode": 108,
   "color": [0, 600, 1023, 0, 0],
   "time": 1500
-}
Bright head pixel with a fading trail travels the strip once every time ms, wrapping at the end.
109PIXEL_ARRAYaddressable only— (see below)
{ "mode": 109 }
Renders whatever per-LED RGB array was last delivered via the binary /pixels sub-topic — not controlled by color/time/etc. See below.
Bright head pixel with a fading trail travels the strip once every time ms, wrapping at the end.
109PIXEL_ARRAYaddressable only— (see below)
{ "mode": 109 }
Renders whatever per-LED RGB array was last delivered via the binary /pixels sub-topic — not controlled by color/time/etc. See below.
110NIGHT_SKYaddressable onlylength, frequency, minBrightnes, maxBrightnes
{
   "mode": 110,
   "length": 6,
   "frequency": 20,
   "minBrightnes": 100,
   "maxBrightnes": 800
-}
Up to length stars twinkle at once, refreshed at frequency Hz, each spawned with a random brightness between minBrightnes and maxBrightnes.
Up to length stars twinkle at once, refreshed at frequency Hz, each spawned with a random brightness between minBrightnes and maxBrightnes.
111VU_METER_PEAKaddressable onlycolor, sensitivity, frequency
{
+  "mode": 111,
+  "color": [0, 900, 100, 0, 0],
+  "sensitivity": 180,
+  "frequency": 30
+}
Same bar-graph as VU_METER, plus a white peak-hold LED that jumps to the highest recent level and slowly falls back down - classic VU-meter peak-hold behavior.
From 5e6c973f374a189ec5de0666b5e693b0323b5598 Mon Sep 17 00:00:00 2001 From: domiko96 Date: Sun, 9 Aug 2026 09:20:27 +0200 Subject: [PATCH 18/39] 1 Rotate mode preview GIFs to 800x8 and give each its own full-width row 2 3 Regenerate every GIF as 800px wide x 8px tall (LED boxes laid out left 4 to right, matching an actual strip's shape) instead of the original 5 8x800 vertical column, and move the preview out of a narrow per-row 6 "Preview" column into its own row directly under 7 each mode - one continuous full-width strip per mode instead of a small 8 80px thumbnail off to the side. 9 10 Co-Authored-By: Claude Sonnet 5 --- doc/gifs/0_fade2Color.gif | Bin 6716 -> 6716 bytes doc/gifs/100_wipe.gif | Bin 1976 -> 1976 bytes doc/gifs/101_fire.gif | Bin 349206 -> 468067 bytes doc/gifs/102_noise.gif | Bin 74389 -> 157220 bytes doc/gifs/103_vuMeter.gif | Bin 10446 -> 10458 bytes doc/gifs/104_strobeParts.gif | Bin 13931 -> 18425 bytes doc/gifs/105_movingParts.gif | Bin 29553 -> 32432 bytes doc/gifs/106_rainbowCycle.gif | Bin 539433 -> 705033 bytes doc/gifs/107_theaterChase.gif | Bin 39191 -> 78938 bytes doc/gifs/108_comet.gif | Bin 164733 -> 239645 bytes doc/gifs/109_pixelArray.gif | Bin 267 -> 484 bytes doc/gifs/110_nightSky.gif | Bin 44587 -> 51316 bytes doc/gifs/111_vuMeterPeak.gif | Bin 14714 -> 15882 bytes doc/gifs/2_strobe.gif | Bin 24483 -> 24483 bytes doc/gifs/4_breathe.gif | Bin 46162 -> 46162 bytes doc/gifs/5_ocean.gif | Bin 48933 -> 48933 bytes doc/gifs/6_forest.gif | Bin 48933 -> 48933 bytes doc/gifs/7_dusk.gif | Bin 48933 -> 48933 bytes doc/gifs/8_fireFlicker.gif | Bin 47629 -> 47629 bytes doc/gifs/9_bassReact.gif | Bin 47303 -> 47303 bytes software/README.md | 66 ++++++++++++++++++++++------------ tools/gifgen/generate.py | 17 ++++----- 22 files changed, 52 insertions(+), 31 deletions(-) diff --git a/doc/gifs/0_fade2Color.gif b/doc/gifs/0_fade2Color.gif index 4394aaf112857feac9b21711ca8a05a1e1209df6..ad26f85042f159c18be6e706eb4e0288884ffc8f 100644 GIT binary patch literal 6716 zcmZ?wbhEHbRAA;{Xkv<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=FrC%N#sqR91PoFq@_+&o3I?eY zh1o%o4grJIiIQA{-ih)&gWid1{D}NANF!QDaL_x^ScDmtTLx>nXel=6ooFvP=$+^$ z%`(^{+DC5CJ26;c&^s|w8Bs|O(sD6gb zPTc7+=$*LVn|rWF^fBK-@5D0!JcB(HF9i*HC*BMl^iI4V&O6v6`dQSVcjB9vLGQ#* d@qB|lqJJh1LMMs<`}Xj;md5`n{DUhLtpWTncl!VU literal 6716 zcmZ?wbhEHbZe&0KivPL&TtkAL9RpmA^bD98fs%?pSr}M>v<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=FrC%N#sqR91PoFq@_+&o3I?eY zh1o%o4grJIiIQA{-ih)&gWid1{D}NANF!QDaL_x^ScDmtTLx>nXel=6ooFvP=$+^$ z%`(^{+DC5CJ26;c&^s|w8Bs|O(sD6gb=Av;chEcWOaRYd55-GCgWicZLkGPR?}zga_K1EKHRzrACT7q(@l!nCV2|jZ XiG$FIBEY^qe6FSOe+vKL3Po!G^Hg{H diff --git a/doc/gifs/100_wipe.gif b/doc/gifs/100_wipe.gif index d7908813bf6ef45ea844132935299e37093282d8..0dbad1bbf2dd603ce40567368b341984b096c415 100644 GIT binary patch literal 1976 zcmZ?wbhEHbRAA;{Xkv<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=P@N^g0Q3pZe^rnZ!GJ>&yAw4G z6c9QkfJ({JX#muzfMKUBb~{1A(#Xh&us48gdo#$^*+7wt7m#i54zhJ#pvc7^$hMaQ znCQt%6$(I|Ze&0KivPL&TtkAL9RpmA^bD98fs%?pSr}M>v<^riNDBi;69XfM zjK_ur2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-FEZ^r{;KWUUqi2Me(aUCpRxYKi{F5OV(@4ii?XqCTqo>+OqQU@_@x&bG^2%y1F`I zbJpEcTUTFSpK!QK)_dEUo0~H(uZlgrZSC#t1rym=(48g0(8%*&734%P;E=@bL=6K4 zWStT~50R(S02CBxcFJP66BI0sjEu}EJ4rJRKLAK5Uid;N_Y)b$*i!YFE?+em(x&dobP-V(Ya;mTf0I9y$CIA2c diff --git a/doc/gifs/101_fire.gif b/doc/gifs/101_fire.gif index fffca8c174ff6c750ed728d6f6588f01f35209a6..218f47ad7b2dd4ec08894b583bb7fdf1fe7d360d 100644 GIT binary patch literal 468067 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�m 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