From 915bb0ea163da5fadcd58466c52448f37bda25b0 Mon Sep 17 00:00:00 2001 From: JChristensen Date: Fri, 1 Nov 2024 14:01:48 -0400 Subject: [PATCH] Improvements for noise immunity. Closes #33. --- library.properties | 4 ++-- src/JC_Button.cpp | 34 ++++++++++++++++++++++++---------- src/JC_Button.h | 13 ++++++++----- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/library.properties b/library.properties index a67a0ca..5e60848 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=JC_Button -version=2.1.4 +version=2.1.5 author=Jack Christensen maintainer=Jack Christensen sentence=Arduino library to debounce button switches, detect presses, releases, and long presses. -paragraph=Copyright (C) 2018-2019 by Jack Christensen and licensed under GNU GPL v3.0. +paragraph=Copyright (C) 2018-2024 by Jack Christensen and licensed under GNU GPL v3.0. category=Signal Input/Output url=https://github.com/JChristensen/JC_Button architectures=* diff --git a/src/JC_Button.cpp b/src/JC_Button.cpp index 2541056..8fe22f1 100644 --- a/src/JC_Button.cpp +++ b/src/JC_Button.cpp @@ -21,18 +21,32 @@ void Button::begin() // does debouncing, captures and maintains times, previous state, etc. bool Button::read() { - uint32_t ms = millis(); + m_time = millis(); bool pinVal = digitalRead(m_pin); if (m_invert) pinVal = !pinVal; - if (ms - m_lastChange < m_dbTime) { - m_changed = false; - } - else { - m_lastState = m_state; - m_state = pinVal; - m_changed = (m_state != m_lastState); - if (m_changed) m_lastChange = ms; + + switch (m_fsm) { + case STABLE: + if (pinVal != m_state) { // maybe a change, but debounce first + m_dbStart = m_time; + m_fsm = DEBOUNCE; + } + else { // nothing to see here + m_changed = false; + } + break; + + case DEBOUNCE: + if (m_time - m_dbStart >= m_dbTime) { + m_fsm = STABLE; + if (pinVal != m_state) { // a real change (else just noise) + m_lastState = m_state; + m_state = pinVal; + m_lastChange = m_time; + m_changed = true; + } + } + break; } - m_time = ms; return m_state; } diff --git a/src/JC_Button.h b/src/JC_Button.h index 1872b8c..20c4802 100644 --- a/src/JC_Button.h +++ b/src/JC_Button.h @@ -60,15 +60,18 @@ class Button uint32_t lastChange() const {return m_lastChange;} private: + enum fsmStates_t {STABLE, DEBOUNCE}; // states for the state machine + fsmStates_t m_fsm {STABLE}; // initial state machine state uint8_t m_pin; // arduino pin number connected to button uint32_t m_dbTime; // debounce time (ms) bool m_puEnable; // internal pullup resistor enabled bool m_invert; // if true, interpret logic low as pressed, else interpret logic high as pressed - bool m_state = false; // current button state, true=pressed - bool m_lastState = false; // previous button state - bool m_changed = false; // state changed since last read - uint32_t m_time = 0; // time of current state (ms from millis) - uint32_t m_lastChange = 0; // time of last state change (ms) + bool m_state {false}; // current button state, true=pressed + bool m_lastState {false}; // previous button state + bool m_changed {false}; // state changed since last read + uint32_t m_time {0}; // time of current state (ms from millis) + uint32_t m_lastChange {0}; // time of last state change (ms) + uint32_t m_dbStart; // debounce interval start time }; // a derived class for a "push-on, push-off" (toggle) type button.