Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve touch handling #28

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 49 additions & 3 deletions lib/EFTouch/EFTouch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@

#include "EFTouch.h"

constexpr unsigned int DEFAULT_DETECTION_STEP = 10000;

EFTouchClass::EFTouchClass()
: pin_fingerprint(EFTOUCH_PIN_TOUCH_FINGERPRINT)
, pin_nose(EFTOUCH_PIN_TOUCH_NOSE)
, detection_step(10000)
, detection_step(DEFAULT_DETECTION_STEP)
, noise_fingerprint(0)
, noise_nose(0)
, last_touch_millis_fingerprint(0)
Expand All @@ -53,7 +55,7 @@ EFTouchClass::~EFTouchClass() {
}

void EFTouchClass::init() {
this->init(10000, EFTOUCH_PIN_TOUCH_FINGERPRINT, EFTOUCH_PIN_TOUCH_NOSE);
this->init(DEFAULT_DETECTION_STEP, EFTOUCH_PIN_TOUCH_FINGERPRINT, EFTOUCH_PIN_TOUCH_NOSE);
}

void EFTouchClass::init(touch_value_t detection_step, uint8_t pin_fingerprint, uint8_t pin_nose) {
Expand All @@ -76,6 +78,7 @@ void EFTouchClass::init(touch_value_t detection_step, uint8_t pin_fingerprint, u
LOGF_DEBUG("(EFTouch) Registered: pin_fingerprint=%d pin_nose=%d\r\n", pin_fingerprint, pin_nose);

this->calibrate();
this->longpressAlreadyRegisteredByCheckNose = false;
this->enableInterrupts(EFTouchZone::Fingerprint);
this->enableInterrupts(EFTouchZone::Nose);
}
Expand Down Expand Up @@ -140,6 +143,37 @@ uint8_t EFTouchClass::readNose() {
}
}

void EFTouchClass::checkForLongpressEvents() {

// const bool currentStateNose = this->isNoseTouched();
// const bool raising_flank = this->lastStateNose == false && currentStateNose == true;
// if (raising_flank) {
// this->lastStateNose = currentStateNose;
// // Just started pressing
// // The ISR *should* have run already and updated last_touch_millis_nose, but some reason this does not always happen
// // So we have to manually do it here.
// auto ms = this->last_touch_millis_nose;
// LOGF_INFO("XXX Detected touch, updating time: %d\r\n", ms);
// this->last_touch_millis_nose = millis();
// return;
// }

if (this->onNoseLongpressIsr == nullptr || this->longpressAlreadyRegisteredByCheckNose == true || this->isNoseTouched() == false) {
// No interrupt method configured or
// we have already triggered and waiting for a reset or
// there is no touch -> do nothing
return;
}

auto ms = this->last_touch_millis_nose;
if (this->last_touch_millis_nose + EFTOUCH_LONGPRESS_DURATION_MS < millis()) {
longpressAlreadyRegisteredByCheckNose = true;
LOGF_INFO("XXX ISR Event by checkForLongpressEvent. last touch: %d\r\n", ms);
LOGF_INFO("XXX isr Event by checkForLongpressEvent. current millis: %d\r\n", millis());
this->onNoseLongpressIsr();
}
}

void ARDUINO_ISR_ATTR _eftouch_isr_fingerprint() {
EFTouch._handleInterrupt(
EFTouchZone::Fingerprint,
Expand Down Expand Up @@ -206,6 +240,7 @@ void ARDUINO_ISR_ATTR EFTouchClass::_handleInterrupt(EFTouchZone zone, bool rais
this->onFingerprintTouchIsr();
}
} else {
// Release
// Fire onFingerprintShortpressIsr() if applicable
if (this->onFingerprintShortpressIsr != nullptr) {
if (this->last_touch_millis_fingerprint + EFTOUCH_SHORTPRESS_DURATION_MS < millis()) {
Expand All @@ -226,6 +261,8 @@ void ARDUINO_ISR_ATTR EFTouchClass::_handleInterrupt(EFTouchZone zone, bool rais
break;
case EFTouchZone::Nose:
if (raising_flank) {
// longpressAlreadyRegisteredByCheckNose = false;

// Register first touch timestamp
this->last_touch_millis_nose = millis();

Expand All @@ -234,13 +271,22 @@ void ARDUINO_ISR_ATTR EFTouchClass::_handleInterrupt(EFTouchZone zone, bool rais
this->onNoseTouchIsr();
}
} else {
// Release
// If it was already handled, we will ignore this interrupt
bool ignoreEvent = longpressAlreadyRegisteredByCheckNose;
// reset, so we can register new longpress events by the check mehtod
longpressAlreadyRegisteredByCheckNose = false;
if (ignoreEvent) {
break;
}

// Fire onNoseShortpressIsr() if applicable
if (this->onNoseShortpressIsr != nullptr) {
if (this->last_touch_millis_nose + EFTOUCH_SHORTPRESS_DURATION_MS < millis()) {
this->onNoseShortpressIsr();
}
}
// Fire onFingerperintLongpressIsr() if applicable
// Fire onNonseLongpressIsr() if applicable
if (this->onNoseLongpressIsr != nullptr) {
if (this->last_touch_millis_nose + EFTOUCH_LONGPRESS_DURATION_MS < millis()) {
this->onNoseLongpressIsr();
Expand Down
12 changes: 10 additions & 2 deletions lib/EFTouch/EFTouch.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ class EFTouchClass {
touch_value_t noise_fingerprint; //!< Calibrated noise floor for fingerprint touch pad
touch_value_t noise_nose; //!< Calibrated noise floor for nose touch pad

unsigned long last_touch_millis_fingerprint; //!< Timestamp when the fingerprint was last touched
unsigned long last_touch_millis_nose; //!< Timestamp when the nose was last touched
volatile unsigned long last_touch_millis_fingerprint; //!< Timestamp when the fingerprint was last touched
volatile unsigned long last_touch_millis_nose; //!< Timestamp when the nose was last touched
bool lastStateNose;
volatile bool longpressAlreadyRegisteredByCheckNose;

void (*onFingerprintTouchIsr)(void); //!< ISR to execute if the fingerprint is first touched
void (*onFingerprintReleaseIsr)(void); //!< ISR to execute if the fingerprint is fully released
Expand Down Expand Up @@ -142,6 +144,12 @@ class EFTouchClass {
*/
uint8_t readNose();

/**
* @brief This method should be called in a loop or some timer to makre sure, the lib checks for long-press
* even if the buttons are still being held.
*/
void checkForLongpressEvents();

/**
* @brief Enable interrupt handling for the given touch zone
*
Expand Down
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ void setup() {
* @brief Main program loop
*/
void loop() {
// The user might be holding the buttons. Calling EFTouch periodically allows it to check this and send events before release
EFTouch.checkForLongpressEvents();

// Handler: ISR Events
if (isrEvents.fingerprintTouch) {
fsm.queueEvent(FSMEvent::FingerprintTouch);
Expand Down
Loading