From 42e49b6c0685b87d3b8dc3a89ee08b932ab4a943 Mon Sep 17 00:00:00 2001 From: Robin Cerny Date: Tue, 20 Jan 2026 14:44:28 +0100 Subject: [PATCH] added lighting fading in and out, when connection is lost/reestablished --- analog_system_monitor_arduino/Config.h | 15 ++++- analog_system_monitor_arduino/Core.cpp | 85 ++++++++++++++++++++++++-- analog_system_monitor_arduino/Core.h | 7 +++ analog_system_monitor_arduino/Ui.cpp | 8 ++- 4 files changed, 105 insertions(+), 10 deletions(-) diff --git a/analog_system_monitor_arduino/Config.h b/analog_system_monitor_arduino/Config.h index ea86bfe..218c2c0 100644 --- a/analog_system_monitor_arduino/Config.h +++ b/analog_system_monitor_arduino/Config.h @@ -26,7 +26,6 @@ static const uint8_t pwmPins[NUM_CHANNELS] = { 5, // D5 18, // D6 19 // D7 - // 23 (D8) remains as a spare }; static const uint32_t pwmFrequency = 25000; // 25 kHz @@ -79,9 +78,21 @@ static const unsigned long slewDuration = 1000; // 1 second smooth transition // ------------------------------- // Animation tuning // ------------------------------- -static const float FADE_IN_FACTOR = 0.999f; // boot-up 0 → 100% +static const float FADE_IN_FACTOR = 0.998f; // boot-up 0 → 100% static const float FADE_OUT_FACTOR = 0.999f; // watchdog 100% → 0 static const unsigned long FADE_INTERVAL = 1; // ms between fade steps +// Lighting fade durations (milliseconds) +#define LIGHTING_FADE_IN_DURATION 1250 +#define LIGHTING_FADE_OUT_DURATION 4250 +// Clamping brightness at the low end +const uint8_t BRIGHTNESS_MIN_VISIBLE = 33; + + +// ------------------------------- +// Lighting (FastLED) +// ------------------------------- +#define LED_PIN 23 +#define NUM_LEDS 20 // ------------------------------- // Connection state machine diff --git a/analog_system_monitor_arduino/Core.cpp b/analog_system_monitor_arduino/Core.cpp index e65087a..99694e3 100644 --- a/analog_system_monitor_arduino/Core.cpp +++ b/analog_system_monitor_arduino/Core.cpp @@ -27,16 +27,19 @@ float calibratedPoints[NUM_CHANNELS][5] = { {0.0f, 26.0f, 50.0f, 76.0f, 99.0f} }; -// ------------------------------- -// Lighting (FastLED) -// ------------------------------- -#define LED_PIN 23 -#define NUM_LEDS 20 // or more if you expand later CRGB leds[NUM_LEDS]; uint8_t lightingHue = 0; uint8_t lightingSaturation = 255; uint8_t lightingBrightness = 255; +uint8_t lightingBrightnessSaved = 255; + +// Lighting fade state +bool lightingFading = false; +uint8_t lightingFadeStart = 0; +uint8_t lightingFadeEnd = 0; +unsigned long lightingFadeStartTime = 0; +unsigned long lightingFadeDuration = 0; bool overrideActive[NUM_CHANNELS] = {false}; @@ -82,6 +85,14 @@ void applyLighting() { FastLED.show(); } +void startLightingFade(uint8_t from, uint8_t to, unsigned long duration) { + lightingFadeStart = from; + lightingFadeEnd = to; + lightingFadeDuration = duration; + lightingFadeStartTime = millis(); + lightingFading = true; +} + void updateConnectionStatusUI(ConnectionState state) { const char* text = "Unknown"; @@ -132,7 +143,9 @@ void coreInit() { lightingHue = prefs.getUChar("light_hue", 0); lightingSaturation = prefs.getUChar("light_sat", 255); - lightingBrightness = prefs.getUChar("light_bright",255); + lightingBrightnessSaved = prefs.getUChar("light_bright",255); + lightingBrightness = lightingBrightnessSaved; + Serial.printf("Lighting loaded (0–255): H=%d S=%d B=%d\n", lightingHue, lightingSaturation, lightingBrightness); @@ -182,6 +195,7 @@ void coreHandleUDP() { Serial.println("STATE CHANGE: DISCONNECTED → CONNECTING (UDP connection established)"); connectionState = STATE_CONNECTING; updateConnectionStatusUI(connectionState); + startLightingFade(0, lightingBrightnessSaved, LIGHTING_FADE_IN_DURATION); // Initialize fade-in: start from 0 on all non-override channels for (int ch = 0; ch < NUM_CHANNELS; ch++) { @@ -273,6 +287,7 @@ void coreUpdateState() { Serial.println("STATE CHANGE: CONNECTED → DISCONNECTED (UDP connection lost)"); connectionState = STATE_DISCONNECTED; updateConnectionStatusUI(connectionState); + startLightingFade(lightingBrightness, 0, LIGHTING_FADE_OUT_DURATION); break; } @@ -362,4 +377,62 @@ void coreUpdateState() { } } break; } + + if (lightingFading) { + unsigned long now = millis(); + unsigned long elapsed = now - lightingFadeStartTime; + + if (elapsed >= lightingFadeDuration) { + // Fade complete + lightingBrightness = lightingFadeEnd; + + // If fade-out finished, jump to 0 + if (lightingFadeEnd == 0) { + lightingBrightness = 0; + } + + lightingFading = false; + applyLighting(); + return; + } + + // Compute normalized progress + float t = (float)elapsed / (float)lightingFadeDuration; + + // Gamma correction + const float gamma = 2.2f; + float t_gamma = pow(t, gamma); + + // Determine effective fade range + uint8_t start = lightingFadeStart; + uint8_t end = lightingFadeEnd; + + // Fade-in: 0 → 13 → 100 + if (start == 0 && end > 0) { + start = BRIGHTNESS_MIN_VISIBLE; + } + + // Fade-out: 100 → 13 → 0 + if (end == 0 && start > 0) { + end = BRIGHTNESS_MIN_VISIBLE; + } + + // Interpolate only within the visible range + float raw = start + (end - start) * t_gamma; + + // Apply jump logic: + if (lightingFadeStart == 0 && elapsed == 0) { + // Fade-in: first frame → jump to 13 + lightingBrightness = BRIGHTNESS_MIN_VISIBLE; + } + else if (lightingFadeEnd == 0 && elapsed + 16 >= lightingFadeDuration) { + // Fade-out: last frame → jump to 0 + lightingBrightness = 0; + } + else { + lightingBrightness = raw; + } + + applyLighting(); + } } diff --git a/analog_system_monitor_arduino/Core.h b/analog_system_monitor_arduino/Core.h index 9c3a419..01007ff 100644 --- a/analog_system_monitor_arduino/Core.h +++ b/analog_system_monitor_arduino/Core.h @@ -27,6 +27,7 @@ extern bool overrideActive[NUM_CHANNELS]; extern uint8_t lightingHue; // 0–255 extern uint8_t lightingSaturation; // 0–255 extern uint8_t lightingBrightness; // 0–255 +extern uint8_t lightingBrightnessSaved; // State extern ConnectionState connectionState; @@ -48,4 +49,10 @@ void coreUpdateState(); // called from loop() // Helpers used by UI float applyCalibration(uint8_t ch, float logicalDuty); void updateConnectionStatusUI(ConnectionState state); + +// Lighting helpers void applyLighting(); +void startLightingFade(uint8_t from, uint8_t to); + +// Lighting fade state +extern bool lightingFading; diff --git a/analog_system_monitor_arduino/Ui.cpp b/analog_system_monitor_arduino/Ui.cpp index 33473b3..d1f87f6 100644 --- a/analog_system_monitor_arduino/Ui.cpp +++ b/analog_system_monitor_arduino/Ui.cpp @@ -101,7 +101,7 @@ void lightingSaveCallback(Control *sender, int type) { prefs.putUChar("light_hue", lightingHue); prefs.putUChar("light_sat", lightingSaturation); - prefs.putUChar("light_bright", lightingBrightness); + prefs.putUChar("light_bright", lightingBrightnessSaved); Serial.printf("Lighting saved (0–255): H=%d S=%d B=%d\n", lightingHue, lightingSaturation, lightingBrightness); @@ -246,6 +246,7 @@ void uiInit(uint16_t& tabSettings, uint16_t& tabLighting, uint16_t& tabCalibrati int sliderVal = sender->value.toInt(); // 0–100 lightingHue = fromSlider(sliderVal); // convert to 0–255 Serial.printf("Lighting Hue changed (RAM only): %d\n", lightingHue); + lightingFading = false; // cancel fade if user moves slider applyLighting(); } ); @@ -261,6 +262,7 @@ void uiInit(uint16_t& tabSettings, uint16_t& tabLighting, uint16_t& tabCalibrati int sliderVal = sender->value.toInt(); // 0–100 lightingSaturation = fromSlider(sliderVal); Serial.printf("Lighting Saturation updated (RAM only): %d\n", lightingSaturation); + lightingFading = false; // cancel fade if user moves slider applyLighting(); } ); @@ -274,8 +276,10 @@ void uiInit(uint16_t& tabSettings, uint16_t& tabLighting, uint16_t& tabCalibrati tabLighting, [](Control *sender, int type) { int sliderVal = sender->value.toInt(); // 0–100 - lightingBrightness = fromSlider(sliderVal); + lightingBrightnessSaved = fromSlider(sliderVal); + lightingBrightness = lightingBrightnessSaved; Serial.printf("Lighting Brightness updated (RAM only): %d\n", lightingBrightness); + lightingFading = false; // cancel fade if user moves slider applyLighting(); } );