From 5da47636cfbb13f12bbeedb8363cb9a8f65e645f Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 9 Jul 2021 16:25:23 +0200 Subject: [PATCH 1/5] Busses extend total configured LEDs if required (closes #2056 ) Fixed extra button pins defaulting to 0 on first boot --- CHANGELOG.md | 5 +++++ wled00/bus_manager.h | 12 +++++++++++ wled00/cfg.cpp | 51 +++++++++++++++++--------------------------- wled00/wled.cpp | 17 +++++++++++---- wled00/wled.h | 2 +- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 403c4b81d..29f3b0249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ### Builds after release 0.12.0 +#### Build 2107090 + +- Busses extend total configured LEDs if required +- Fixed extra button pins defaulting to 0 on first boot + #### Build 2107080 - Made Peek use the main websocket connection instead of opening a second one diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 3517288c2..530cae32d 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -27,6 +27,18 @@ struct BusConfig { else if (type > 40 && type < 46) nPins = NUM_PWM_PINS(type); for (uint8_t i = 0; i < nPins; i++) pins[i] = ppins[i]; } + + //validates start and length and extends total if needed + bool adjustBounds(uint16_t& total) { + if (!count) count = 1; + if (count > MAX_LEDS_PER_BUS) count = MAX_LEDS_PER_BUS; + if (start >= MAX_LEDS) return false; + //limit length of strip if it would exceed total permissible LEDs + if (start + count > MAX_LEDS) count = MAX_LEDS - start; + //extend total count accordingly + if (start + count > total) total = start + count; + return true; + } }; //parent class of BusDigital and BusPwm diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 827439e32..d4cce2f37 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -85,6 +85,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (fromFS || !ins.isNull()) { uint8_t s = 0; //bus iterator strip.isRgbw = false; + strip.isOffRefreshRequred = false; busses.removeAll(); uint32_t mem = 0; for (JsonObject elm : ins) { @@ -99,25 +100,23 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (i>4) break; } - uint16_t length = elm[F("len")]; - if (length==0) continue; + uint16_t length = elm[F("len")] | 1; uint8_t colorOrder = (int)elm[F("order")]; - //only use skip from the first strip (this shouldn't have been in ins obj. but remains here for compatibility) uint8_t skipFirst = elm[F("skip")]; uint16_t start = elm[F("start")] | 0; - if (start >= ledCount) continue; - //limit length of strip if it would exceed total configured LEDs - if (start + length > ledCount) length = ledCount - start; uint8_t ledType = elm["type"] | TYPE_WS2812_RGB; bool reversed = elm["rev"]; - //RGBW mode is enabled if at least one of the strips is RGBW - strip.isRgbw = (strip.isRgbw || BusManager::isRgbw(ledType)); - //refresh is required to remain off if at least one of the strips requires the refresh. - strip.isOffRefreshRequred |= BusManager::isOffRefreshRequred(ledType); - s++; + BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst); - mem += busses.memUsage(bc); - if (mem <= MAX_LED_MEMORY) busses.add(bc); + if (bc.adjustBounds(ledCount)) { + //RGBW mode is enabled if at least one of the strips is RGBW + strip.isRgbw = (strip.isRgbw || BusManager::isRgbw(ledType)); + //refresh is required to remain off if at least one of the strips requires the refresh. + strip.isOffRefreshRequred |= BusManager::isOffRefreshRequred(ledType); + s++; + mem += busses.memUsage(bc); + if (mem <= MAX_LED_MEMORY) busses.add(bc); + } } strip.finalizeInit(ledCount); } @@ -153,7 +152,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } } else { // new install/missing configuration (button 0 has defaults) - if (fromFS) + if (fromFS) for (uint8_t s=1; stype)) strip.isRgbw = true; - strip.isRgbw = (strip.isRgbw || BusManager::isRgbw(busConfigs[i]->type)); + + if (busConfigs[i]->adjustBounds(ledCount)) { + mem += busses.memUsage(*busConfigs[i]); + if (mem <= MAX_LED_MEMORY) { + busses.add(*busConfigs[i]); + //RGBW mode is enabled if at least one of the strips is RGBW + strip.isRgbw = (strip.isRgbw || BusManager::isRgbw(busConfigs[i]->type)); + //refresh is required to remain off if at least one of the strips requires the refresh. + strip.isOffRefreshRequred |= BusManager::isOffRefreshRequred(busConfigs[i]->type); + } + } delete busConfigs[i]; busConfigs[i] = nullptr; } strip.finalizeInit(ledCount); @@ -284,6 +291,8 @@ void WLED::setup() pinManager.allocatePin(2); #endif + for (uint8_t i=1; i Date: Fri, 9 Jul 2021 18:42:52 +0200 Subject: [PATCH 2/5] Fixed presets using wrong call mode (e.g. causing buttons to send UDP under direct change type) Increased hue buffer --- CHANGELOG.md | 5 ++++ wled00/alexa.cpp | 4 +-- wled00/button.cpp | 10 +++---- wled00/fcn_declare.h | 4 +-- wled00/hue.cpp | 2 +- wled00/ir.cpp | 62 ++++++++++++++++++++++---------------------- wled00/json.cpp | 6 ++--- wled00/mqtt.cpp | 2 ++ wled00/presets.cpp | 6 ++--- wled00/wled.cpp | 2 +- wled00/wled.h | 2 +- 11 files changed, 56 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29f3b0249..8f4ad85ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ### Builds after release 0.12.0 +#### Build 2107091 + +- Fixed presets using wrong call mode (e.g. causing buttons to send UDP under direct change type) +- Increased hue buffer + #### Build 2107090 - Busses extend total configured LEDs if required diff --git a/wled00/alexa.cpp b/wled00/alexa.cpp index 83e7c25f1..213c9306d 100644 --- a/wled00/alexa.cpp +++ b/wled00/alexa.cpp @@ -47,7 +47,7 @@ void onAlexaChange(EspalexaDevice* dev) colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } } else { - applyPreset(macroAlexaOn); + applyPreset(macroAlexaOn, NOTIFIER_CALL_MODE_ALEXA); if (bri == 0) espalexaDevice->setValue(briLast); //stop Alexa from complaining if macroAlexaOn does not actually turn on } } else if (m == EspalexaDeviceProperty::off) @@ -61,7 +61,7 @@ void onAlexaChange(EspalexaDevice* dev) colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } } else { - applyPreset(macroAlexaOff); + applyPreset(macroAlexaOff, NOTIFIER_CALL_MODE_ALEXA); if (bri != 0) espalexaDevice->setValue(0); //stop Alexa from complaining if macroAlexaOff does not actually turn off } } else if (m == EspalexaDeviceProperty::bri) diff --git a/wled00/button.cpp b/wled00/button.cpp index ff0f4ee64..7b044c49a 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -15,7 +15,7 @@ void shortPressAction(uint8_t b) toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } else { - applyPreset(macroButton[b]); + applyPreset(macroButton[b], NOTIFIER_CALL_MODE_BUTTON); } // publish MQTT message @@ -62,12 +62,12 @@ void handleSwitch(uint8_t b) if (millis() - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce) if (!buttonPressedBefore[b]) { // on -> off - if (macroButton[b]) applyPreset(macroButton[b]); + if (macroButton[b]) applyPreset(macroButton[b], NOTIFIER_CALL_MODE_BUTTON); else { //turn on if (!bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);} } } else { // off -> on - if (macroLongPress[b]) applyPreset(macroLongPress[b]); + if (macroLongPress[b]) applyPreset(macroLongPress[b], NOTIFIER_CALL_MODE_BUTTON); else { //turn off if (bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);} } @@ -195,7 +195,7 @@ void handleButton() { if (!buttonLongPressed[b]) { - if (macroLongPress[b]) {applyPreset(macroLongPress[b]);} + if (macroLongPress[b]) {applyPreset(macroLongPress[b], NOTIFIER_CALL_MODE_BUTTON);} else _setRandomColor(false,true); // publish MQTT message @@ -224,7 +224,7 @@ void handleButton() if (macroDoublePress[b]) { if (doublePress) { - applyPreset(macroDoublePress[b]); + applyPreset(macroDoublePress[b], NOTIFIER_CALL_MODE_BUTTON); // publish MQTT message if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index b1d43ebda..4fe07f743 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -120,7 +120,7 @@ void handleIR(); #include "FX.h" void deserializeSegment(JsonObject elem, byte it, byte presetId = 0); -bool deserializeState(JsonObject root, byte presetId = 0); +bool deserializeState(JsonObject root, byte callMode = NOTIFIER_CALL_MODE_DIRECT_CHANGE, byte presetId = 0); void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true); void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true); void serializeInfo(JsonObject root); @@ -181,7 +181,7 @@ void loadPlaylist(JsonObject playlistObject, byte presetId = 0); void handlePlaylist(); //presets.cpp -bool applyPreset(byte index); +bool applyPreset(byte index, byte callMode = NOTIFIER_CALL_MODE_DIRECT_CHANGE); void savePreset(byte index, bool persist = true, const char* pname = nullptr, JsonObject saveobj = JsonObject()); void deletePreset(byte index); diff --git a/wled00/hue.cpp b/wled00/hue.cpp index bbf08c859..47b252e91 100644 --- a/wled00/hue.cpp +++ b/wled00/hue.cpp @@ -92,7 +92,7 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len) if (str == nullptr) return; str += 4; - StaticJsonDocument<512> root; + StaticJsonDocument<1024> root; if (str[0] == '[') //is JSON array { auto error = deserializeJson(root, str); diff --git a/wled00/ir.cpp b/wled00/ir.cpp index a38f7b016..a08321a5b 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -69,9 +69,9 @@ void decBrightness() } // apply preset or fallback to a effect and palette if it doesn't exist -void presetFallback(int8_t presetID, int8_t effectID, int8_t paletteID) +void presetFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) { - if (!applyPreset(presetID)) { + if (!applyPreset(presetID, NOTIFIER_CALL_MODE_BUTTON)) { effectCurrent = effectID; effectPalette = paletteID; } @@ -85,7 +85,7 @@ bool decodeIRCustom(uint32_t code) { //just examples, feel free to modify or remove case IRCUSTOM_ONOFF : toggleOnOff(); break; - case IRCUSTOM_MACRO1 : applyPreset(1); break; + case IRCUSTOM_MACRO1 : applyPreset(1, NOTIFIER_CALL_MODE_BUTTON); break; default: return false; } @@ -257,11 +257,11 @@ void decodeIR24(uint32_t code) case IR24_PURPLE : colorFromUint32(COLOR_PURPLE); break; case IR24_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; case IR24_PINK : colorFromUint32(COLOR_PINK); break; - case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR24_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break; - case IR24_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break; - case IR24_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break; - case IR24_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; + case IR24_FLASH : presetFallback(1, FX_MODE_COLORTWINKLE, effectPalette); break; + case IR24_STROBE : presetFallback(2, FX_MODE_RAINBOW_CYCLE, effectPalette); break; + case IR24_FADE : presetFallback(3, FX_MODE_BREATH, effectPalette); break; + case IR24_SMOOTH : presetFallback(4, FX_MODE_RAINBOW, effectPalette); break; default: return; } lastValidCode = code; @@ -289,11 +289,11 @@ void decodeIR24OLD(uint32_t code) case IR24_OLD_PURPLE : colorFromUint32(COLOR_PURPLE); break; case IR24_OLD_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; case IR24_OLD_PINK : colorFromUint32(COLOR_PINK); break; - case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR24_OLD_FLASH : if (!applyPreset(1)) { effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; } break; - case IR24_OLD_STROBE : if (!applyPreset(2)) { effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; } break; - case IR24_OLD_FADE : if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR24_OLD_SMOOTH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; + case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; + case IR24_OLD_FLASH : presetFallback(1, FX_MODE_COLORTWINKLE, 0); break; + case IR24_OLD_STROBE : presetFallback(2, FX_MODE_RAINBOW_CYCLE, 0); break; + case IR24_OLD_FADE : presetFallback(3, FX_MODE_BREATH, 0); break; + case IR24_OLD_SMOOTH : presetFallback(4, FX_MODE_RAINBOW, 0); break; default: return; } lastValidCode = code; @@ -382,10 +382,10 @@ void decodeIR40(uint32_t code) case IR40_SLOW : changeEffectSpeed(-16); break; case IR40_JUMP7 : changeEffectIntensity( 16); break; case IR40_AUTO : changeEffectIntensity(-16); break; - case IR40_JUMP3 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break; - case IR40_FADE3 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR40_FADE7 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break; - case IR40_FLASH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; + case IR40_JUMP3 : presetFallback(1, FX_MODE_STATIC, 0); break; + case IR40_FADE3 : presetFallback(2, FX_MODE_BREATH, 0); break; + case IR40_FADE7 : presetFallback(3, FX_MODE_FIRE_FLICKER, 0); break; + case IR40_FLASH : presetFallback(4, FX_MODE_RAINBOW, 0); break; } lastValidCode = code; } @@ -437,12 +437,12 @@ void decodeIR44(uint32_t code) case IR44_BLUEMINUS : changeEffectIntensity(-16); break; case IR44_QUICK : changeEffectSpeed( 16); break; case IR44_SLOW : changeEffectSpeed(-16); break; - case IR44_DIY1 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break; - case IR44_DIY2 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR44_DIY3 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break; - case IR44_DIY4 : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; - case IR44_DIY5 : if (!applyPreset(5)) { effectCurrent = FX_MODE_METEOR_SMOOTH; effectPalette = 0; } break; - case IR44_DIY6 : if (!applyPreset(6)) { effectCurrent = FX_MODE_RAIN; effectPalette = 0; } break; + case IR44_DIY1 : presetFallback(1, FX_MODE_STATIC, 0); break; + case IR44_DIY2 : presetFallback(2, FX_MODE_BREATH, 0); break; + case IR44_DIY3 : presetFallback(3, FX_MODE_FIRE_FLICKER, 0); break; + case IR44_DIY4 : presetFallback(4, FX_MODE_RAINBOW, 0); break; + case IR44_DIY5 : presetFallback(5, FX_MODE_METEOR_SMOOTH, 0); break; + case IR44_DIY6 : presetFallback(6, FX_MODE_RAIN, 0); break; case IR44_AUTO : effectCurrent = FX_MODE_STATIC; break; case IR44_FLASH : effectCurrent = FX_MODE_PALETTE; break; case IR44_JUMP3 : bri = 63; break; @@ -473,10 +473,10 @@ void decodeIR21(uint32_t code) case IR21_PURPLE: colorFromUint32(COLOR_PURPLE); break; case IR21_PINK: colorFromUint32(COLOR_PINK); break; case IR21_WHITE: colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR21_FLASH: if (!applyPreset(1)) { effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; } break; - case IR21_STROBE: if (!applyPreset(2)) { effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; } break; - case IR21_FADE: if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR21_SMOOTH: if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; + case IR21_FLASH: presetFallback(1, FX_MODE_COLORTWINKLE, 0); break; + case IR21_STROBE: presetFallback(2, FX_MODE_RAINBOW_CYCLE, 0); break; + case IR21_FADE: presetFallback(3, FX_MODE_BREATH, 0); break; + case IR21_SMOOTH: presetFallback(4, FX_MODE_RAINBOW, 0); break; default: return; } lastValidCode = code; @@ -518,9 +518,9 @@ void decodeIR9(uint32_t code) { switch (code) { case IR9_POWER : toggleOnOff(); break; - case IR9_A : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break; - case IR9_B : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break; - case IR9_C : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break; + case IR9_A : presetFallback(1, FX_MODE_COLORTWINKLE, effectPalette); break; + case IR9_B : presetFallback(2, FX_MODE_RAINBOW_CYCLE, effectPalette); break; + case IR9_C : presetFallback(3, FX_MODE_BREATH, effectPalette); break; case IR9_UP : incBrightness(); break; case IR9_DOWN : decBrightness(); break; //case IR9_UP : changeEffectIntensity(16); break; @@ -612,7 +612,7 @@ void decodeIRJson(uint32_t code) // command is JSON object //allow applyPreset() to reuse JSON buffer, or it would alloc. a second buffer and run out of mem. fileDoc = &irDoc; - deserializeState(jsonCmdObj); + deserializeState(jsonCmdObj, NOTIFIER_CALL_MODE_BUTTON); fileDoc = nullptr; } } diff --git a/wled00/json.cpp b/wled00/json.cpp index 845464e8d..78ee3883f 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -174,7 +174,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) return; // seg.hasChanged(prev); } -bool deserializeState(JsonObject root, byte presetId) +bool deserializeState(JsonObject root, byte callMode, byte presetId) { strip.applyToAllSelected = false; bool stateResponse = root[F("v")] | false; @@ -294,7 +294,7 @@ bool deserializeState(JsonObject root, byte presetId) ps = root["ps"] | -1; //load preset (clears state request!) if (ps >= 0) { if (!presetId) unloadPlaylist(); //stop playlist if preset changed manually - applyPreset(ps); + applyPreset(ps, callMode); return stateResponse; } @@ -315,7 +315,7 @@ bool deserializeState(JsonObject root, byte presetId) interfaceUpdateCallMode = NOTIFIER_CALL_MODE_WS_SEND; } - colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : callMode); return stateResponse; } diff --git a/wled00/mqtt.cpp b/wled00/mqtt.cpp index 8540335ba..b6975962d 100644 --- a/wled00/mqtt.cpp +++ b/wled00/mqtt.cpp @@ -93,7 +93,9 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties if (payload[0] == '{') { //JSON API DynamicJsonDocument doc(JSON_BUFFER_SIZE); deserializeJson(doc, payloadStr); + fileDoc = &doc; deserializeState(doc.as()); + fileDoc = nullptr; } else { //HTTP API String apireq = "win&"; apireq += (char*)payloadStr; diff --git a/wled00/presets.cpp b/wled00/presets.cpp index cdbd82a37..8ffc96b10 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -4,7 +4,7 @@ * Methods to handle saving and loading presets to/from the filesystem */ -bool applyPreset(byte index) +bool applyPreset(byte index, byte callMode) { if (index == 0) return false; if (fileDoc) { @@ -14,7 +14,7 @@ bool applyPreset(byte index) #ifdef WLED_DEBUG_FS serializeJson(*fileDoc, Serial); #endif - deserializeState(fdo, index); + deserializeState(fdo, callMode, index); } else { DEBUGFS_PRINTLN(F("Make read buf")); DynamicJsonDocument fDoc(JSON_BUFFER_SIZE); @@ -24,7 +24,7 @@ bool applyPreset(byte index) #ifdef WLED_DEBUG_FS serializeJson(fDoc, Serial); #endif - deserializeState(fdo, index); + deserializeState(fdo, callMode, index); } if (!errorFlag) { diff --git a/wled00/wled.cpp b/wled00/wled.cpp index e5048d952..827025d93 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -387,7 +387,7 @@ void WLED::beginStrip() strip.setShowCallback(handleOverlayDraw); if (bootPreset > 0) { - applyPreset(bootPreset); + applyPreset(bootPreset, NOTIFIER_CALL_MODE_INIT); } else if (turnOnAtBoot) { if (briS > 0) bri = briS; else if (bri == 0) bri = 128; diff --git a/wled00/wled.h b/wled00/wled.h index 81a876558..225915406 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2107090 +#define VERSION 2107091 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG From a17f83ceddde25fc179220e66e89b9432a4a490b Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 9 Jul 2021 18:54:28 +0200 Subject: [PATCH 3/5] Renamed `NOTIFIER_CALL_MODE_` to `CALL_MODE_` --- CHANGELOG.md | 1 + .../Animated_Staircase/Animated_Staircase.h | 4 +- .../PIR_sensor_switch/PIR_Highlight_Standby | 2 +- .../usermod_PIR_sensor_switch.h | 2 +- .../wled06_usermod.ino | 32 +++++++-------- .../wled06_usermod.ino | 2 +- .../stairway-wipe-usermod-v2.h | 8 ++-- .../stairway_wipe_basic/wled06_usermod.ino | 8 ++-- .../usermod_rotary_brightness_color.h | 4 +- .../usermod_v2_rotary_encoder_ui.h | 4 +- .../word-clock-matrix/word-clock-matrix.cpp | 4 +- wled00/alexa.cpp | 12 +++--- wled00/blynk.cpp | 14 +++---- wled00/button.cpp | 20 +++++----- wled00/const.h | 24 +++++------ wled00/e131.cpp | 6 +-- wled00/fcn_declare.h | 4 +- wled00/hue.cpp | 2 +- wled00/ir.cpp | 28 ++++++------- wled00/json.cpp | 4 +- wled00/led.cpp | 40 +++++++++---------- wled00/mqtt.cpp | 4 +- wled00/set.cpp | 2 +- wled00/udp.cpp | 18 ++++----- wled00/wled.cpp | 4 +- wled00/wled.h | 4 +- 26 files changed, 129 insertions(+), 128 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f4ad85ff..ee2740839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Fixed presets using wrong call mode (e.g. causing buttons to send UDP under direct change type) - Increased hue buffer +- Renamed `NOTIFIER_CALL_MODE_` to `CALL_MODE_` #### Build 2107090 diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index b94760e96..9bd2a8a39 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -123,7 +123,7 @@ class Animated_Staircase : public Usermod { // Always mark segments as "transitional", we are animating the staircase segments->setOption(SEG_OPTION_TRANSITIONAL, 1, 1); } - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); } /* @@ -298,7 +298,7 @@ class Animated_Staircase : public Usermod { } segments->setOption(SEG_OPTION_ON, 1, 1); } - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); DEBUG_PRINTLN(F("Animated Staircase disabled.")); } enabled = enable; diff --git a/usermods/PIR_sensor_switch/PIR_Highlight_Standby b/usermods/PIR_sensor_switch/PIR_Highlight_Standby index ddbbddeae..4cca1874d 100644 --- a/usermods/PIR_sensor_switch/PIR_Highlight_Standby +++ b/usermods/PIR_sensor_switch/PIR_Highlight_Standby @@ -62,7 +62,7 @@ class PIRsensorSwitch : public Usermod { // PIR sensor pin const uint8_t PIRsensorPin = 13; // D7 on D1 mini // notification mode for colorUpdated() - const byte NotifyUpdateMode = NOTIFIER_CALL_MODE_NO_NOTIFY; // NOTIFIER_CALL_MODE_DIRECT_CHANGE + const byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // CALL_MODE_DIRECT_CHANGE // 1 min delay before switch off after the sensor state goes LOW uint32_t m_switchOffDelay = 60000; // off timer start time diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index 3552724fe..c85cead5f 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -58,7 +58,7 @@ private: // PIR sensor pin int8_t PIRsensorPin = PIR_SENSOR_PIN; // notification mode for colorUpdated() - const byte NotifyUpdateMode = NOTIFIER_CALL_MODE_NO_NOTIFY; // NOTIFIER_CALL_MODE_DIRECT_CHANGE + const byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // CALL_MODE_DIRECT_CHANGE // delay before switch off after the sensor state goes LOW uint32_t m_switchOffDelay = 600000; // 10min // off timer start time diff --git a/usermods/battery_keypad_controller/wled06_usermod.ino b/usermods/battery_keypad_controller/wled06_usermod.ino index 877713b61..acc1bd8c4 100644 --- a/usermods/battery_keypad_controller/wled06_usermod.ino +++ b/usermods/battery_keypad_controller/wled06_usermod.ino @@ -54,46 +54,46 @@ void userLoop() switch (myKey) { case '1': applyPreset(1); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '2': applyPreset(2); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '3': applyPreset(3); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '4': applyPreset(4); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '5': applyPreset(5); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '6': applyPreset(6); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'A': applyPreset(7); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'B': applyPreset(8); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '7': effectCurrent += 1; if (effectCurrent >= MODE_COUNT) effectCurrent = 0; - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '*': effectCurrent -= 1; if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '8': @@ -102,7 +102,7 @@ void userLoop() } else if (effectSpeed < 255) { effectSpeed += 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '0': if (effectSpeed > 15) { @@ -110,7 +110,7 @@ void userLoop() } else if (effectSpeed > 0) { effectSpeed -= 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '9': @@ -119,7 +119,7 @@ void userLoop() } else if (effectIntensity < 255) { effectIntensity += 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '#': if (effectIntensity > 15) { @@ -127,18 +127,18 @@ void userLoop() } else if (effectIntensity > 0) { effectIntensity -= 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'C': effectPalette += 1; if (effectPalette >= 50) effectPalette = 0; - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'D': effectPalette -= 1; if (effectPalette <= 0) effectPalette = 50; - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; } diff --git a/usermods/rotary_encoder_change_effect/wled06_usermod.ino b/usermods/rotary_encoder_change_effect/wled06_usermod.ino index f004ba2f4..5444ab9fb 100644 --- a/usermods/rotary_encoder_change_effect/wled06_usermod.ino +++ b/usermods/rotary_encoder_change_effect/wled06_usermod.ino @@ -39,7 +39,7 @@ void userLoop() { //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); lastTime = millis(); } } diff --git a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h index 816b6e8d9..67c78feed 100644 --- a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h +++ b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h @@ -42,7 +42,7 @@ class StairwayWipeUsermod : public Usermod { if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete effectCurrent = FX_MODE_STATIC; timeStaticStart = millis(); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 2; } } else if (wipeState == 2) { //static @@ -54,7 +54,7 @@ class StairwayWipeUsermod : public Usermod { #ifdef STAIRCASE_WIPE_OFF effectCurrent = FX_MODE_COLOR_WIPE; strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 4; #else turnOff(); @@ -100,7 +100,7 @@ class StairwayWipeUsermod : public Usermod { bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); } void turnOff() @@ -111,7 +111,7 @@ class StairwayWipeUsermod : public Usermod { transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 0; userVar0 = 0; previousUserVar0 = 0; diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index 0cc85df74..a0dcc3bb2 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -47,7 +47,7 @@ void userLoop() if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete effectCurrent = FX_MODE_STATIC; timeStaticStart = millis(); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 2; } } else if (wipeState == 2) { //static @@ -59,7 +59,7 @@ void userLoop() #ifdef STAIRCASE_WIPE_OFF effectCurrent = FX_MODE_COLOR_WIPE; strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 4; #else turnOff(); @@ -93,7 +93,7 @@ void startWipe() bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); } void turnOff() @@ -104,7 +104,7 @@ void turnOff() transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 0; userVar0 = 0; previousUserVar0 = 0; diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h index 24f1e7ae4..61b76ba19 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h @@ -138,8 +138,8 @@ public: } //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); - updateInterfaces(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); + updateInterfaces(CALL_MODE_BUTTON); } Enc_A_prev = Enc_A; // Store value of A for next time loopTime = currentTime; // Updates loopTime diff --git a/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h b/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h index 5ff1090d2..424bb67ac 100644 --- a/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h +++ b/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h @@ -267,8 +267,8 @@ public: //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); - updateInterfaces(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); + updateInterfaces(CALL_MODE_DIRECT_CHANGE); } void changeBrightness(bool increase) { diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index aadfb8b18..5c8985f17 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -64,13 +64,13 @@ void hourChime() { //strip.resetSegments(); selectWordSegments(true); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); savePreset(13, false); selectWordSegments(false); //strip.getSegment(0).setOption(0, true); strip.getSegment(0).setOption(2, true); applyPreset(12); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); } void displayTime(byte hour, byte minute) diff --git a/wled00/alexa.cpp b/wled00/alexa.cpp index 213c9306d..2e5b9b17b 100644 --- a/wled00/alexa.cpp +++ b/wled00/alexa.cpp @@ -44,10 +44,10 @@ void onAlexaChange(EspalexaDevice* dev) if (bri == 0) { bri = briLast; - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } } else { - applyPreset(macroAlexaOn, NOTIFIER_CALL_MODE_ALEXA); + applyPreset(macroAlexaOn, CALL_MODE_ALEXA); if (bri == 0) espalexaDevice->setValue(briLast); //stop Alexa from complaining if macroAlexaOn does not actually turn on } } else if (m == EspalexaDeviceProperty::off) @@ -58,16 +58,16 @@ void onAlexaChange(EspalexaDevice* dev) { briLast = bri; bri = 0; - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } } else { - applyPreset(macroAlexaOff, NOTIFIER_CALL_MODE_ALEXA); + applyPreset(macroAlexaOff, CALL_MODE_ALEXA); if (bri != 0) espalexaDevice->setValue(0); //stop Alexa from complaining if macroAlexaOff does not actually turn off } } else if (m == EspalexaDeviceProperty::bri) { bri = espalexaDevice->getValue(); - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } else //color { if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white @@ -93,7 +93,7 @@ void onAlexaChange(EspalexaDevice* dev) col[2] = ( color & 0xFF); col[3] = 0; } - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } } diff --git a/wled00/blynk.cpp b/wled00/blynk.cpp index ef53ca9b2..ce3904487 100644 --- a/wled00/blynk.cpp +++ b/wled00/blynk.cpp @@ -44,45 +44,45 @@ void updateBlynk() BLYNK_WRITE(V0) { bri = param.asInt();//bri - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V1) { blHue = param.asInt();//hue colorHStoRGB(blHue*10,blSat,(false)? colSec:col); - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V2) { blSat = param.asInt();//sat colorHStoRGB(blHue*10,blSat,(false)? colSec:col); - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V3) { bool on = (param.asInt()>0); - if (!on != !bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BLYNK);} + if (!on != !bri) {toggleOnOff(); colorUpdated(CALL_MODE_BLYNK);} } BLYNK_WRITE(V4) { effectCurrent = param.asInt()-1;//fx - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V5) { effectSpeed = param.asInt();//sx - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V6) { effectIntensity = param.asInt();//ix - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V7) diff --git a/wled00/button.cpp b/wled00/button.cpp index 7b044c49a..ba6a0c973 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -13,9 +13,9 @@ void shortPressAction(uint8_t b) if (!macroButton[b]) { toggleOnOff(); - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); } else { - applyPreset(macroButton[b], NOTIFIER_CALL_MODE_BUTTON); + applyPreset(macroButton[b], CALL_MODE_BUTTON); } // publish MQTT message @@ -62,14 +62,14 @@ void handleSwitch(uint8_t b) if (millis() - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce) if (!buttonPressedBefore[b]) { // on -> off - if (macroButton[b]) applyPreset(macroButton[b], NOTIFIER_CALL_MODE_BUTTON); + if (macroButton[b]) applyPreset(macroButton[b], CALL_MODE_BUTTON); else { //turn on - if (!bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);} + if (!bri) {toggleOnOff(); colorUpdated(CALL_MODE_BUTTON);} } } else { // off -> on - if (macroLongPress[b]) applyPreset(macroLongPress[b], NOTIFIER_CALL_MODE_BUTTON); + if (macroLongPress[b]) applyPreset(macroLongPress[b], CALL_MODE_BUTTON); else { //turn off - if (bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);} + if (bri) {toggleOnOff(); colorUpdated(CALL_MODE_BUTTON);} } } @@ -154,14 +154,14 @@ void handleAnalog(uint8_t b) seg.setOption(SEG_OPTION_ON, 1); } // this will notify clients of update (websockets,mqtt,etc) - updateInterfaces(NOTIFIER_CALL_MODE_BUTTON); + updateInterfaces(CALL_MODE_BUTTON); } } else { //TODO: // we can either trigger a preset depending on the level (between short and long entries) // or use it for RGBW direct control } - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); } void handleButton() @@ -195,7 +195,7 @@ void handleButton() { if (!buttonLongPressed[b]) { - if (macroLongPress[b]) {applyPreset(macroLongPress[b], NOTIFIER_CALL_MODE_BUTTON);} + if (macroLongPress[b]) {applyPreset(macroLongPress[b], CALL_MODE_BUTTON);} else _setRandomColor(false,true); // publish MQTT message @@ -224,7 +224,7 @@ void handleButton() if (macroDoublePress[b]) { if (doublePress) { - applyPreset(macroDoublePress[b], NOTIFIER_CALL_MODE_BUTTON); + applyPreset(macroDoublePress[b], CALL_MODE_BUTTON); // publish MQTT message if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { diff --git a/wled00/const.h b/wled00/const.h index e6297a60c..dec4bc030 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -66,18 +66,18 @@ #define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec //Notifier callMode -#define NOTIFIER_CALL_MODE_INIT 0 //no updates on init, can be used to disable updates -#define NOTIFIER_CALL_MODE_DIRECT_CHANGE 1 -#define NOTIFIER_CALL_MODE_BUTTON 2 -#define NOTIFIER_CALL_MODE_NOTIFICATION 3 -#define NOTIFIER_CALL_MODE_NIGHTLIGHT 4 -#define NOTIFIER_CALL_MODE_NO_NOTIFY 5 -#define NOTIFIER_CALL_MODE_FX_CHANGED 6 //no longer used -#define NOTIFIER_CALL_MODE_HUE 7 -#define NOTIFIER_CALL_MODE_PRESET_CYCLE 8 -#define NOTIFIER_CALL_MODE_BLYNK 9 -#define NOTIFIER_CALL_MODE_ALEXA 10 -#define NOTIFIER_CALL_MODE_WS_SEND 11 //special call mode, not for notifier, updates websocket only +#define CALL_MODE_INIT 0 //no updates on init, can be used to disable updates +#define CALL_MODE_DIRECT_CHANGE 1 +#define CALL_MODE_BUTTON 2 +#define CALL_MODE_NOTIFICATION 3 +#define CALL_MODE_NIGHTLIGHT 4 +#define CALL_MODE_NO_NOTIFY 5 +#define CALL_MODE_FX_CHANGED 6 //no longer used +#define CALL_MODE_HUE 7 +#define CALL_MODE_PRESET_CYCLE 8 +#define CALL_MODE_BLYNK 9 +#define CALL_MODE_ALEXA 10 +#define CALL_MODE_WS_SEND 11 //special call mode, not for notifier, updates websocket only //RGB to RGBW conversion mode #define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider diff --git a/wled00/e131.cpp b/wled00/e131.cpp index 9ca092a9a..d556e6768 100644 --- a/wled00/e131.cpp +++ b/wled00/e131.cpp @@ -156,9 +156,9 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){ col[3] = e131_data[DMXAddress+11]; //white colSec[3] = e131_data[DMXAddress+12]; } - transitionDelayTemp = 0; // act fast - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP - return; // don't activate realtime live mode + transitionDelayTemp = 0; // act fast + colorUpdated(CALL_MODE_NOTIFICATION); // don't send UDP + return; // don't activate realtime live mode break; case DMX_MODE_MULTIPLE_DRGB: diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 4fe07f743..87ccebb2b 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -120,7 +120,7 @@ void handleIR(); #include "FX.h" void deserializeSegment(JsonObject elem, byte it, byte presetId = 0); -bool deserializeState(JsonObject root, byte callMode = NOTIFIER_CALL_MODE_DIRECT_CHANGE, byte presetId = 0); +bool deserializeState(JsonObject root, byte callMode = CALL_MODE_DIRECT_CHANGE, byte presetId = 0); void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true); void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true); void serializeInfo(JsonObject root); @@ -181,7 +181,7 @@ void loadPlaylist(JsonObject playlistObject, byte presetId = 0); void handlePlaylist(); //presets.cpp -bool applyPreset(byte index, byte callMode = NOTIFIER_CALL_MODE_DIRECT_CHANGE); +bool applyPreset(byte index, byte callMode = CALL_MODE_DIRECT_CHANGE); void savePreset(byte index, bool persist = true, const char* pname = nullptr, JsonObject saveobj = JsonObject()); void deletePreset(byte index); diff --git a/wled00/hue.cpp b/wled00/hue.cpp index 47b252e91..4e775f664 100644 --- a/wled00/hue.cpp +++ b/wled00/hue.cpp @@ -10,7 +10,7 @@ void handleHue() { if (hueReceived) { - colorUpdated(NOTIFIER_CALL_MODE_HUE); hueReceived = false; + colorUpdated(CALL_MODE_HUE); hueReceived = false; if (hueStoreAllowed && hueNewKey) { serializeConfigSec(); //save api key diff --git a/wled00/ir.cpp b/wled00/ir.cpp index a08321a5b..4a45e6660 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -71,7 +71,7 @@ void decBrightness() // apply preset or fallback to a effect and palette if it doesn't exist void presetFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) { - if (!applyPreset(presetID, NOTIFIER_CALL_MODE_BUTTON)) { + if (!applyPreset(presetID, CALL_MODE_BUTTON)) { effectCurrent = effectID; effectPalette = paletteID; } @@ -85,11 +85,11 @@ bool decodeIRCustom(uint32_t code) { //just examples, feel free to modify or remove case IRCUSTOM_ONOFF : toggleOnOff(); break; - case IRCUSTOM_MACRO1 : applyPreset(1, NOTIFIER_CALL_MODE_BUTTON); break; + case IRCUSTOM_MACRO1 : applyPreset(1, CALL_MODE_BUTTON); break; default: return false; } - if (code != IRCUSTOM_MACRO1) colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //don't update color again if we apply macro, it already does it + if (code != IRCUSTOM_MACRO1) colorUpdated(CALL_MODE_BUTTON); //don't update color again if we apply macro, it already does it return true; } @@ -183,51 +183,51 @@ void decodeIR(uint32_t code) } if (nightlightActive && bri == 0) nightlightActive = false; - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input + colorUpdated(CALL_MODE_BUTTON); //for notifier, IR is considered a button input } void applyRepeatActions(){ if (lastRepeatableAction == ACTION_BRIGHT_UP) { - incBrightness(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + incBrightness(); colorUpdated(CALL_MODE_BUTTON); } else if (lastRepeatableAction == ACTION_BRIGHT_DOWN ) { - decBrightness(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + decBrightness(); colorUpdated(CALL_MODE_BUTTON); } if (lastRepeatableAction == ACTION_SPEED_UP) { - changeEffectSpeed(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectSpeed(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } else if (lastRepeatableAction == ACTION_SPEED_DOWN ) { - changeEffectSpeed(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectSpeed(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } if (lastRepeatableAction == ACTION_INTENSITY_UP) { - changeEffectIntensity(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectIntensity(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } else if (lastRepeatableAction == ACTION_INTENSITY_DOWN ) { - changeEffectIntensity(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectIntensity(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } if (lastValidCode == IR40_WPLUS) { - relativeChangeWhite(10); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + relativeChangeWhite(10); colorUpdated(CALL_MODE_BUTTON); } else if (lastValidCode == IR40_WMINUS) { - relativeChangeWhite(-10, 5); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + relativeChangeWhite(-10, 5); colorUpdated(CALL_MODE_BUTTON); } else if ((lastValidCode == IR24_ON || lastValidCode == IR40_ON) && irTimesRepeated > 7 ) { nightlightActive = true; nightlightStartTime = millis(); - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); } else if (irEnabled == 8) { @@ -612,7 +612,7 @@ void decodeIRJson(uint32_t code) // command is JSON object //allow applyPreset() to reuse JSON buffer, or it would alloc. a second buffer and run out of mem. fileDoc = &irDoc; - deserializeState(jsonCmdObj, NOTIFIER_CALL_MODE_BUTTON); + deserializeState(jsonCmdObj, CALL_MODE_BUTTON); fileDoc = nullptr; } } diff --git a/wled00/json.cpp b/wled00/json.cpp index 78ee3883f..a94270991 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -312,10 +312,10 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) loadPlaylist(playlist, presetId); noNotification = true; //do not notify both for this request and the first playlist entry } else { - interfaceUpdateCallMode = NOTIFIER_CALL_MODE_WS_SEND; + interfaceUpdateCallMode = CALL_MODE_WS_SEND; } - colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : callMode); + colorUpdated(noNotification ? CALL_MODE_NO_NOTIFY : callMode); return stateResponse; } diff --git a/wled00/led.cpp b/wled00/led.cpp index 9f034ca2b..25c684e32 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -88,13 +88,13 @@ void colorUpdated(int callMode) { //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - if (callMode != NOTIFIER_CALL_MODE_INIT && - callMode != NOTIFIER_CALL_MODE_DIRECT_CHANGE && - callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments + if (callMode != CALL_MODE_INIT && + callMode != CALL_MODE_DIRECT_CHANGE && + callMode != CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments bool someSel = false; - if (callMode == NOTIFIER_CALL_MODE_NOTIFICATION) { + if (callMode == CALL_MODE_NOTIFICATION) { someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); } @@ -119,17 +119,17 @@ void colorUpdated(int callMode) interfaceUpdateCallMode = callMode; } else { if (nightlightActive && !nightlightActiveOld && - callMode != NOTIFIER_CALL_MODE_NOTIFICATION && - callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) + callMode != CALL_MODE_NOTIFICATION && + callMode != CALL_MODE_NO_NOTIFY) { - notify(NOTIFIER_CALL_MODE_NIGHTLIGHT); - interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT; + notify(CALL_MODE_NIGHTLIGHT); + interfaceUpdateCallMode = CALL_MODE_NIGHTLIGHT; } } if (!colChanged) return; //following code is for e.g. initiating transitions - if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)) + if (callMode != CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)) { briNlT = bri; nightlightDelayMs -= (millis() - nightlightStartTime); @@ -143,19 +143,19 @@ void colorUpdated(int callMode) if (briT == 0) { //setLedsStandard(true); //do not color transition if starting from off! - if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning + if (callMode != CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning } briIT = bri; if (bri > 0) briLast = bri; //deactivate nightlight if target brightness is reached - if (bri == nightlightTargetBri && callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightMode != NL_MODE_SUN) nightlightActive = false; + if (bri == nightlightTargetBri && callMode != CALL_MODE_NO_NOTIFY && nightlightMode != NL_MODE_SUN) nightlightActive = false; if (fadeTransition) { //set correct delay if not using notification delay - if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; + if (callMode != CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; jsonTransitionOnce = false; strip.setTransition(transitionDelayTemp); if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;} @@ -180,19 +180,19 @@ void colorUpdated(int callMode) void updateInterfaces(uint8_t callMode) { sendDataWs(); - if (callMode == NOTIFIER_CALL_MODE_WS_SEND) { + if (callMode == CALL_MODE_WS_SEND) { lastInterfaceUpdate = millis(); return; } #ifndef WLED_DISABLE_ALEXA - if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) { + if (espalexaDevice != nullptr && callMode != CALL_MODE_ALEXA) { espalexaDevice->setValue(bri); espalexaDevice->setColor(col[0], col[1], col[2]); } #endif - if (callMode != NOTIFIER_CALL_MODE_BLYNK && - callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) updateBlynk(); + if (callMode != CALL_MODE_BLYNK && + callMode != CALL_MODE_NO_NOTIFY) updateBlynk(); doPublishMqtt = true; lastInterfaceUpdate = millis(); } @@ -254,7 +254,7 @@ void handleNightlight() if (bri) effectSpeed += 60; //sunset if currently on briNlT = !bri; //true == sunrise, false == sunset if (!bri) bri = briLast; - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); @@ -265,7 +265,7 @@ void handleNightlight() { for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color } - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } if (nper >= 1) //nightlight duration over { @@ -273,7 +273,7 @@ void handleNightlight() if (nightlightMode == NL_MODE_SET) { bri = nightlightTargetBri; - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } if (bri == 0) briLast = briNlT; if (nightlightMode == NL_MODE_SUN) @@ -297,7 +297,7 @@ void handleNightlight() effectCurrent = colNlT[0]; effectSpeed = colNlT[1]; effectPalette = colNlT[2]; - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } nightlightActiveOld = false; } diff --git a/wled00/mqtt.cpp b/wled00/mqtt.cpp index b6975962d..d76632fc1 100644 --- a/wled00/mqtt.cpp +++ b/wled00/mqtt.cpp @@ -15,7 +15,7 @@ void parseMQTTBriPayload(char* payload) uint8_t in = strtoul(payload, NULL, 10); if (in == 0 && bri > 0) briLast = bri; bri = in; - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); } } @@ -88,7 +88,7 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties if (strcmp_P(topic, PSTR("/col")) == 0) { colorFromDecOrHexString(col, (char*)payloadStr); - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); } else if (strcmp_P(topic, PSTR("/api")) == 0) { if (payload[0] == '{') { //JSON API DynamicJsonDocument doc(JSON_BUFFER_SIZE); diff --git a/wled00/set.cpp b/wled00/set.cpp index 361f00d9c..37004dd05 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -919,7 +919,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) strip.applyToAllSelected = false; pos = req.indexOf(F("&NN")); //do not send UDP notifications this time - colorUpdated((pos > 0) ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated((pos > 0) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE); return true; } diff --git a/wled00/udp.cpp b/wled00/udp.cpp index ad6e727ae..df30cde20 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -13,14 +13,14 @@ void notify(byte callMode, bool followUp) if (!udpConnected) return; switch (callMode) { - case NOTIFIER_CALL_MODE_INIT: return; - case NOTIFIER_CALL_MODE_DIRECT_CHANGE: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_BUTTON: if (!notifyButton) return; break; - case NOTIFIER_CALL_MODE_NIGHTLIGHT: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_HUE: if (!notifyHue) return; break; - case NOTIFIER_CALL_MODE_PRESET_CYCLE: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_BLYNK: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_ALEXA: if (!notifyAlexa) return; break; + case CALL_MODE_INIT: return; + case CALL_MODE_DIRECT_CHANGE: if (!notifyDirect) return; break; + case CALL_MODE_BUTTON: if (!notifyButton) return; break; + case CALL_MODE_NIGHTLIGHT: if (!notifyDirect) return; break; + case CALL_MODE_HUE: if (!notifyHue) return; break; + case CALL_MODE_PRESET_CYCLE: if (!notifyDirect) return; break; + case CALL_MODE_BLYNK: if (!notifyDirect) return; break; + case CALL_MODE_ALEXA: if (!notifyAlexa) return; break; default: return; } byte udpOut[WLEDPACKETSIZE]; @@ -296,7 +296,7 @@ void handleNotifications() if (nightlightActive) nightlightDelayMins = udpIn[7]; if (receiveNotificationBrightness || !someSel) bri = udpIn[2]; - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); return; } diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 827025d93..e925740a3 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -387,14 +387,14 @@ void WLED::beginStrip() strip.setShowCallback(handleOverlayDraw); if (bootPreset > 0) { - applyPreset(bootPreset, NOTIFIER_CALL_MODE_INIT); + applyPreset(bootPreset, CALL_MODE_INIT); } else if (turnOnAtBoot) { if (briS > 0) bri = briS; else if (bri == 0) bri = 128; } else { briLast = briS; bri = 0; } - colorUpdated(NOTIFIER_CALL_MODE_INIT); + colorUpdated(CALL_MODE_INIT); // init relay pin if (rlyPin>=0) diff --git a/wled00/wled.h b/wled00/wled.h index 225915406..c73813862 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -453,7 +453,7 @@ WLED_GLOBAL byte touchThreshold _INIT(TOUCH_THRESH WLED_GLOBAL bool notifyDirectDefault _INIT(notifyDirect); WLED_GLOBAL bool receiveNotifications _INIT(true); WLED_GLOBAL unsigned long notificationSentTime _INIT(0); -WLED_GLOBAL byte notificationSentCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL byte notificationSentCallMode _INIT(CALL_MODE_INIT); WLED_GLOBAL bool notificationTwoRequired _INIT(false); // effects @@ -519,7 +519,7 @@ WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0); // mqtt WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0); WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0); -WLED_GLOBAL byte interfaceUpdateCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT); WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers // alexa udp From 3ad336a1eb42d7023bb1c548b66e50b4cafbd190 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 9 Jul 2021 11:06:48 -0700 Subject: [PATCH 4/5] Bug 2064, 2063 - PinManager usage (#2066) * Fix 2063 - Do not free pins unless allocated * Fix 2064: Allocate pins used for Ethernet * Fix obvious compilation errors. * Fix multiple bugs... * pinsAllocated[2] set twice due to copy/paste bug. * wrong pin allocated for ETH_CLOCK_GPIO17_OUT due to copy/paste bug * Stylistic change per PR review * Stylistic change per PR review * attempt to allocate pin for "default" button * remove extra local variable * check return value from ETH.begin() Co-authored-by: Christian Schwinne --- wled00/bus_manager.h | 11 ++++---- wled00/cfg.cpp | 10 +++++-- wled00/wled.cpp | 62 ++++++++++++++++++++++++++++++++++++------ wled00/wled_ethernet.h | 12 ++++++-- 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 530cae32d..295a84e52 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -119,13 +119,13 @@ class BusDigital : public Bus { public: BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) { if (!IS_DIGITAL(bc.type) || !bc.count) return; + if (!pinManager.allocatePin(bc.pins[0])) return; _pins[0] = bc.pins[0]; - if (!pinManager.allocatePin(_pins[0])) return; if (IS_2PIN(bc.type)) { - _pins[1] = bc.pins[1]; - if (!pinManager.allocatePin(_pins[1])) { + if (!pinManager.allocatePin(bc.pins[1])) { cleanup(); return; } + _pins[1] = bc.pins[1]; } reversed = bc.reversed; _skip = bc.skipAmount; //sacrificial pixels @@ -241,10 +241,11 @@ class BusPwm : public Bus { #endif for (uint8_t i = 0; i < numPins; i++) { - _pins[i] = bc.pins[i]; - if (!pinManager.allocatePin(_pins[i])) { + uint8_t currentPin = bc.pins[i]; + if (!pinManager.allocatePin(currentPin)) { deallocatePins(); return; } + _pins[i] = currentPin; // store only after allocatePin() succeeds #ifdef ESP8266 pinMode(_pins[i], OUTPUT); #else diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index d4cce2f37..d054b8b08 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -152,14 +152,20 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } } else { // new install/missing configuration (button 0 has defaults) - if (fromFS) - for (uint8_t s=1; s Date: Fri, 9 Jul 2021 20:25:35 +0200 Subject: [PATCH 5/5] New usermod: Support for RGB Rotary Encoder Board (#2068) * Added RGB Rotary Encoder usermod v1 * RGB rotary encoder UM: Readme; Added example video * RGB rotary encoder UM: Readme; Added example video * RGB rotary encoder UM: Fixed getJsonValue usage * RGB rotary encoder UM: Removed spaces in JSON keys * RGB rotary encoder UM: Cleanup readFromConfig * RGB rotary encoder UM: Cleaned up type usages * RGB rotary encoder UM: Fixed crash on re-enable --- usermods/rgb-rotary-encoder/readme.md | 86 +++++ .../rgb-rotary-encoder/rgb-rotary-encoder.h | 344 ++++++++++++++++++ wled00/usermods_list.cpp | 8 + 3 files changed, 438 insertions(+) create mode 100644 usermods/rgb-rotary-encoder/readme.md create mode 100644 usermods/rgb-rotary-encoder/rgb-rotary-encoder.h diff --git a/usermods/rgb-rotary-encoder/readme.md b/usermods/rgb-rotary-encoder/readme.md new file mode 100644 index 000000000..2bf0ecb72 --- /dev/null +++ b/usermods/rgb-rotary-encoder/readme.md @@ -0,0 +1,86 @@ +# RGB Encoder Board + +This usermod-v2 adds support for the awesome RGB Rotary Encoder Board by Adam Zeloof / "Isotope Engineering" to control the overall brightness of your WLED instance: https://github.com/isotope-engineering/RGB-Encoder-Board. A great DIY rotary encoder with 20 tiny SK6805 / "NeoPixel Nano" LEDs. + +https://user-images.githubusercontent.com/3090131/124680599-0180ab80-dec7-11eb-9065-a6d08ebe0287.mp4 + +## Credits +The actual / original code that does the different LED modes is from Adam Zeloof. So I don't take credit for these. But I ported it to WLED, which involved replacing the LED library he used (because, guess what, WLED already has one; so no need to add another one, but use whatever WLED uses), plus the rotary encoder library, because that one was not compatible with ESP, only Arduino. +So it was quite more work than I hoped, but I got there eventually :) + +## Requirements +* "ESP Rotary" by Lennart Hennigs, v1.5.0 or higher: https://github.com/LennartHennigs/ESPRotary + +## Usermod installation +Simply copy the below block (build task) to your `platformio_override.ini` and compile WLED using this new build task. Or use an existing one and add the buildflag `-D RGB_ROTARY_ENCODER`. + +ESP32: +``` +[env:custom_esp32dev_usermod_rgb_encoder_board] +extends = env:esp32dev +build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 -D RGB_ROTARY_ENCODER +lib_deps = ${esp32.lib_deps} + lennarthennigs/ESP Rotary@^1.5.0 +``` + +ESP8266 / D1 Mini: +``` +[env:custom_d1_mini_usermod_rgb_encoder_board] +extends = env:d1_mini +build_flags = ${common.build_flags_esp8266} -D RGB_ROTARY_ENCODER +lib_deps = ${esp8266.lib_deps} + lennarthennigs/ESP Rotary@^1.5.0 +``` + +## How to connect the board to your ESP +We gonna need (minimum) three or (maximum) four GPIOs for the board: +* "ea": Basically tells if the encoder goes into one or the other direction +* "eb": Same thing, but the other direction +* "di": LED data in. To actually control the LEDs +* *(optional)* "sw": The integrated switch in the rotary encoder. Can be omitted for the bare functionality of just controlling the brightness + +We also gonna need some power, so: + +* "vdd": Needs to be connected to **+5V**. +* "gnd": Well, it's GND. + +You can freely pick the GPIOs, it doesn't matter. Those will be configured in the "Usermods" section in the WLED web panel: + +## Configuration +Navigate to the "Config" and then to the "Usermods" section. If you compiled WLED with `-D RGB_ROTARY_ENCODER`, you will see the config for it there. The settings there are the GPIOs we mentioned before (*Note: The switch pin is not there, as this can just be configured the "normal" button on the "LED Preferences" page*), plus a few more: +* LED pin: + * Possible values: Any valid and available GPIO + * Default: 3 + * What it does: Pin to control the LED ring +* ea pin: + * Possible values: Any valid and available GPIO + * Default: 15 + * What it does: First of the two rotary encoder pins +* eb pin: + * Possible values: Any valid and available GPIO + * Default: 32 + * What it does: Second of the two rotary encoder pins +* LED Mode: + * Possible values: 1-3 + * Default: 3 + * What it does: The usermod provides three different modes of how the LEDs can look like. Here's an example: https://github.com/isotope-engineering/RGB-Encoder-Board/blob/master/images/rgb-encoder-animations.gif + * Up left is "1" + * Up right is not supported / doesn't make sense for brightness control + * Bottom left is "2" + * Bottom right is "3" +* LED Brightness: + * Possible values: 1-255 + * Default: 64 + * What it does: Brightness of the LED ring +* Steps per click: + * Possible values: Any positive number + * Default: 4 + * What it does: With each "click", a rotary encoder actually increments it's "steps". Most rotary encoder do four "steps" per "click". I know this sounds super weird, so just leave this the default value, unless your rotary encoder behaves weirdly, like with one click, it makes two LEDs light up, or you sometimes need two click for one LED. Then you should play around with this value or write a small sketch using the same "ESP Rotary" library and read out the steps it does. +* Increment per click: + * Possible values: Any positive number + * Default: 5 + * What it does: Most rotary encoder have 20 "clicks", so basically 20 positions. This value should be set to 100 / `number of clicks` + +## Change log +2021-07 +* First implementation. diff --git a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.h b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.h new file mode 100644 index 000000000..ab680a8f3 --- /dev/null +++ b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.h @@ -0,0 +1,344 @@ +#pragma once + +#include "ESPRotary.h" +#include +#include "wled.h" + +class RgbRotaryEncoderUsermod : public Usermod +{ + private: + bool enabled = false; + bool initDone = false; + bool isDirty = false; + BusDigital *ledBus; + /* + * Green - eb - Q4 - 32 + * Red - ea - Q1 - 15 + * Black - sw - Q2 - 12 + */ + ESPRotary *rotaryEncoder; + int8_t ledIo = 3; // GPIO to control the LEDs + int8_t eaIo = 15; // "ea" from RGB Encoder Board + int8_t ebIo = 32; // "eb" from RGB Encoder Board + byte stepsPerClick = 4; // How many "steps" your rotary encoder does per click. This varies per rotary encoder + /* This could vary per rotary encoder: Usually rotary encoders have 20 "clicks". + If yours has less/more, adjust this to: 100% = 20 LEDs * incrementPerClick */ + byte incrementPerClick = 5; + byte ledMode = 3; + byte ledBrightness = 64; + + // This is all needed to calculate the brightness, rotary position, etc. + const byte minPos = 5; // minPos is not zero, because if we want to turn the LEDs off, we use the built-in button ;) + const byte maxPos = 100; // maxPos=100, like 100% + const byte numLeds = 20; + byte lastKnownPos = 0; + + byte currentColors[3]; + byte lastKnownBri = 0; + + + void initRotaryEncoder() + { + if (!pinManager.allocatePin(eaIo, false)) { + eaIo = -1; + } + if (!pinManager.allocatePin(ebIo, false)) { + ebIo = -1; + } + if (eaIo == -1 || ebIo == -1) { + cleanup(); + return; + } + + // I don't know why, but setting the upper bound here does not work. It results into 1717922932 O_o + rotaryEncoder = new ESPRotary(eaIo, ebIo, stepsPerClick, incrementPerClick, maxPos, currentPos, incrementPerClick); + rotaryEncoder->setUpperBound(maxPos); // I have to again set it here and then it works / is actually 100... + + rotaryEncoder->setChangedHandler(RgbRotaryEncoderUsermod::cbRotate); + } + + void initLedBus() + { + byte _pins[5] = {(byte)ledIo, 255, 255, 255, 255}; + BusConfig busCfg = BusConfig(TYPE_WS2812_RGB, _pins, 0, numLeds, COL_ORDER_GRB, false, 0); + + ledBus = new BusDigital(busCfg, WLED_MAX_BUSSES - 1); + if (!ledBus->isOk()) { + cleanup(); + return; + } + + ledBus->setBrightness(ledBrightness); + } + + void updateLeds() + { + switch (ledMode) { + case 2: + { + currentColors[0] = 255; currentColors[1] = 0; currentColors[2] = 0; + for (int i = 0; i < currentPos / incrementPerClick - 1; i++) { + ledBus->setPixelColor(i, 0); + } + ledBus->setPixelColor(currentPos / incrementPerClick - 1, colorFromRgbw(currentColors)); + for (int i = currentPos / incrementPerClick; i < numLeds; i++) { + ledBus->setPixelColor(i, 0); + } + } + break; + + default: + case 1: + case 3: + // WLED orange (of course), which we will use in mode 1 + currentColors[0] = 255; currentColors[1] = 160; currentColors[2] = 0; + for (int i = 0; i < currentPos / incrementPerClick; i++) { + if (ledMode == 3) { + hsv2rgb((i) / float(numLeds), 1, .25); + } + ledBus->setPixelColor(i, colorFromRgbw(currentColors)); + } + for (int i = currentPos / incrementPerClick; i < numLeds; i++) { + ledBus->setPixelColor(i, 0); + } + break; + } + + isDirty = true; + } + + void cleanup() + { + // Only deallocate pins if we allocated them ;) + if (eaIo != -1) { + pinManager.deallocatePin(eaIo); + } + if (ebIo != -1) { + pinManager.deallocatePin(ebIo); + } + + delete rotaryEncoder; + delete ledBus; + + enabled = false; + } + + int getPositionForBrightness() + { + return int(((float)bri / (float)255) * 100); + } + + float fract(float x) { return x - int(x); } + + float mix(float a, float b, float t) { return a + (b - a) * t; } + + void hsv2rgb(float h, float s, float v) { + currentColors[0] = int((v * mix(1.0, constrain(abs(fract(h + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s)) * 255); + currentColors[1] = int((v * mix(1.0, constrain(abs(fract(h + 0.6666666) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s)) * 255); + currentColors[2] = int((v * mix(1.0, constrain(abs(fract(h + 0.3333333) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s)) * 255); + } + + public: + static byte currentPos; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _ledIo[]; + static const char _eaIo[]; + static const char _ebIo[]; + static const char _ledMode[]; + static const char _ledBrightness[]; + static const char _stepsPerClick[]; + static const char _incrementPerClick[]; + + + static void cbRotate(ESPRotary& r) { + currentPos = r.getPosition(); + } + + /** + * Enable/Disable the usermod + */ + // inline void enable(bool enable) { enabled = enable; } + /** + * Get usermod enabled/disabled state + */ + // inline bool isEnabled() { return enabled; } + + /* + * setup() is called once at boot. WiFi is not yet connected at this point. + * You can use it to initialize variables, sensors or similar. + */ + void setup() + { + if (enabled) { + currentPos = getPositionForBrightness(); + lastKnownBri = bri; + + initRotaryEncoder(); + initLedBus(); + + // No updating of LEDs here, as that's sometimes not working; loop() will take care of that + + initDone = true; + } + } + + /* + * loop() is called continuously. Here you can check for events, read sensors, etc. + * + * Tips: + * 1. You can use "if (WLED_CONNECTED)" to check for a successful network connection. + * Additionally, "if (WLED_MQTT_CONNECTED)" is available to check for a connection to an MQTT broker. + * + * 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds. + * Instead, use a timer check as shown here. + */ + void loop() + { + if (!enabled || strip.isUpdating()) return; + + rotaryEncoder->loop(); + + // If the rotary was changed + if(lastKnownPos != currentPos) { + lastKnownPos = currentPos; + + bri = min(int(round((2.55 * currentPos))), 255); + lastKnownBri = bri; + + updateLeds(); + colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + } + + // If the brightness is changed not with the rotary, update the rotary + if (bri != lastKnownBri) { + currentPos = lastKnownPos = getPositionForBrightness(); + lastKnownBri = bri; + rotaryEncoder->resetPosition(currentPos); + updateLeds(); + } + + // Update LEDs here in loop to also validate that we can update/show + if (isDirty && ledBus->canShow()) { + isDirty = false; + ledBus->show(); + } + } + + void addToConfig(JsonObject &root) + { + JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname + + top[FPSTR(_enabled)] = enabled; + top[FPSTR(_ledIo)] = ledIo; + top[FPSTR(_eaIo)] = eaIo; + top[FPSTR(_ebIo)] = ebIo; + top[FPSTR(_ledMode)] = ledMode; + top[FPSTR(_ledBrightness)] = ledBrightness; + top[FPSTR(_stepsPerClick)] = stepsPerClick; + top[FPSTR(_incrementPerClick)] = incrementPerClick; + } + + /** + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + * + * The function should return true if configuration was successfully loaded or false if there was no configuration. + */ + bool readFromConfig(JsonObject &root) + { + JsonObject top = root[FPSTR(_name)]; + if (top.isNull()) { + DEBUG_PRINTF("[%s] No config found. (Using defaults.)\n", _name); + return false; + } + + bool oldEnabled = enabled; + int8_t oldLedIo = ledIo; + int8_t oldEaIo = eaIo; + int8_t oldEbIo = ebIo; + byte oldLedMode = ledMode; + byte oldStepsPerClick = stepsPerClick; + byte oldIncrementPerClick = incrementPerClick; + byte oldLedBrightness = ledBrightness; + + getJsonValue(top[FPSTR(_enabled)], enabled); + getJsonValue(top[FPSTR(_ledIo)], ledIo); + getJsonValue(top[FPSTR(_eaIo)], eaIo); + getJsonValue(top[FPSTR(_ebIo)], ebIo); + getJsonValue(top[FPSTR(_stepsPerClick)], stepsPerClick); + getJsonValue(top[FPSTR(_incrementPerClick)], incrementPerClick); + ledMode = top[FPSTR(_ledMode)] > 0 && top[FPSTR(_ledMode)] < 4 ? top[FPSTR(_ledMode)] : ledMode; + ledBrightness = top[FPSTR(_ledBrightness)] > 0 && top[FPSTR(_ledBrightness)] <= 255 ? top[FPSTR(_ledBrightness)] : ledBrightness; + + if (!initDone) { + // First run: reading from cfg.json + // Nothing to do here, will be all done in setup() + } + // Mod was disabled, so run setup() + else if (enabled && enabled != oldEnabled) { + DEBUG_PRINTF("[%s] Usermod has been re-enabled\n", _name); + setup(); + } + // Config has been changed, so adopt to changes + else { + if (!enabled) { + DEBUG_PRINTF("[%s] Usermod has been disabled\n", _name); + cleanup(); + } + else { + DEBUG_PRINTF("[%s] Usermod is enabled\n", _name); + if (ledIo != oldLedIo) { + delete ledBus; + initLedBus(); + } + + if (ledBrightness != oldLedBrightness) { + ledBus->setBrightness(ledBrightness); + isDirty = true; + } + + if (ledMode != oldLedMode) { + updateLeds(); + } + + if (eaIo != oldEaIo || ebIo != oldEbIo || stepsPerClick != oldStepsPerClick || incrementPerClick != oldIncrementPerClick) { + pinManager.deallocatePin(oldEaIo); + pinManager.deallocatePin(oldEbIo); + + delete rotaryEncoder; + initRotaryEncoder(); + } + } + + DEBUG_PRINTF("[%s] Config (re)loaded\n", _name); + } + + return true; + } + + /* + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() + { + return 0x4711; + } + + //More methods can be added in the future, this example will then be extended. + //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! +}; + +byte RgbRotaryEncoderUsermod::currentPos = 5; +// strings to reduce flash memory usage (used more than twice) +const char RgbRotaryEncoderUsermod::_name[] PROGMEM = "RGB-Rotary-Encoder"; +const char RgbRotaryEncoderUsermod::_enabled[] PROGMEM = "Enabled"; +const char RgbRotaryEncoderUsermod::_ledIo[] PROGMEM = "LED-pin"; +const char RgbRotaryEncoderUsermod::_eaIo[] PROGMEM = "ea-pin"; +const char RgbRotaryEncoderUsermod::_ebIo[] PROGMEM = "eb-pin"; +const char RgbRotaryEncoderUsermod::_ledMode[] PROGMEM = "LED-Mode"; +const char RgbRotaryEncoderUsermod::_ledBrightness[] PROGMEM = "LED-Brightness"; +const char RgbRotaryEncoderUsermod::_stepsPerClick[] PROGMEM = "Steps-per-Click"; +const char RgbRotaryEncoderUsermod::_incrementPerClick[] PROGMEM = "Increment-per-Click"; \ No newline at end of file diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 5669f2f30..fb68d62e9 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -78,6 +78,10 @@ #include "../usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h" #endif +#ifdef RGB_ROTARY_ENCODER +#include "../usermods/rgb-rotary-encoder/rgb-rotary-encoder.h" +#endif + void registerUsermods() { /* @@ -151,4 +155,8 @@ void registerUsermods() #ifdef USERMOD_ROTARY_ENCODER_BRIGHTNESS_COLOR usermods.add(new RotaryEncoderBrightnessColor()); #endif + + #ifdef RGB_ROTARY_ENCODER + usermods.add(new RgbRotaryEncoderUsermod()); + #endif }