* MomentaryButton: added support for analog button (with threshold)

* RAK: support for PIN_USER_BTN_ANA
This commit is contained in:
Scott Powell 2025-09-01 17:11:55 +10:00
parent b8223e9d07
commit 74722c24b8
5 changed files with 39 additions and 3 deletions

View file

@ -354,6 +354,9 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
#if defined(PIN_USER_BTN)
user_btn.begin();
#endif
#if defined(PIN_USER_BTN_ANA)
analog_btn.begin();
#endif
_node_prefs = node_prefs;
if (_display != NULL) {
@ -508,6 +511,14 @@ void UITask::loop() {
c = handleLongPress(KEY_RIGHT);
}
#endif
#if defined(PIN_USER_BTN_ANA)
ev = analog_btn.check();
if (ev == BUTTON_EVENT_CLICK) {
c = checkDisplayOn(KEY_SELECT);
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
c = handleLongPress(KEY_ENTER);
}
#endif
if (c != 0 && curr) {
curr->handleInput(c);

View file

@ -8,16 +8,29 @@ MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, bool reverse
prev = _reverse ? HIGH : LOW;
cancel = 0;
_long_millis = long_press_millis;
_threshold = 0;
}
MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, int analog_threshold) {
_pin = pin;
_reverse = false;
_pull = false;
down_at = 0;
prev = LOW;
cancel = 0;
_long_millis = long_press_millis;
_threshold = analog_threshold;
}
void MomentaryButton::begin() {
if (_pin >= 0) {
if (_pin >= 0 && _threshold == 0) {
pinMode(_pin, _pull ? (_reverse ? INPUT_PULLUP : INPUT_PULLDOWN) : INPUT);
}
}
bool MomentaryButton::isPressed() const {
return isPressed(digitalRead(_pin));
int btn = _threshold > 0 ? (analogRead(_pin) < _threshold) : digitalRead(_pin);
return isPressed(btn);
}
void MomentaryButton::cancelClick() {
@ -25,6 +38,9 @@ void MomentaryButton::cancelClick() {
}
bool MomentaryButton::isPressed(int level) const {
if (_threshold > 0) {
return level;
}
if (_reverse) {
return level == LOW;
} else {
@ -36,7 +52,7 @@ int MomentaryButton::check(bool repeat_click) {
if (_pin < 0) return BUTTON_EVENT_NONE;
int event = BUTTON_EVENT_NONE;
int btn = digitalRead(_pin);
int btn = _threshold > 0 ? (analogRead(_pin) < _threshold) : digitalRead(_pin);
if (btn != prev) {
if (isPressed(btn)) {
down_at = millis();

View file

@ -11,12 +11,14 @@ class MomentaryButton {
int8_t prev, cancel;
bool _reverse, _pull;
int _long_millis;
int _threshold; // analog mode
unsigned long down_at;
bool isPressed(int level) const;
public:
MomentaryButton(int8_t pin, int long_press_mills=0, bool reverse=false, bool pulldownup=false);
MomentaryButton(int8_t pin, int long_press_mills, int analog_threshold);
void begin();
int check(bool repeat_click=false); // returns one of BUTTON_EVENT_*
void cancelClick(); // suppress next BUTTON_EVENT_CLICK (if already in DOWN state)

View file

@ -11,6 +11,10 @@ RAK4631Board board;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
#if defined(PIN_USER_BTN_ANA)
MomentaryButton analog_btn(PIN_USER_BTN_ANA, 1000, 20);
#endif
#endif
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);

View file

@ -13,6 +13,9 @@
extern DISPLAY_CLASS display;
#include <helpers/ui/MomentaryButton.h>
extern MomentaryButton user_btn;
#if defined(PIN_USER_BTN_ANA)
extern MomentaryButton analog_btn;
#endif
#endif
extern RAK4631Board board;