mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-06 11:39:32 +00:00
Add longPress event for RotaryEncoder Press.
This commit is contained in:
parent
d83bb244c2
commit
d31e104679
@ -687,8 +687,6 @@ void NotificationRenderer::drawTextInput(OLEDDisplay *display, OLEDDisplayUiStat
|
|||||||
inEvent.inputEvent = INPUT_BROKER_NONE;
|
inEvent.inputEvent = INPUT_BROKER_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continuous long-press repeat removed: no per-frame ticking needed
|
|
||||||
|
|
||||||
// Clear the screen to avoid overlapping with underlying frames or overlays
|
// Clear the screen to avoid overlapping with underlying frames or overlays
|
||||||
display->setColor(BLACK);
|
display->setColor(BLACK);
|
||||||
display->fillRect(0, 0, display->getWidth(), display->getHeight());
|
display->fillRect(0, 0, display->getWidth(), display->getHeight());
|
||||||
|
@ -8,22 +8,24 @@ RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(const char *name) : concu
|
|||||||
|
|
||||||
void RotaryEncoderInterruptBase::init(
|
void RotaryEncoderInterruptBase::init(
|
||||||
uint8_t pinA, uint8_t pinB, uint8_t pinPress, input_broker_event eventCw, input_broker_event eventCcw,
|
uint8_t pinA, uint8_t pinB, uint8_t pinPress, input_broker_event eventCw, input_broker_event eventCcw,
|
||||||
input_broker_event eventPressed,
|
input_broker_event eventPressed, input_broker_event eventPressedLong,
|
||||||
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
|
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
|
||||||
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
|
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
|
||||||
{
|
{
|
||||||
this->_pinA = pinA;
|
this->_pinA = pinA;
|
||||||
this->_pinB = pinB;
|
this->_pinB = pinB;
|
||||||
|
this->_pinPress = pinPress;
|
||||||
this->_eventCw = eventCw;
|
this->_eventCw = eventCw;
|
||||||
this->_eventCcw = eventCcw;
|
this->_eventCcw = eventCcw;
|
||||||
this->_eventPressed = eventPressed;
|
this->_eventPressed = eventPressed;
|
||||||
|
this->_eventPressedLong = eventPressedLong;
|
||||||
|
|
||||||
pinMode(pinPress, INPUT_PULLUP);
|
pinMode(pinPress, INPUT_PULLUP);
|
||||||
pinMode(this->_pinA, INPUT_PULLUP);
|
pinMode(this->_pinA, INPUT_PULLUP);
|
||||||
pinMode(this->_pinB, INPUT_PULLUP);
|
pinMode(this->_pinB, INPUT_PULLUP);
|
||||||
|
|
||||||
// attachInterrupt(pinPress, onIntPress, RISING);
|
// Use FALLING edge for active-low press button to start long-press timing immediately
|
||||||
attachInterrupt(pinPress, onIntPress, RISING);
|
attachInterrupt(pinPress, onIntPress, FALLING);
|
||||||
attachInterrupt(this->_pinA, onIntA, CHANGE);
|
attachInterrupt(this->_pinA, onIntA, CHANGE);
|
||||||
attachInterrupt(this->_pinB, onIntB, CHANGE);
|
attachInterrupt(this->_pinB, onIntB, CHANGE);
|
||||||
|
|
||||||
@ -37,10 +39,37 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
|||||||
InputEvent e;
|
InputEvent e;
|
||||||
e.inputEvent = INPUT_BROKER_NONE;
|
e.inputEvent = INPUT_BROKER_NONE;
|
||||||
e.source = this->_originName;
|
e.source = this->_originName;
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
// Handle press long/short detection
|
||||||
if (this->action == ROTARY_ACTION_PRESSED) {
|
if (this->action == ROTARY_ACTION_PRESSED) {
|
||||||
LOG_DEBUG("Rotary event Press");
|
bool buttonPressed = !digitalRead(_pinPress);
|
||||||
e.inputEvent = this->_eventPressed;
|
if (!pressDetected && buttonPressed) {
|
||||||
|
pressDetected = true;
|
||||||
|
pressStartTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressDetected) {
|
||||||
|
uint32_t duration = now - pressStartTime;
|
||||||
|
if (!buttonPressed) {
|
||||||
|
// released -> if short press, send short, else already sent long
|
||||||
|
if (duration < LONG_PRESS_DURATION && now - lastPressKeyTime >= pressDebounceMs) {
|
||||||
|
lastPressKeyTime = now;
|
||||||
|
LOG_DEBUG("Rotary event Press short");
|
||||||
|
e.inputEvent = this->_eventPressed;
|
||||||
|
}
|
||||||
|
pressDetected = false;
|
||||||
|
pressStartTime = 0;
|
||||||
|
lastPressLongEventTime = 0;
|
||||||
|
this->action = ROTARY_ACTION_NONE;
|
||||||
|
} else if (duration >= LONG_PRESS_DURATION && this->_eventPressedLong != INPUT_BROKER_NONE &&
|
||||||
|
lastPressLongEventTime == 0) {
|
||||||
|
// fire single-shot long press
|
||||||
|
lastPressLongEventTime = now;
|
||||||
|
LOG_DEBUG("Rotary event Press long");
|
||||||
|
e.inputEvent = this->_eventPressedLong;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (this->action == ROTARY_ACTION_CW) {
|
} else if (this->action == ROTARY_ACTION_CW) {
|
||||||
LOG_DEBUG("Rotary event CW");
|
LOG_DEBUG("Rotary event CW");
|
||||||
e.inputEvent = this->_eventCw;
|
e.inputEvent = this->_eventCw;
|
||||||
@ -53,7 +82,9 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
|||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->action = ROTARY_ACTION_NONE;
|
if (!pressDetected) {
|
||||||
|
this->action = ROTARY_ACTION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
@ -61,7 +92,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
|||||||
void RotaryEncoderInterruptBase::intPressHandler()
|
void RotaryEncoderInterruptBase::intPressHandler()
|
||||||
{
|
{
|
||||||
this->action = ROTARY_ACTION_PRESSED;
|
this->action = ROTARY_ACTION_PRESSED;
|
||||||
setIntervalFromNow(20); // TODO: this modifies a non-volatile variable!
|
setIntervalFromNow(20); // start checking for long/short
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotaryEncoderInterruptBase::intAHandler()
|
void RotaryEncoderInterruptBase::intAHandler()
|
||||||
|
@ -13,7 +13,7 @@ class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, public
|
|||||||
public:
|
public:
|
||||||
explicit RotaryEncoderInterruptBase(const char *name);
|
explicit RotaryEncoderInterruptBase(const char *name);
|
||||||
void init(uint8_t pinA, uint8_t pinB, uint8_t pinPress, input_broker_event eventCw, input_broker_event eventCcw,
|
void init(uint8_t pinA, uint8_t pinB, uint8_t pinPress, input_broker_event eventCw, input_broker_event eventCcw,
|
||||||
input_broker_event eventPressed,
|
input_broker_event eventPressed, input_broker_event eventPressedLong,
|
||||||
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
|
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
|
||||||
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
|
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
|
||||||
void intPressHandler();
|
void intPressHandler();
|
||||||
@ -33,10 +33,22 @@ class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, public
|
|||||||
volatile RotaryEncoderInterruptBaseActionType action = ROTARY_ACTION_NONE;
|
volatile RotaryEncoderInterruptBaseActionType action = ROTARY_ACTION_NONE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// pins and events
|
||||||
uint8_t _pinA = 0;
|
uint8_t _pinA = 0;
|
||||||
uint8_t _pinB = 0;
|
uint8_t _pinB = 0;
|
||||||
|
uint8_t _pinPress = 0;
|
||||||
input_broker_event _eventCw = INPUT_BROKER_NONE;
|
input_broker_event _eventCw = INPUT_BROKER_NONE;
|
||||||
input_broker_event _eventCcw = INPUT_BROKER_NONE;
|
input_broker_event _eventCcw = INPUT_BROKER_NONE;
|
||||||
input_broker_event _eventPressed = INPUT_BROKER_NONE;
|
input_broker_event _eventPressed = INPUT_BROKER_NONE;
|
||||||
|
input_broker_event _eventPressedLong = INPUT_BROKER_NONE;
|
||||||
const char *_originName;
|
const char *_originName;
|
||||||
|
|
||||||
|
// Long press detection variables
|
||||||
|
uint32_t pressStartTime = 0;
|
||||||
|
bool pressDetected = false;
|
||||||
|
uint32_t lastPressLongEventTime = 0;
|
||||||
|
unsigned long lastPressKeyTime = 0;
|
||||||
|
static const uint32_t LONG_PRESS_DURATION = 300; // ms
|
||||||
|
static const uint32_t LONG_PRESS_REPEAT_INTERVAL = 0; // 0 = single-shot for rotary select
|
||||||
|
const unsigned long pressDebounceMs = 200; // ms
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "RotaryEncoderInterruptImpl1.h"
|
#include "RotaryEncoderInterruptImpl1.h"
|
||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
|
extern bool osk_found;
|
||||||
|
|
||||||
RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
|
RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
|
||||||
|
|
||||||
@ -19,12 +20,14 @@ bool RotaryEncoderInterruptImpl1::init()
|
|||||||
input_broker_event eventCw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_cw);
|
input_broker_event eventCw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_cw);
|
||||||
input_broker_event eventCcw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_ccw);
|
input_broker_event eventCcw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_ccw);
|
||||||
input_broker_event eventPressed = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_press);
|
input_broker_event eventPressed = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_press);
|
||||||
|
input_broker_event eventPressedLong = INPUT_BROKER_SELECT_LONG;
|
||||||
|
|
||||||
// moduleConfig.canned_message.ext_notification_module_output
|
// moduleConfig.canned_message.ext_notification_module_output
|
||||||
RotaryEncoderInterruptBase::init(pinA, pinB, pinPress, eventCw, eventCcw, eventPressed,
|
RotaryEncoderInterruptBase::init(pinA, pinB, pinPress, eventCw, eventCcw, eventPressed, eventPressedLong,
|
||||||
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
||||||
RotaryEncoderInterruptImpl1::handleIntPressed);
|
RotaryEncoderInterruptImpl1::handleIntPressed);
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
osk_found = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user