Fix realtime mode disabled by brightness change

Fix realtime mode not working immediately at turn on
Fix individual segment control not working immediately at turn on
This commit is contained in:
cschwinne 2022-03-10 20:40:48 +01:00
parent a556732e4f
commit 4865ddb377
6 changed files with 34 additions and 16 deletions

View File

@ -625,7 +625,7 @@ class WS2812FX {
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
setColor(uint8_t slot, uint32_t c), setColor(uint8_t slot, uint32_t c),
setCCT(uint16_t k), setCCT(uint16_t k),
setBrightness(uint8_t b), setBrightness(uint8_t b, bool direct = false),
setRange(uint16_t i, uint16_t i2, uint32_t col), setRange(uint16_t i, uint16_t i2, uint32_t col),
setShowCallback(show_callback cb), setShowCallback(show_callback cb),
setTransition(uint16_t t), setTransition(uint16_t t),

View File

@ -133,7 +133,8 @@ void WS2812FX::service() {
if (!SEGMENT.isActive()) continue; if (!SEGMENT.isActive()) continue;
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary // last condition ensures all solid segments are updated at the same time
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0))
{ {
if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check
doShow = true; doShow = true;
@ -426,7 +427,7 @@ void WS2812FX::setCCT(uint16_t k) {
} }
} }
void WS2812FX::setBrightness(uint8_t b) { void WS2812FX::setBrightness(uint8_t b, bool direct) {
if (gammaCorrectBri) b = gamma8(b); if (gammaCorrectBri) b = gamma8(b);
if (_brightness == b) return; if (_brightness == b) return;
_brightness = b; _brightness = b;
@ -436,8 +437,13 @@ void WS2812FX::setBrightness(uint8_t b) {
_segments[i].setOption(SEG_OPTION_FREEZE, false); _segments[i].setOption(SEG_OPTION_FREEZE, false);
} }
} }
unsigned long t = millis(); if (direct) {
if (_segment_runtimes[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) show(); //apply brightness change immediately if no refresh soon // would be dangerous if applied immediately (could exceed ABL), but will not output until the next show()
busses.setBrightness(b);
} else {
unsigned long t = millis();
if (_segment_runtimes[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) show(); //apply brightness change immediately if no refresh soon
}
} }
uint8_t WS2812FX::getBrightness(void) { uint8_t WS2812FX::getBrightness(void) {

View File

@ -130,7 +130,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
if (DMXOldDimmer != e131_data[DMXAddress+0]) { if (DMXOldDimmer != e131_data[DMXAddress+0]) {
DMXOldDimmer = e131_data[DMXAddress+0]; DMXOldDimmer = e131_data[DMXAddress+0];
bri = e131_data[DMXAddress+0]; bri = e131_data[DMXAddress+0];
strip.setBrightness(bri); strip.setBrightness(bri, true);
} }
for (uint16_t i = 0; i < totalLen; i++) for (uint16_t i = 0; i < totalLen; i++)
setRealtimePixel(i, e131_data[DMXAddress+1], e131_data[DMXAddress+2], e131_data[DMXAddress+3], wChannel); setRealtimePixel(i, e131_data[DMXAddress+1], e131_data[DMXAddress+2], e131_data[DMXAddress+3], wChannel);
@ -184,7 +184,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
previousLeds = 0; previousLeds = 0;
// First DMX address is dimmer in DMX_MODE_MULTIPLE_DRGB mode. // First DMX address is dimmer in DMX_MODE_MULTIPLE_DRGB mode.
if (DMXMode == DMX_MODE_MULTIPLE_DRGB) { if (DMXMode == DMX_MODE_MULTIPLE_DRGB) {
strip.setBrightness(e131_data[dmxOffset++]); strip.setBrightness(e131_data[dmxOffset++], true);
} }
} else { } else {
// All subsequent universes start at the first channel. // All subsequent universes start at the first channel.

View File

@ -177,7 +177,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
if (!iarr.isNull()) { if (!iarr.isNull()) {
uint8_t oldSegId = strip.setPixelSegment(id); uint8_t oldSegId = strip.setPixelSegment(id);
//freeze and init to black // set brightness immediately and disable transition
transitionDelayTemp = 0;
jsonTransitionOnce = true;
strip.setBrightness(scaledBri(bri), true);
// freeze and init to black
if (!seg.getOption(SEG_OPTION_FREEZE)) { if (!seg.getOption(SEG_OPTION_FREEZE)) {
seg.setOption(SEG_OPTION_FREEZE, true); seg.setOption(SEG_OPTION_FREEZE, true);
strip.fill(0); strip.fill(0);
@ -263,7 +268,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
transitionDelayTemp *= 100; transitionDelayTemp *= 100;
jsonTransitionOnce = true; jsonTransitionOnce = true;
} }
strip.setTransition(transitionDelayTemp); strip.setTransition(transitionDelayTemp); // required here for color transitions to have correct duration
tr = root[F("tb")] | -1; tr = root[F("tb")] | -1;
if (tr >= 0) strip.timebase = ((uint32_t)tr) - millis(); if (tr >= 0) strip.timebase = ((uint32_t)tr) - millis();
@ -290,10 +295,16 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
realtimeOverride = root[F("lor")] | realtimeOverride; realtimeOverride = root[F("lor")] | realtimeOverride;
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS; if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
bool liveEnabled = false;
if (root.containsKey("live")) { if (root.containsKey("live")) {
bool lv = root["live"]; bool lv = root["live"];
if (lv) realtimeLock(65000); //enter realtime without timeout if (lv) {
else realtimeTimeout = 0; //cancel realtime mode immediately transitionDelayTemp = 0;
jsonTransitionOnce = true;
liveEnabled = true; // triggers realtimeLock() below
realtimeLock(65000);
}
else realtimeTimeout = 0; //cancel realtime mode immediately
} }
strip.setMainSegmentId(root[F("mainseg")] | strip.getMainSegmentId()); strip.setMainSegmentId(root[F("mainseg")] | strip.getMainSegmentId());
@ -370,6 +381,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
} }
stateUpdated(callMode); stateUpdated(callMode);
if (liveEnabled) realtimeTimeout = UINT32_MAX; // force indefinite timeout if this request contained {"live":true}
return stateResponse; return stateResponse;
} }

View File

@ -153,13 +153,13 @@ void realtimeLock(uint32_t timeoutMs, byte md)
if (timeoutMs == 255001 || timeoutMs == 65000) realtimeTimeout = UINT32_MAX; if (timeoutMs == 255001 || timeoutMs == 65000) realtimeTimeout = UINT32_MAX;
} }
// if strip is off (bri==0) and not already in RTM // if strip is off (bri==0) and not already in RTM
if (bri == 0 && !realtimeMode) { if (briT == 0 && !realtimeMode) {
strip.setBrightness(scaledBri(briLast)); strip.setBrightness(scaledBri(briLast), true);
} }
realtimeMode = md; realtimeMode = md;
if (arlsForceMaxBri && !realtimeOverride) strip.setBrightness(scaledBri(255)); if (arlsForceMaxBri && !realtimeOverride) strip.setBrightness(scaledBri(255), true);
if (md == REALTIME_MODE_GENERIC) strip.show(); if (briT > 0 && md == REALTIME_MODE_GENERIC) strip.show();
} }

View File

@ -174,7 +174,7 @@ void handleSerial()
if (!realtimeOverride) setRealtimePixel(pixel++, red, green, blue, 0); if (!realtimeOverride) setRealtimePixel(pixel++, red, green, blue, 0);
if (--count > 0) state = AdaState::Data_Red; if (--count > 0) state = AdaState::Data_Red;
else { else {
if (!realtimeMode && bri == 0) strip.setBrightness(briLast); if (!realtimeMode && bri == 0) strip.setBrightness(briLast, true);
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT); realtimeLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT);
if (!realtimeOverride) strip.show(); if (!realtimeOverride) strip.show();