diff --git a/examples/ButtonWithRotaryAdapter/ButtonWithRotaryAdapter.ino b/examples/ButtonWithRotaryAdapter/ButtonWithRotaryAdapter.ino index 7d36926f..226cd353 100644 --- a/examples/ButtonWithRotaryAdapter/ButtonWithRotaryAdapter.ino +++ b/examples/ButtonWithRotaryAdapter/ButtonWithRotaryAdapter.ino @@ -1,4 +1,4 @@ -// Disable double press detection +// Disable SimpleRotary double press detection and use dedicated BACKSPACE button. #define DOUBLE_PRESS_THRESHOLD 0 #include diff --git a/examples/InputRotary/InputRotary.ino b/examples/InputRotary/InputRotary.ino index 43fe82d4..d4699299 100644 --- a/examples/InputRotary/InputRotary.ino +++ b/examples/InputRotary/InputRotary.ino @@ -12,6 +12,10 @@ #define LCD_ROWS 2 #define LCD_COLS 16 +// SimpleRotary samples button state every 200ms internally. +// Keep DOUBLE_PRESS_THRESHOLD >= 500 for reliable BACKSPACE detection. +// Set DOUBLE_PRESS_THRESHOLD to 0 if you want to disable double-press handling. + // Create your charset const char* charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/examples/SimpleRotary/SimpleRotary.ino b/examples/SimpleRotary/SimpleRotary.ino index 1ecb02ba..3087bccc 100644 --- a/examples/SimpleRotary/SimpleRotary.ino +++ b/examples/SimpleRotary/SimpleRotary.ino @@ -11,6 +11,9 @@ #define LCD_ROWS 2 #define LCD_COLS 16 +// For SimpleRotary double-press actions, keep DOUBLE_PRESS_THRESHOLD >= 500. +// Set DOUBLE_PRESS_THRESHOLD to 0 to disable double-press handling entirely. + // Declare the callbacks void callback(int pos); void toggleBacklight(bool isOn); diff --git a/src/input/SimpleRotaryAdapter.h b/src/input/SimpleRotaryAdapter.h index a62a9703..07dec317 100644 --- a/src/input/SimpleRotaryAdapter.h +++ b/src/input/SimpleRotaryAdapter.h @@ -15,11 +15,22 @@ * @brief Threshold for detecting a double press in milliseconds. * * This value defines the maximum time interval (in milliseconds) between two - * consecutive button presses to be considered a double press. The default value - * is 300 milliseconds. + * consecutive button presses to be considered a double press. + * + * SimpleRotary samples button state every 200ms internally, so thresholds below + * 500ms are too short for reliable double-press detection. To keep BACKSPACE + * usable out of the box, the adapter clamps positive values below that minimum. */ +#ifndef SIMPLE_ROTARY_BUTTON_DEBOUNCE_DELAY +#define SIMPLE_ROTARY_BUTTON_DEBOUNCE_DELAY 200 +#endif + +#ifndef SIMPLE_ROTARY_MIN_DOUBLE_PRESS_THRESHOLD +#define SIMPLE_ROTARY_MIN_DOUBLE_PRESS_THRESHOLD ((SIMPLE_ROTARY_BUTTON_DEBOUNCE_DELAY * 2) + 100) +#endif + #ifndef DOUBLE_PRESS_THRESHOLD -#define DOUBLE_PRESS_THRESHOLD 300 +#define DOUBLE_PRESS_THRESHOLD SIMPLE_ROTARY_MIN_DOUBLE_PRESS_THRESHOLD #endif // #include "InputInterface.h" @@ -48,6 +59,13 @@ */ class SimpleRotaryAdapter : public InputInterface { private: + static constexpr unsigned long doublePressThreshold = + DOUBLE_PRESS_THRESHOLD == 0 + ? 0 + : (DOUBLE_PRESS_THRESHOLD < SIMPLE_ROTARY_MIN_DOUBLE_PRESS_THRESHOLD + ? SIMPLE_ROTARY_MIN_DOUBLE_PRESS_THRESHOLD + : DOUBLE_PRESS_THRESHOLD); + unsigned long lastPressTime = 0; // Last time the button was pressed bool pendingEnter = false; // Flag to indicate if an enter action is pending SimpleRotary* encoder; // Pointer to the SimpleRotary instance @@ -72,7 +90,7 @@ class SimpleRotaryAdapter : public InputInterface { if (pressType == 1) { if (pendingEnter) { - if (DOUBLE_PRESS_THRESHOLD > 0 && currentTime - lastPressTime < DOUBLE_PRESS_THRESHOLD) { + if (doublePressThreshold > 0 && currentTime - lastPressTime <= doublePressThreshold) { menu->process(BACKSPACE); // Call BACKSPACE action (double press) pendingEnter = false; } @@ -87,7 +105,7 @@ class SimpleRotaryAdapter : public InputInterface { // Check if the doublePressThreshold has elapsed for pending enter action if ((!MenuItem::isEditing() && pendingEnter) || - (pendingEnter && (currentTime - lastPressTime >= DOUBLE_PRESS_THRESHOLD))) { + (pendingEnter && (doublePressThreshold == 0 || (currentTime - lastPressTime >= doublePressThreshold)))) { menu->process(ENTER); // Call ENTER action (short press) pendingEnter = false; }