added lighting fading in and out, when connection is lost/reestablished

This commit is contained in:
2026-01-20 14:44:28 +01:00
parent 153d134f88
commit 42e49b6c06
4 changed files with 105 additions and 10 deletions

View File

@@ -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

View File

@@ -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 (0255): 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();
}
}

View File

@@ -27,6 +27,7 @@ extern bool overrideActive[NUM_CHANNELS];
extern uint8_t lightingHue; // 0255
extern uint8_t lightingSaturation; // 0255
extern uint8_t lightingBrightness; // 0255
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;

View File

@@ -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 (0255): 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(); // 0100
lightingHue = fromSlider(sliderVal); // convert to 0255
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(); // 0100
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(); // 0100
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();
}
);