From 40bf7bbb9f4536c947d3589914013b81f0979565 Mon Sep 17 00:00:00 2001 From: hank Date: Sun, 1 Jun 2025 20:15:16 -0700 Subject: [PATCH] Reverting changes to Button code --- examples/companion_radio/Button.cpp | 231 +++++++++++++--------------- examples/companion_radio/Button.h | 112 ++++++++------ 2 files changed, 169 insertions(+), 174 deletions(-) diff --git a/examples/companion_radio/Button.cpp b/examples/companion_radio/Button.cpp index 5de4b702..ec1f0f69 100644 --- a/examples/companion_radio/Button.cpp +++ b/examples/companion_radio/Button.cpp @@ -1,142 +1,125 @@ #include "Button.h" -Button::Button(uint8_t pin, bool activeState) - : _pin(pin), _activeState(activeState), _isAnalog(false), _analogThreshold(20) -{ - _currentState = false; // Initialize as not pressed - _lastState = _currentState; +Button::Button(uint8_t pin, bool activeState) + : _pin(pin), _activeState(activeState), _isAnalog(false), _analogThreshold(20) { + _currentState = false; // Initialize as not pressed + _lastState = _currentState; } Button::Button(uint8_t pin, bool activeState, bool isAnalog, uint16_t analogThreshold) - : _pin(pin), _activeState(activeState), _isAnalog(isAnalog), _analogThreshold(analogThreshold) -{ - _currentState = false; // Initialize as not pressed - _lastState = _currentState; + : _pin(pin), _activeState(activeState), _isAnalog(isAnalog), _analogThreshold(analogThreshold) { + _currentState = false; // Initialize as not pressed + _lastState = _currentState; } -void Button::begin() -{ - _currentState = readButton(); - _lastState = _currentState; +void Button::begin() { + _currentState = readButton(); + _lastState = _currentState; } -void Button::update() -{ - uint32_t now = millis(); - - // Read button at specified interval - if (now - _lastReadTime < BUTTON_READ_INTERVAL_MS) { - return; - } - _lastReadTime = now; - - bool newState = readButton(); - - // Check if state has changed - if (newState != _lastState) { - _stateChangeTime = now; - } - - // Debounce check - if ((now - _stateChangeTime) > BUTTON_DEBOUNCE_TIME_MS) { - if (newState != _currentState) { - _currentState = newState; - handleStateChange(); +void Button::update() { + uint32_t now = millis(); + + // Read button at specified interval + if (now - _lastReadTime < BUTTON_READ_INTERVAL_MS) { + return; } - } - - _lastState = newState; - - // Handle multi-click timeout - if (_state == WAITING_FOR_MULTI_CLICK && (now - _releaseTime) > BUTTON_CLICK_TIMEOUT_MS) { - // Timeout reached, process the clicks - if (_clickCount == 1) { - triggerEvent(SHORT_PRESS); + _lastReadTime = now; + + bool newState = readButton(); + + // Check if state has changed + if (newState != _lastState) { + _stateChangeTime = now; } - else if (_clickCount == 2) { - triggerEvent(DOUBLE_PRESS); + + // Debounce check + if ((now - _stateChangeTime) > BUTTON_DEBOUNCE_TIME_MS) { + if (newState != _currentState) { + _currentState = newState; + handleStateChange(); + } } - else if (_clickCount >= 3) { - triggerEvent(TRIPLE_PRESS); - } - _clickCount = 0; - _state = IDLE; - } - - // Handle long press while button is held - if (_state == PRESSED && (now - _pressTime) > BUTTON_LONG_PRESS_TIME_MS) { - triggerEvent(LONG_PRESS); - _state = IDLE; // Prevent multiple press events - _clickCount = 0; - } -} - -bool Button::readButton() -{ - if (_isAnalog) { - return (analogRead(_pin) < _analogThreshold); - } - else { - return (digitalRead(_pin) == _activeState); - } -} - -void Button::handleStateChange() -{ - uint32_t now = millis(); - - if (_currentState) { - // Button pressed - _pressTime = now; - _state = PRESSED; - triggerEvent(ANY_PRESS); - } - else { - // Button released - if (_state == PRESSED) { - uint32_t pressDuration = now - _pressTime; - - if (pressDuration < BUTTON_LONG_PRESS_TIME_MS) { - // Short press detected - _clickCount++; - _releaseTime = now; - _state = WAITING_FOR_MULTI_CLICK; - } - else { - // Long press already handled in update() - _state = IDLE; + + _lastState = newState; + + // Handle multi-click timeout + if (_state == WAITING_FOR_MULTI_CLICK && (now - _releaseTime) > BUTTON_CLICK_TIMEOUT_MS) { + // Timeout reached, process the clicks + if (_clickCount == 1) { + triggerEvent(SHORT_PRESS); + } else if (_clickCount == 2) { + triggerEvent(DOUBLE_PRESS); + } else if (_clickCount >= 3) { + triggerEvent(TRIPLE_PRESS); + } + _clickCount = 0; + _state = IDLE; + } + + // Handle long press while button is held + if (_state == PRESSED && (now - _pressTime) > BUTTON_LONG_PRESS_TIME_MS) { + triggerEvent(LONG_PRESS); + _state = IDLE; // Prevent multiple press events _clickCount = 0; - } } - } } -void Button::triggerEvent(EventType event) -{ - _lastEvent = event; +bool Button::readButton() { + if (_isAnalog) { + return (analogRead(_pin) < _analogThreshold); + } else { + return (digitalRead(_pin) == _activeState); + } +} - switch (event) { - case ANY_PRESS: - if (_onAnyPress) - _onAnyPress(); - break; - case SHORT_PRESS: - if (_onShortPress) - _onShortPress(); - break; - case DOUBLE_PRESS: - if (_onDoublePress) - _onDoublePress(); - break; - case TRIPLE_PRESS: - if (_onTriplePress) - _onTriplePress(); - break; - case LONG_PRESS: - if (_onLongPress) - _onLongPress(); - break; - default: - break; - } +void Button::handleStateChange() { + uint32_t now = millis(); + + if (_currentState) { + // Button pressed + _pressTime = now; + _state = PRESSED; + triggerEvent(ANY_PRESS); + } else { + // Button released + if (_state == PRESSED) { + uint32_t pressDuration = now - _pressTime; + + if (pressDuration < BUTTON_LONG_PRESS_TIME_MS) { + // Short press detected + _clickCount++; + _releaseTime = now; + _state = WAITING_FOR_MULTI_CLICK; + } else { + // Long press already handled in update() + _state = IDLE; + _clickCount = 0; + } + } + } +} + +void Button::triggerEvent(EventType event) { + _lastEvent = event; + + switch (event) { + case ANY_PRESS: + if (_onAnyPress) _onAnyPress(); + break; + case SHORT_PRESS: + if (_onShortPress) _onShortPress(); + break; + case DOUBLE_PRESS: + if (_onDoublePress) _onDoublePress(); + break; + case TRIPLE_PRESS: + if (_onTriplePress) _onTriplePress(); + break; + case LONG_PRESS: + if (_onLongPress) _onLongPress(); + break; + default: + break; + } } \ No newline at end of file diff --git a/examples/companion_radio/Button.h b/examples/companion_radio/Button.h index 85564593..47c792bd 100644 --- a/examples/companion_radio/Button.h +++ b/examples/companion_radio/Button.h @@ -4,62 +4,74 @@ #include // Button timing configuration -#define BUTTON_DEBOUNCE_TIME_MS 50 // Debounce time in ms -#define BUTTON_CLICK_TIMEOUT_MS 500 // Max time between clicks for multi-click -#define BUTTON_LONG_PRESS_TIME_MS 3000 // Time to trigger long press (3 seconds) -#define BUTTON_READ_INTERVAL_MS 10 // How often to read the button +#define BUTTON_DEBOUNCE_TIME_MS 50 // Debounce time in ms +#define BUTTON_CLICK_TIMEOUT_MS 500 // Max time between clicks for multi-click +#define BUTTON_LONG_PRESS_TIME_MS 3000 // Time to trigger long press (3 seconds) +#define BUTTON_READ_INTERVAL_MS 10 // How often to read the button class Button { public: - enum EventType { NONE, SHORT_PRESS, DOUBLE_PRESS, TRIPLE_PRESS, LONG_PRESS, ANY_PRESS }; + enum EventType { + NONE, + SHORT_PRESS, + DOUBLE_PRESS, + TRIPLE_PRESS, + LONG_PRESS, + ANY_PRESS + }; - using EventCallback = std::function; + using EventCallback = std::function; - Button(uint8_t pin, bool activeState = LOW); - Button(uint8_t pin, bool activeState, bool isAnalog, uint16_t analogThreshold = 20); - - void begin(); - void update(); - - // Set callbacks for different events - void onShortPress(EventCallback callback) { _onShortPress = callback; } - void onDoublePress(EventCallback callback) { _onDoublePress = callback; } - void onTriplePress(EventCallback callback) { _onTriplePress = callback; } - void onLongPress(EventCallback callback) { _onLongPress = callback; } - void onAnyPress(EventCallback callback) { _onAnyPress = callback; } - - // State getters - bool isPressed() const { return _currentState; } - EventType getLastEvent() const { return _lastEvent; } + Button(uint8_t pin, bool activeState = LOW); + Button(uint8_t pin, bool activeState, bool isAnalog, uint16_t analogThreshold = 20); + + void begin(); + void update(); + + // Set callbacks for different events + void onShortPress(EventCallback callback) { _onShortPress = callback; } + void onDoublePress(EventCallback callback) { _onDoublePress = callback; } + void onTriplePress(EventCallback callback) { _onTriplePress = callback; } + void onLongPress(EventCallback callback) { _onLongPress = callback; } + void onAnyPress(EventCallback callback) { _onAnyPress = callback; } + + // State getters + bool isPressed() const { return _currentState; } + EventType getLastEvent() const { return _lastEvent; } private: - enum State { IDLE, PRESSED, RELEASED, WAITING_FOR_MULTI_CLICK }; + enum State { + IDLE, + PRESSED, + RELEASED, + WAITING_FOR_MULTI_CLICK + }; - uint8_t _pin; - bool _activeState; - bool _isAnalog; - uint16_t _analogThreshold; - - State _state = IDLE; - bool _currentState; - bool _lastState; - - uint32_t _stateChangeTime = 0; - uint32_t _pressTime = 0; - uint32_t _releaseTime = 0; - uint32_t _lastReadTime = 0; - - uint8_t _clickCount = 0; - EventType _lastEvent = NONE; - - // Callbacks - EventCallback _onShortPress = nullptr; - EventCallback _onDoublePress = nullptr; - EventCallback _onTriplePress = nullptr; - EventCallback _onLongPress = nullptr; - EventCallback _onAnyPress = nullptr; - - bool readButton(); - void handleStateChange(); - void triggerEvent(EventType event); + uint8_t _pin; + bool _activeState; + bool _isAnalog; + uint16_t _analogThreshold; + + State _state = IDLE; + bool _currentState; + bool _lastState; + + uint32_t _stateChangeTime = 0; + uint32_t _pressTime = 0; + uint32_t _releaseTime = 0; + uint32_t _lastReadTime = 0; + + uint8_t _clickCount = 0; + EventType _lastEvent = NONE; + + // Callbacks + EventCallback _onShortPress = nullptr; + EventCallback _onDoublePress = nullptr; + EventCallback _onTriplePress = nullptr; + EventCallback _onLongPress = nullptr; + EventCallback _onAnyPress = nullptr; + + bool readButton(); + void handleStateChange(); + void triggerEvent(EventType event); }; \ No newline at end of file