2525// / @version 1.1.4 Repeated debounce in the button class removed.
2626// /
2727// / @date 2024-07-06
28- // / @version 1.1.5 The autorelease is only executed once as long as the button has not been released.
29- // / Previously, if the button was held down continuously, the autorelease was executed
30- // / every time the time for a long button press expired.
28+ // / @version 1.1.5 The autorelease is only executed once as long as the button has not been released.
29+ // / Previously, if the button was held down continuously, the autorelease was executed
30+ // / every time the time for a long button press expired.
31+ // /
32+ // / @date 2025-05-10
33+ // / @version 1.1.6 The ButtonState::pressed status has been added.
34+ // / For a long button press with automatic release enabled, the ButtonState::longPressed status
35+ // / is returned once when the defined time for a long button press is reached. Then
36+ // / the ButtonState::pressed status is returned as long as the button is held down.
37+ // /
38+ // / @date 2025-05-26
39+ // / @version 1.1.7 tick() Method code rework. Bug fix.
3140// /
3241// / @copyright Copyright (c) 2022
3342// / MIT license, check license.md for more information
@@ -58,10 +67,10 @@ bool Button::tick() {
5867 switch (compareState) {
5968 case LOW :
6069 compareState = HIGH ; // set to HIGH when Button was pressed
61- timeStamp = millis ();
70+ timestamp = millis ();
6271 [[fallthrough]] ;
6372 case HIGH :
64- if (millis () - timeStamp > dbTime_ms) {
73+ if (millis () - timestamp > dbTime_ms) {
6574 // If the button press is equal to the specified debounce time, confirm the button press with true.
6675 flag = true ;
6776 }
@@ -84,30 +93,50 @@ void Button::setDebounceTime_ms(uint16_t dbT_ms) { dbTime_ms = dbT_ms; }
8493// / @brief The ButtonSL query. The tick() method should be called in an endless loop.
8594// /
8695// / @param time_ms time (in ms) from which a key press is recognized as long
87- // / @return ButtonState The states are "Not pressed", "short pressed" and "long pressed"
96+ // / @return ButtonState The states are "not pressed", " pressed", "short pressed" and "long pressed"
8897// ////////////////////////////////////////////////////////////////////////////
98+
8999ButtonState ButtonSL::tick () {
90- uint_least32_t now = millis ();
91100 compareState = state;
92101 state = digitalRead (pin);
93- if (state == activeState && compareState != activeState) {
94- timeStamp = now;
95- hasReleased = false ;
96- } else if (state != activeState && compareState == activeState) {
97- timeStamp = now - timeStamp;
98- if (timeStamp >= dbTime_ms && !hasReleased) { // released after debounce time?
99- return (timeStamp >= time_ms) ? ButtonState::longPressed : ButtonState::shortPressed;
100- }
101- // hasReleased = false;
102- } else if (autoRelease && not hasReleased && (compareState == activeState)) {
103- if (now - timeStamp >= time_ms) {
104- // state = !compareState;
105- hasReleased = true ;
106- timeStamp = time_ms;
107- return ButtonState::longPressed;
108- }
102+
103+ MillisType now = millis ();
104+ if (state != activeState && compareState != activeState) { // not pressed
105+ return ButtonState::notPressed;
106+ } else if (state == activeState && compareState != activeState) { // Not pressed to pressed
107+ timestamp = now;
108+ autoReleaseFired = false ;
109+ pin_state = Condition::notPressedToPressed;
110+ } else if (state == activeState && compareState == activeState) { // pressed
111+ pin_state = Condition::pressed;
112+ } else if (state != activeState && compareState == activeState) { // Pressed to not pressed
113+ pin_state = Condition::pressedToNotpressed;
114+ }
115+
116+ switch (pin_state) {
117+ case Condition::notPressedToPressed:
118+ case Condition::pressed:
119+ if (autoRelease) {
120+ switch (autoReleaseFired) {
121+ case true : return ButtonState::pressed; break ;
122+ case false :
123+ if (now - timestamp >= time_ms) {
124+ autoReleaseFired = true ;
125+ timestamp = time_ms;
126+ return ButtonState::longPressed;
127+ }
128+ }
129+ }
130+ break ;
131+ case Condition::pressedToNotpressed:
132+ timestamp = now - timestamp;
133+ // Push duration longer than the debounce time?
134+ if (timestamp >= dbTime_ms && !autoReleaseFired) {
135+ return (timestamp >= time_ms) ? ButtonState::longPressed : ButtonState::shortPressed;
136+ }
137+ break ;
109138 }
110- return hasReleased ? ButtonState::pressed : ButtonState::notPressed;
139+ return ButtonState::notPressed;
111140}
112141
113142// ////////////////////////////////////////////////////////////////////////////
@@ -122,5 +151,5 @@ void ButtonSL::setTimeThreshold_ms(uint16_t th_ms) { time_ms = th_ms; }
122151// /
123152// / @return uint32_t Time in milliseconds
124153// ////////////////////////////////////////////////////////////////////////////
125- uint32_t ButtonSL::getDuration_ms (void ) const { return timeStamp ; }
154+ uint32_t ButtonSL::getDuration_ms (void ) const { return timestamp ; }
126155} // namespace Btn
0 commit comments