From af88c68fca9ee88a2ad045cee6c468ba0088bcbe Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 2 Jun 2023 10:51:16 +0200 Subject: [PATCH] Buttons: Trigger on button press (instead of release) if all configured presets are the same (#3226) * Buttons: Trigger when pressing if all configured presets are the same * Add debounce for immediate rising-edge short press --------- Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com> --- wled00/button.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index d51040a8..d45274a6 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -227,9 +227,8 @@ void handleButton() static unsigned long lastRun = 0UL; unsigned long now = millis(); - //if (strip.isUpdating()) return; // don't interfere with strip updates. Our button will still be there in 1ms (next cycle) - if (strip.isUpdating() && (millis() - lastRun < 400)) return; // be niced, but avoid button starvation - lastRun = millis(); + if (strip.isUpdating() && (now - lastRun < 400)) return; // don't interfere with strip update (unless strip is updating continuously, e.g. very long strips) + lastRun = now; for (uint8_t b=0; b ANALOG_BTN_READ_CYCLE) { handleAnalog(b); lastRead = now; @@ -248,14 +247,23 @@ void handleButton() continue; } - //button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NOT gpio0) + // button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NOT gpio0) if (buttonType[b] == BTN_TYPE_SWITCH || buttonType[b] == BTN_TYPE_PIR_SENSOR) { handleSwitch(b); continue; } - //momentary button logic - if (isButtonPressed(b)) { //pressed + // momentary button logic + if (isButtonPressed(b)) { // pressed + + // if all macros are the same, fire action immediately on rising edge + if (macroButton[b] && macroButton[b] == macroLongPress[b] && macroButton[b] == macroDoublePress[b]) { + if (!buttonPressedBefore[b]) + shortPressAction(b); + buttonPressedBefore[b] = true; + buttonPressedTime[b] = now; // continually update (for debouncing to work in release handler) + return; + } if (!buttonPressedBefore[b]) buttonPressedTime[b] = now; buttonPressedBefore[b] = true; @@ -270,9 +278,15 @@ void handleButton() } } else if (!isButtonPressed(b) && buttonPressedBefore[b]) { //released - long dur = now - buttonPressedTime[b]; - if (dur < WLED_DEBOUNCE_THRESHOLD) {buttonPressedBefore[b] = false; continue;} //too short "press", debounce + + // released after rising-edge short press action + if (macroButton[b] && macroButton[b] == macroLongPress[b] && macroButton[b] == macroDoublePress[b]) { + if (dur > WLED_DEBOUNCE_THRESHOLD) buttonPressedBefore[b] = false; // debounce, blocks button for 50 ms once it has been released + return; + } + + if (dur < WLED_DEBOUNCE_THRESHOLD) {buttonPressedBefore[b] = false; continue;} // too short "press", debounce bool doublePress = buttonWaitTime[b]; //did we have a short press before? buttonWaitTime[b] = 0;