mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-29 06:06:38 +00:00
fix(ui): debounce the Hall sensor poll against reed-switch contact bounce
pollHallSensor() acted on the raw pin reading immediately, unlike every other physical-input path in this file (MomentaryButton, pollCardKB()'s own last-raw edge check). A cheap mechanical reed switch -- one of the two sensor types the docs explicitly recommend wiring here, alongside a solid-state Hall IC -- can chatter for a few ms while the magnet crosses the trigger distance, so a poll every loop() tick during that window could flip _locked and fire _display->turnOff()/turnOn() repeatedly in that short span: wasted work on any panel, and a real cost on e-ink where each is a slow full-panel operation. A raw reading now has to hold steady for HALL_DEBOUNCE_MS (25ms, same threshold as MomentaryButton's ISR_DEBOUNCE_MS) before it replaces _hall_magnet_present and triggers the lock/unlock actions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2255,11 +2255,24 @@ void UITask::pollCardKB() {
|
|||||||
// there's nothing to show), opening unlocks and wakes it, with no combo or
|
// there's nothing to show), opening unlocks and wakes it, with no combo or
|
||||||
// keypress either way. Independent of Auto-lock (Settings > Display), which is
|
// keypress either way. Independent of Auto-lock (Settings > Display), which is
|
||||||
// a timeout-driven setting -- this is a direct physical event.
|
// a timeout-driven setting -- this is a direct physical event.
|
||||||
|
//
|
||||||
|
// Debounced against a mechanical reed switch chattering for a few ms as the
|
||||||
|
// magnet crosses the trigger distance -- a raw flip only becomes the new
|
||||||
|
// _hall_magnet_present once it's been steady for HALL_DEBOUNCE_MS, so a bounce
|
||||||
|
// can't fire the lock/unlock actions (each including a full display
|
||||||
|
// off/on -- slow and disruptive on e-ink) more than once per real transition.
|
||||||
void UITask::pollHallSensor() {
|
void UITask::pollHallSensor() {
|
||||||
#if defined(PIN_HALL_SENSOR)
|
#if defined(PIN_HALL_SENSOR)
|
||||||
bool present = HALL_ACTIVE_HIGH ? (digitalRead(PIN_HALL_SENSOR) == HIGH)
|
bool raw = HALL_ACTIVE_HIGH ? (digitalRead(PIN_HALL_SENSOR) == HIGH)
|
||||||
: (digitalRead(PIN_HALL_SENSOR) == LOW);
|
: (digitalRead(PIN_HALL_SENSOR) == LOW);
|
||||||
if (present == _hall_magnet_present) return;
|
if (raw != _hall_candidate) {
|
||||||
|
_hall_candidate = raw;
|
||||||
|
_hall_candidate_since = millis();
|
||||||
|
}
|
||||||
|
if (_hall_candidate == _hall_magnet_present) return; // no debounced change yet
|
||||||
|
if (millis() - _hall_candidate_since < HALL_DEBOUNCE_MS) return; // not steady long enough
|
||||||
|
|
||||||
|
bool present = _hall_candidate;
|
||||||
_hall_magnet_present = present;
|
_hall_magnet_present = present;
|
||||||
|
|
||||||
if (present) { // cover closed
|
if (present) { // cover closed
|
||||||
|
|||||||
@@ -219,6 +219,13 @@ class UITask : public AbstractUITask {
|
|||||||
#define HALL_ACTIVE_HIGH 0
|
#define HALL_ACTIVE_HIGH 0
|
||||||
#endif
|
#endif
|
||||||
bool _hall_magnet_present = false;
|
bool _hall_magnet_present = false;
|
||||||
|
// Contact-bounce guard for a mechanical reed switch (a Hall-effect IC reads
|
||||||
|
// clean, but the docs recommend either): a raw reading only replaces
|
||||||
|
// _hall_magnet_present once it's held steady for HALL_DEBOUNCE_MS, same
|
||||||
|
// threshold and reasoning as MomentaryButton's ISR_DEBOUNCE_MS.
|
||||||
|
static const uint32_t HALL_DEBOUNCE_MS = 25;
|
||||||
|
bool _hall_candidate = false;
|
||||||
|
uint32_t _hall_candidate_since = 0;
|
||||||
#endif
|
#endif
|
||||||
void pollHallSensor();
|
void pollHallSensor();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user