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
pull/2577/head
cschwinne 2022-03-10 20:40:48 +01:00
rodzic a556732e4f
commit 4865ddb377
6 zmienionych plików z 34 dodań i 16 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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