From 1dbea434a337025227beb2150a7f99965f96b7d8 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 20 Jun 2022 16:04:43 +0200 Subject: [PATCH 1/5] fix for issue #2587 --- wled00/button.cpp | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index 60fccfc3..93f75369 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -131,21 +131,41 @@ void handleSwitch(uint8_t b) } } +#define ANALOG_BTN_READ_CYCLE 250 // min time between two analog reading cycles +#define STRIP_WAIT_TIME 6 // max wait time in case of strip.isUpdating() +#define POT_SMOOTHING 0.25 // smoothing factor for raw potentiometer readings +#define POT_SENSITIVITY 4 // changes below this amount are noise (POT scratching, or ADC noise) + void handleAnalog(uint8_t b) { - static uint8_t oldRead[WLED_MAX_BUTTONS]; + static uint8_t oldRead[WLED_MAX_BUTTONS] = {0}; + static float filteredReading[WLED_MAX_BUTTONS] = {0.0}; + uint16_t rawReading; // raw value from analogRead, scaled to 12bit + #ifdef ESP8266 - uint16_t aRead = analogRead(A0) >> 2; // convert 10bit read to 8bit + rawReading = analogRead(A0) << 2; // convert 10bit read to 12bit #else - uint16_t aRead = analogRead(btnPin[b]) >> 4; // convert 12bit read to 8bit + rawReading = analogRead(btnPin[b]); // collect at full 12bit resolution #endif + yield(); // keep WiFi task running - analog read may take several millis on ESP8266 + + filteredReading[b] += POT_SMOOTHING * ((float(rawReading) / 16.0) - filteredReading[b]); // filter raw input, and scale to [0..255] + uint16_t aRead = max(min(int(filteredReading[b]), 255), 0); // squash into 8bit + if(aRead <= POT_SENSITIVITY) aRead = 0; // make sure that 0 and 255 are used + if(aRead >= 255-POT_SENSITIVITY) aRead = 255; if (buttonType[b] == BTN_TYPE_ANALOG_INVERTED) aRead = 255 - aRead; // remove noise & reduce frequency of UI updates - aRead &= 0xFC; + if (abs(int(aRead) - int(oldRead[b])) <= POT_SENSITIVITY) return; // no significant change in reading + + // wait until strip finishes updating + unsigned long wait_started = millis(); + while(strip.isUpdating() && (millis() - wait_started < STRIP_WAIT_TIME)) { + delay(1); + } + if (strip.isUpdating()) return; // give up - if (oldRead[b] == aRead) return; // no change in reading oldRead[b] = aRead; // if no macro for "short press" and "long press" is defined use brightness control @@ -168,6 +188,7 @@ void handleAnalog(uint8_t b) } else if (macroDoublePress[b] == 247) { // selected palette effectPalette = map(aRead, 0, 252, 0, strip.getPaletteCount()-1); + effectPalette = constrain(effectPalette, 0, strip.getPaletteCount()-1); // map is allowed to "overshoot", so we need to contrain the result } else if (macroDoublePress[b] == 200) { // primary color, hue, full saturation colorHStoRGB(aRead*256,255,col); @@ -196,6 +217,8 @@ void handleButton() static unsigned long lastRead = 0UL; bool analog = false; + if (strip.isUpdating()) return; // don't interfere with strip updates. Our button will still be there in 1ms (next cycle) + for (uint8_t b=0; b 250) { // button is not a button but a potentiometer + if ((buttonType[b] == BTN_TYPE_ANALOG || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) && millis() - lastRead > ANALOG_BTN_READ_CYCLE) { // button is not a button but a potentiometer analog = true; handleAnalog(b); continue; } From 169a46c38c194479bbb3fbce5d24788a7ac0049b Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 20 Jun 2022 21:56:16 +0200 Subject: [PATCH 2/5] button.cpp: marked literal constant as "float! --- wled00/button.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index 93f75369..a5a4718a 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -139,7 +139,7 @@ void handleSwitch(uint8_t b) void handleAnalog(uint8_t b) { static uint8_t oldRead[WLED_MAX_BUTTONS] = {0}; - static float filteredReading[WLED_MAX_BUTTONS] = {0.0}; + static float filteredReading[WLED_MAX_BUTTONS] = {0.0f}; uint16_t rawReading; // raw value from analogRead, scaled to 12bit #ifdef ESP8266 From ed374684a6a4c655627da873df5e56e6f6509e2a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 20 Jun 2022 22:00:23 +0200 Subject: [PATCH 3/5] Update button.cpp overlooked one --- wled00/button.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index a5a4718a..937dddf0 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -133,7 +133,7 @@ void handleSwitch(uint8_t b) #define ANALOG_BTN_READ_CYCLE 250 // min time between two analog reading cycles #define STRIP_WAIT_TIME 6 // max wait time in case of strip.isUpdating() -#define POT_SMOOTHING 0.25 // smoothing factor for raw potentiometer readings +#define POT_SMOOTHING 0.25f // smoothing factor for raw potentiometer readings #define POT_SENSITIVITY 4 // changes below this amount are noise (POT scratching, or ADC noise) void handleAnalog(uint8_t b) From 860e74bffa963a05e6d1693b2789cc93a63eb0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Wed, 22 Jun 2022 09:58:21 +0200 Subject: [PATCH 4/5] Comment & float constant. --- wled00/button.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index 937dddf0..2f01fdab 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -138,7 +138,7 @@ void handleSwitch(uint8_t b) void handleAnalog(uint8_t b) { - static uint8_t oldRead[WLED_MAX_BUTTONS] = {0}; + static uint8_t oldRead[WLED_MAX_BUTTONS] = {0}; static float filteredReading[WLED_MAX_BUTTONS] = {0.0f}; uint16_t rawReading; // raw value from analogRead, scaled to 12bit @@ -149,7 +149,7 @@ void handleAnalog(uint8_t b) #endif yield(); // keep WiFi task running - analog read may take several millis on ESP8266 - filteredReading[b] += POT_SMOOTHING * ((float(rawReading) / 16.0) - filteredReading[b]); // filter raw input, and scale to [0..255] + filteredReading[b] += POT_SMOOTHING * ((float(rawReading) / 16.0f) - filteredReading[b]); // filter raw input, and scale to [0..255] uint16_t aRead = max(min(int(filteredReading[b]), 255), 0); // squash into 8bit if(aRead <= POT_SENSITIVITY) aRead = 0; // make sure that 0 and 255 are used if(aRead >= 255-POT_SENSITIVITY) aRead = 255; @@ -159,7 +159,7 @@ void handleAnalog(uint8_t b) // remove noise & reduce frequency of UI updates if (abs(int(aRead) - int(oldRead[b])) <= POT_SENSITIVITY) return; // no significant change in reading - // wait until strip finishes updating + // wait until strip finishes updating (why: strip was not updating at the start of handleButton() but may have started during analogRead()?) unsigned long wait_started = millis(); while(strip.isUpdating() && (millis() - wait_started < STRIP_WAIT_TIME)) { delay(1); From c79eb43347cade815656146af9c5c5b9504e93a2 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 22 Jun 2022 12:36:47 +0200 Subject: [PATCH 5/5] disabled second check for strip.isUpdating() commented out the second `strip.isUpdating()` check, because it should not be neccesary; Strip.service() is called after handleIO()/handleButton(). --- wled00/button.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index 2f01fdab..2c433a34 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -159,12 +159,13 @@ void handleAnalog(uint8_t b) // remove noise & reduce frequency of UI updates if (abs(int(aRead) - int(oldRead[b])) <= POT_SENSITIVITY) return; // no significant change in reading - // wait until strip finishes updating (why: strip was not updating at the start of handleButton() but may have started during analogRead()?) - unsigned long wait_started = millis(); - while(strip.isUpdating() && (millis() - wait_started < STRIP_WAIT_TIME)) { - delay(1); - } - if (strip.isUpdating()) return; // give up + // Unomment the next lines if you still see flickering related to potentiometer + // This waits until strip finishes updating (why: strip was not updating at the start of handleButton() but may have started during analogRead()?) + //unsigned long wait_started = millis(); + //while(strip.isUpdating() && (millis() - wait_started < STRIP_WAIT_TIME)) { + // delay(1); + //} + //if (strip.isUpdating()) return; // give up oldRead[b] = aRead;