From 88ceba59cfe40d3d1b010b9e89001c0bc7ddccbf Mon Sep 17 00:00:00 2001 From: Scott Bailey Date: Thu, 2 Sep 2021 22:56:49 -0700 Subject: [PATCH 1/7] Fix error 12 issues --- wled00/ir.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 30dae3db..63b5410f 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -71,9 +71,11 @@ 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) { + byte prevError = errorFlag; if (!applyPreset(presetID, CALL_MODE_BUTTON)) { effectCurrent = effectID; effectPalette = paletteID; + errorFlag = prevError; //clear error 12 from non-existent preset } } @@ -566,16 +568,17 @@ void decodeIRJson(uint32_t code) char objKey[10]; const char* cmd; String cmdStr; + byte irError; DynamicJsonDocument irDoc(JSON_BUFFER_SIZE); JsonObject fdo; JsonObject jsonCmdObj; sprintf(objKey, "\"0x%X\":", code); - errorFlag = readObjectFromFile("/ir.json", objKey, &irDoc) ? ERR_NONE : ERR_FS_PLOAD; + irError = readObjectFromFile("/ir.json", objKey, &irDoc) ? ERR_NONE : ERR_FS_PLOAD; fdo = irDoc.as(); lastValidCode = 0; - if (!errorFlag) + if (!irError) { cmd = fdo["cmd"]; cmdStr = String(cmd); From a839809eb8b706ac6415175c79534b7705fe5036 Mon Sep 17 00:00:00 2001 From: Scott Bailey Date: Fri, 3 Sep 2021 00:14:07 -0700 Subject: [PATCH 2/7] change random mode choice on presetFallback --- wled00/ir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 63b5410f..b1812caa 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -595,7 +595,7 @@ void decodeIRJson(uint32_t code) decBrightness(); } else if (cmdStr.startsWith(F("!presetF"))) { //!presetFallback uint8_t p1 = fdo["PL"] ? fdo["PL"] : 1; - uint8_t p2 = fdo["FX"] ? fdo["FX"] : random8(100); + uint8_t p2 = fdo["FX"] ? fdo["FX"] : random8(MODE_COUNT); uint8_t p3 = fdo["FP"] ? fdo["FP"] : 0; presetFallback(p1, p2, p3); } From e80594d61da173e9f1493e573c15531462765a3a Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Tue, 7 Sep 2021 17:03:46 +0200 Subject: [PATCH 3/7] Bugfix (sclPin, sdaPin). Removed unnecessary static_cast. --- .../usermod_v2_four_line_display.h | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h b/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h index b7a88eb4..2089db93 100644 --- a/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h +++ b/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h @@ -168,7 +168,6 @@ class FourLineDisplayUsermod : public Usermod { // network here void setup() { if (type == NONE) return; - byte i; if (type == SSD1306_SPI || type == SSD1306_SPI64) { PinManagerPinType pins[5] = { { ioPin[0], true }, { ioPin[1], true}, { ioPin[2], true }, { ioPin[3], true}, { ioPin[4], true }}; if (!pinManager.allocateMultiplePins(pins, 5, PinOwner::UM_FourLineDisplay)) { type=NONE; return; } @@ -242,17 +241,14 @@ class FourLineDisplayUsermod : public Usermod { } if (nullptr == u8x8) { DEBUG_PRINTLN(F("Display init failed.")); - pinManager.deallocatePin(sclPin, PinOwner::UM_FourLineDisplay); - pinManager.deallocatePin(sdaPin, PinOwner::UM_FourLineDisplay); - sclPin = -1; - sdaPin = -1; + for (byte i=0; i<5 && ioPin[i]>=0; i++) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay); type = NONE; return; } initDone = true; DEBUG_PRINTLN(F("Starting display.")); - (static_cast(u8x8))->begin(); // why a static cast here? variable is of this type... + u8x8->begin(); setFlipMode(flip); setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255 setPowerSave(0); @@ -278,40 +274,40 @@ class FourLineDisplayUsermod : public Usermod { */ void setFlipMode(uint8_t mode) { if (type==NONE) return; - (static_cast(u8x8))->setFlipMode(mode); + u8x8->setFlipMode(mode); } void setContrast(uint8_t contrast) { if (type==NONE) return; - (static_cast(u8x8))->setContrast(contrast); + u8x8->setContrast(contrast); } void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false) { if (type==NONE) return; - (static_cast(u8x8))->setFont(u8x8_font_chroma48medium8_r); - if (!ignoreLH && lineHeight==2) (static_cast(u8x8))->draw1x2String(col, row, string); - else (static_cast(u8x8))->drawString(col, row, string); + u8x8->setFont(u8x8_font_chroma48medium8_r); + if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string); + else u8x8->drawString(col, row, string); } void draw2x2String(uint8_t col, uint8_t row, const char *string) { if (type==NONE) return; - (static_cast(u8x8))->setFont(u8x8_font_chroma48medium8_r); - (static_cast(u8x8))->draw2x2String(col, row, string); + u8x8->setFont(u8x8_font_chroma48medium8_r); + u8x8->draw2x2String(col, row, string); } void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false) { if (type==NONE) return; - (static_cast(u8x8))->setFont(font); - if (!ignoreLH && lineHeight==2) (static_cast(u8x8))->draw1x2Glyph(col, row, glyph); - else (static_cast(u8x8))->drawGlyph(col, row, glyph); + u8x8->setFont(font); + if (!ignoreLH && lineHeight==2) u8x8->draw1x2Glyph(col, row, glyph); + else u8x8->drawGlyph(col, row, glyph); } uint8_t getCols() { if (type==NONE) return 0; - return (static_cast(u8x8))->getCols(); + return u8x8->getCols(); } void clear() { if (type==NONE) return; - (static_cast(u8x8))->clear(); + u8x8->clear(); } void setPowerSave(uint8_t save) { if (type==NONE) return; - (static_cast(u8x8))->setPowerSave(save); + u8x8->setPowerSave(save); } void center(String &line, uint8_t width) { @@ -726,7 +722,7 @@ class FourLineDisplayUsermod : public Usermod { bool pinsChanged = false; for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; } if (pinsChanged || type!=newType) { - if (type != NONE) delete (static_cast(u8x8)); + if (type != NONE) delete u8x8; for (byte i=0; i<5; i++) { if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay); ioPin[i] = newPin[i]; @@ -736,9 +732,7 @@ class FourLineDisplayUsermod : public Usermod { return true; } else type = newType; setup(); - if (sclPin >= 0 && sdaPin >= 0) { - needsRedraw |= true; - } + needsRedraw |= true; } setContrast(contrast); setFlipMode(flip); From f1e2439e669ba064de221f84fc25a2bbb11f5e6a Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 9 Sep 2021 12:05:02 +0200 Subject: [PATCH 4/7] Slight IR JSON simplefication Check for missing file No duplicate cmd object --- wled00/const.h | 1 + wled00/ir.cpp | 92 ++++++++++++++++++++++++++------------------------ 2 files changed, 48 insertions(+), 45 deletions(-) diff --git a/wled00/const.h b/wled00/const.h index b8b54dc5..e5061627 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -215,6 +215,7 @@ #define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?) #define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached #define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist +#define ERR_FS_IRLOAD 13 // It was attempted to load an IR JSON cmd, but the "ir.json" file does not exist #define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured #define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented) #define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented) diff --git a/wled00/ir.cpp b/wled00/ir.cpp index b1812caa..ba22421d 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -568,60 +568,62 @@ void decodeIRJson(uint32_t code) char objKey[10]; const char* cmd; String cmdStr; - byte irError; DynamicJsonDocument irDoc(JSON_BUFFER_SIZE); JsonObject fdo; JsonObject jsonCmdObj; sprintf(objKey, "\"0x%X\":", code); - irError = readObjectFromFile("/ir.json", objKey, &irDoc) ? ERR_NONE : ERR_FS_PLOAD; + readObjectFromFile("/ir.json", objKey, &irDoc); fdo = irDoc.as(); lastValidCode = 0; - if (!irError) + if (fdo.isNull()) { + //the received code does not exist + if (!WLED_FS.exists("/ir.json")) errorFlag = ERR_FS_IRLOAD; //warn if IR file itself doesn't exist + return; + } + + jsonCmdObj = fdo["cmd"]; + cmdStr = String(jsonCmdObj); + + if (!cmdStr.isEmpty()) { - cmd = fdo["cmd"]; - cmdStr = String(cmd); - jsonCmdObj = fdo["cmd"]; - if (!cmdStr.isEmpty()) - { - if (cmdStr.startsWith("!")) { - // call limited set of C functions - if (cmdStr.startsWith(F("!incBri"))) { - lastValidCode = code; - incBrightness(); - } else if (cmdStr.startsWith(F("!decBri"))) { - lastValidCode = code; - decBrightness(); - } else if (cmdStr.startsWith(F("!presetF"))) { //!presetFallback - uint8_t p1 = fdo["PL"] ? fdo["PL"] : 1; - uint8_t p2 = fdo["FX"] ? fdo["FX"] : random8(MODE_COUNT); - uint8_t p3 = fdo["FP"] ? fdo["FP"] : 0; - presetFallback(p1, p2, p3); - } - } else { - // HTTP API command - if (cmdStr.indexOf("~") || fdo["rpt"]) - { - // repeatable action - lastValidCode = code; - } - if (effectCurrent == 0 && cmdStr.indexOf("FP=") > -1) { - // setting palette but it wont show because effect is solid - effectCurrent = FX_MODE_GRADIENT; - } - if (!cmdStr.startsWith("win&")) { - cmdStr = "win&" + cmdStr; - } - handleSet(nullptr, cmdStr, false); - } - } else if (!jsonCmdObj.isNull()) { - // 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, CALL_MODE_BUTTON); - fileDoc = nullptr; - } + if (cmdStr.startsWith("!")) { + // call limited set of C functions + if (cmdStr.startsWith(F("!incBri"))) { + lastValidCode = code; + incBrightness(); + } else if (cmdStr.startsWith(F("!decBri"))) { + lastValidCode = code; + decBrightness(); + } else if (cmdStr.startsWith(F("!presetF"))) { //!presetFallback + uint8_t p1 = fdo["PL"] ? fdo["PL"] : 1; + uint8_t p2 = fdo["FX"] ? fdo["FX"] : random8(MODE_COUNT); + uint8_t p3 = fdo["FP"] ? fdo["FP"] : 0; + presetFallback(p1, p2, p3); + } + } else { + // HTTP API command + if (cmdStr.indexOf("~") || fdo["rpt"]) + { + // repeatable action + lastValidCode = code; + } + if (effectCurrent == 0 && cmdStr.indexOf("FP=") > -1) { + // setting palette but it wont show because effect is solid + effectCurrent = FX_MODE_GRADIENT; + } + if (!cmdStr.startsWith("win&")) { + cmdStr = "win&" + cmdStr; + } + handleSet(nullptr, cmdStr, false); + } + } else if (!jsonCmdObj.isNull()) { + // 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, CALL_MODE_BUTTON); + fileDoc = nullptr; } } From 6a01658355e45e3a57825c196322c41f9c58136e Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 9 Sep 2021 17:50:59 +0200 Subject: [PATCH 5/7] Use pbolduc fork of AsyncTCP (fixing flicker with upstream AsyncTCP v1.1.1) --- platformio.ini | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index c1011be4..b969322a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -205,11 +205,12 @@ lib_deps = build_flags = -g -DARDUINO_ARCH_ESP32 -DCONFIG_LITTLEFS_FOR_IDF_3_2 + -D CONFIG_ASYNC_TCP_USE_WDT=0 lib_deps = ${env.lib_deps} makuna/NeoPixelBus @ 2.6.7 - AsyncTCP @ 1.0.3 + https://github.com/pbolduc/AsyncTCP.git [esp32s2] build_flags = -g @@ -217,11 +218,13 @@ build_flags = -g -DCONFIG_LITTLEFS_FOR_IDF_3_2 -DARDUINO_ARCH_ESP32S2 -DCONFIG_IDF_TARGET_ESP32S2 + -D CONFIG_ASYNC_TCP_USE_WDT=0 + -DCO lib_deps = ${env.lib_deps} makuna/NeoPixelBus @ 2.6.7 - AsyncTCP @ 1.0.3 + https://github.com/pbolduc/AsyncTCP.git # ------------------------------------------------------------------------------ # WLED BUILDS From c24ab1b21d42d7e9e95b2173dc89d96ee2181f1c Mon Sep 17 00:00:00 2001 From: Christian Schwinne Date: Sat, 11 Sep 2021 01:17:42 +0200 Subject: [PATCH 6/7] Auto create segments setting (#2183) --- CHANGELOG.md | 7 +++++ platformio.ini | 4 +-- wled00/FX_fcn.cpp | 49 +++++++++++++++++++++++++---------- wled00/cfg.cpp | 2 ++ wled00/data/settings_leds.htm | 4 ++- wled00/html_settings.h | 3 ++- wled00/hue.cpp | 2 +- wled00/mqtt.cpp | 18 ++++++------- wled00/set.cpp | 4 ++- wled00/wled.h | 7 ++++- wled00/xml.cpp | 1 + 11 files changed, 71 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 219549ad..19bf7186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ### Builds after release 0.12.0 +#### Build 2109100 + +- Added an auto create segments per bus setting +- Added 15 new palettes from SR branch (PR #2134) +- Fixed segment runtime not reset on FX change via HTTP API +- Changed AsyncTCP dependency to pbolduc fork v1.2.0 + #### Build 2108250 - Added Sync groups (PR #2150) diff --git a/platformio.ini b/platformio.ini index b969322a..6ca479ff 100644 --- a/platformio.ini +++ b/platformio.ini @@ -210,7 +210,7 @@ build_flags = -g lib_deps = ${env.lib_deps} makuna/NeoPixelBus @ 2.6.7 - https://github.com/pbolduc/AsyncTCP.git + https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 [esp32s2] build_flags = -g @@ -224,7 +224,7 @@ build_flags = -g lib_deps = ${env.lib_deps} makuna/NeoPixelBus @ 2.6.7 - https://github.com/pbolduc/AsyncTCP.git + https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 # ------------------------------------------------------------------------------ # WLED BUILDS diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 4113ab72..43cb4846 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -98,24 +98,25 @@ void WS2812FX::finalizeInit(uint16_t countPixels) setBrightness(_brightness); //TODO make sure segments are only refreshed when bus config actually changed (new settings page) - //make one segment per bus uint8_t s = 0; for (uint8_t i = 0; i < busses.getNumBusses(); i++) { Bus* b = busses.getBus(i); - segStarts[s] = b->getStart(); - segStops[s] = segStarts[s] + b->getLength(); + if (autoSegments) { //make one segment per bus + segStarts[s] = b->getStart(); + segStops[s] = segStarts[s] + b->getLength(); - //check for overlap with previous segments - for (uint8_t j = 0; j < s; j++) { - if (segStops[j] > segStarts[s] && segStarts[j] < segStops[s]) { - //segments overlap, merge - segStarts[j] = min(segStarts[s],segStarts[j]); - segStops [j] = max(segStops [s],segStops [j]); segStops[s] = 0; - s--; + //check for overlap with previous segments + for (uint8_t j = 0; j < s; j++) { + if (segStops[j] > segStarts[s] && segStarts[j] < segStops[s]) { + //segments overlap, merge + segStarts[j] = min(segStarts[s],segStarts[j]); + segStops [j] = max(segStops [s],segStops [j]); segStops[s] = 0; + s--; + } } + s++; } - s++; #ifdef ESP8266 if ((!IS_DIGITAL(b->getType()) || IS_2PIN(b->getType()))) continue; @@ -126,9 +127,29 @@ void WS2812FX::finalizeInit(uint16_t countPixels) #endif } - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - _segments[i].start = segStarts[i]; - _segments[i].stop = segStops [i]; + if (autoSegments) { + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { + _segments[i].start = segStarts[i]; + _segments[i].stop = segStops [i]; + } + } else { + //expand the main seg to the entire length, but only if there are no other segments + uint8_t mainSeg = getMainSegmentId(); + bool isMultipleSegs = false; + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) + { + if (i != mainSeg && _segments[i].isActive()) isMultipleSegs = true; + } + if (!isMultipleSegs) { + _segments[mainSeg].start = 0; _segments[mainSeg].stop = _length; + } else { + //there are multiple segments, leave them, but prune length to total + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) + { + if (_segments[i].start > _length) _segments[i].stop = 0; + if (_segments[i].stop > _length) _segments[i].stop = _length; + } + } } } diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index b345a873..18048649 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -202,6 +202,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { JsonObject light = doc[F("light")]; CJSON(briMultiplier, light[F("scale-bri")]); CJSON(strip.paletteBlend, light[F("pal-mode")]); + CJSON(autoSegments, light[F("aseg")]); float light_gc_bri = light["gc"]["bri"]; float light_gc_col = light["gc"]["col"]; // 2.8 @@ -565,6 +566,7 @@ void serializeConfig() { JsonObject light = doc.createNestedObject(F("light")); light[F("scale-bri")] = briMultiplier; light[F("pal-mode")] = strip.paletteBlend; + light[F("aseg")] = autoSegments; JsonObject light_gc = light.createNestedObject("gc"); light_gc["bri"] = (strip.gammaCorrectBri) ? 2.8 : 1.0; diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 2dfb6ab2..ae6a37f5 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -369,7 +369,9 @@ Reverse (rotated 180°):
+ + Make a segment for each output:
+
Touch threshold:
IR pin:  

Touch threshold:
IR pin: