mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-21 10:12:50 +00:00
Add On-Screen Keyboard for UpDown Encoder and Rotary Encoder. (#7762)
* Add On-Screen Keyboard for UpDownInterrupt. Pls notice the new keyboard layout was inspired and adviced by https://github.com/csrutil * Add longPress event for RotaryEncoder Press. * Update UpdownInterrupt UP and DOWN on main UI. * Change the interrupt trigger mode from rising edge to falling edge to improve button response.
This commit is contained in:
@@ -8,15 +8,17 @@ RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(const char *name) : concu
|
||||
|
||||
void RotaryEncoderInterruptBase::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) :
|
||||
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
|
||||
{
|
||||
this->_pinA = pinA;
|
||||
this->_pinB = pinB;
|
||||
this->_pinPress = pinPress;
|
||||
this->_eventCw = eventCw;
|
||||
this->_eventCcw = eventCcw;
|
||||
this->_eventPressed = eventPressed;
|
||||
this->_eventPressedLong = eventPressedLong;
|
||||
|
||||
bool isRAK = false;
|
||||
#ifdef RAK_4631
|
||||
@@ -46,10 +48,37 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
InputEvent e;
|
||||
e.inputEvent = INPUT_BROKER_NONE;
|
||||
e.source = this->_originName;
|
||||
unsigned long now = millis();
|
||||
|
||||
// Handle press long/short detection
|
||||
if (this->action == ROTARY_ACTION_PRESSED) {
|
||||
LOG_DEBUG("Rotary event Press");
|
||||
e.inputEvent = this->_eventPressed;
|
||||
bool buttonPressed = !digitalRead(_pinPress);
|
||||
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) {
|
||||
LOG_DEBUG("Rotary event CW");
|
||||
e.inputEvent = this->_eventCw;
|
||||
@@ -62,7 +91,9 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
|
||||
this->action = ROTARY_ACTION_NONE;
|
||||
if (!pressDetected) {
|
||||
this->action = ROTARY_ACTION_NONE;
|
||||
}
|
||||
|
||||
return INT32_MAX;
|
||||
}
|
||||
@@ -70,7 +101,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
void RotaryEncoderInterruptBase::intPressHandler()
|
||||
{
|
||||
this->action = ROTARY_ACTION_PRESSED;
|
||||
setIntervalFromNow(20); // TODO: this modifies a non-volatile variable!
|
||||
setIntervalFromNow(20); // start checking for long/short
|
||||
}
|
||||
|
||||
void RotaryEncoderInterruptBase::intAHandler()
|
||||
|
||||
Reference in New Issue
Block a user