Skip to content

Commit cfaae73

Browse files
committed
Update
Various cleanups made. Now uses only the robust algorithm for simplicity. Various documentation updates including detailed debounce algorithm description.
1 parent 3b4e0fe commit cfaae73

File tree

8 files changed

+27
-86
lines changed

8 files changed

+27
-86
lines changed

README.md

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
# Toggle [![arduino-library-badge](https://www.ardu-badge.com/badge/Toggle.svg?)](https://www.ardu-badge.com/Toggle) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/dlloydev/library/Toggle.svg)](https://registry.platformio.org/libraries/dlloydev/Toggle)
22

3-
Arduino button library for deglitching and debouncing switch contacts and logic data. Works with all switch types, port expander and other 8-bit data sources. Three algorithm modes available that can ignore up to several consecutive spurious transitions.
3+
Arduino button library for debouncing switch contacts and logic data. New pressCode() function detects fast, short and long button presses for 225 combinations. Works with all switch types, port expanders and other 8-bit data sources. Debounce algorithm ignores several consecutive spurious transitions.
44

55
## Features
66

77
### Flexible Inputs
88

99
The inputs can be from a single pin or several pins allowing the use of 2 or 3-position switches and up to seven debounced states. When linking to a data (byte) input, the debouncer can work with any selected bit or it can debounce all 8-bits in one Toggle instance. Examples: [`Input_Bit_Test.ino`](https://github.com/Dlloydev/Toggle/blob/main/examples/Input_Bit_Test/Input_Bit_Test.ino) , [`Input_Bit.ino`](https://github.com/Dlloydev/Toggle/blob/main/examples/Input_Bit/Input_Bit.ino), [`Input_Port_Test.ino`](https://github.com/Dlloydev/Toggle/blob/main/examples/Input_Port_Test/Input_Port_Test.ino) and [`Input_Port.ino`](https://github.com/Dlloydev/Toggle/blob/main/examples/Input_Port/Input_Port.ino).
1010

11-
### Algorithms
11+
### Algorithm
1212

13-
```c++
14-
setAlgorithm(2); // Robust Mode, 2 glitches ignored
15-
setAlgorithm(1); // Average Mode, 1 glitch ignored
16-
setAlgorithm(0); // Common Mode, can respond to spurious transitions
17-
```
13+
The debounce algorithm adds only 2 sample periods of time lag to the output signal. A 3-sample stable period is required for an output bit to change. Therefore, to set an output bit, 3 consecutive 1's are required. When 3 consecutive 0's are detected, that bit value is cleared.![image](https://user-images.githubusercontent.com/63488701/171260623-befe88a4-66c4-44a2-a38b-6c14c715a92d.png)
1814

19-
In Robust Mode, the algorithm adds only 2 sample periods of time lag to the output signal. A 3-sample stable period is required for an output bit to change. Therefore, to set an output bit, 3 consecutive 1's are required. When 3 consecutive 0's are detected, that bit value is cleared.
15+
| ppDat | pDat | dat | **R** | **S** | **Q** | **State** |
16+
| ----- | ---- | ---- | ----- | ----- | ---------- | --------- |
17+
| 0 | 0 | 0 | 1 | 0 | 0 | Reset |
18+
| 0 | 0 | 1 | 0 | 0 | Last State | No Change |
19+
| 0 | 1 | 0 | 0 | 0 | Last State | No Change |
20+
| 0 | 1 | 1 | 0 | 0 | Last State | No Change |
21+
| 1 | 0 | 0 | 0 | 0 | Last State | No Change |
22+
| 1 | 0 | 1 | 0 | 0 | Last State | No Change |
23+
| 1 | 1 | 0 | 0 | 0 | Last State | No Change |
24+
| 1 | 1 | 1 | 0 | 1 | 1 | Set |
2025

2126
### Sampling
2227

23-
Rather than use a basic timer strategy, the Toggle library uses sampling and only requires up to three samples on the input to to provide a clean (debounced) output. The sample period defaults to 5000 μs (5 ms) which works well the default Robust Mode. With these defaults, only 15ms is required for detecting a button switch being pressed or released. This may seem low when thinking of regular debouncig, but in order for this method to falsely detect a transition, it would require that there be a gap of greater than 15ms between bounces. From *[A Guide to Debouncing](http://www.ganssle.com/item/debouncing-switches-contacts-code.htm)*, (Anatomy of a Bounce):
28+
The sample period defaults to 5000 μs. With this setting, only 15ms is required for detecting a button switch being pressed or released. This may seem low when thinking of regular debouncig, but in order for this method to falsely detect a transition, it would require that there be a gap of greater than 15ms between bounces. From *[A Guide to Debouncing](http://www.ganssle.com/item/debouncing-switches-contacts-code.htm)*, (Anatomy of a Bounce):
2429

2530
> *Consider switch E again, that one with the pretty face that hides a vicious 157 msec bouncing heart. One test showed the switch going to a solid one for 81 msec, after which it dropped to a perfect zero for 42 msec before finally assuming its correct high state. Think what that would do to pretty much any debounce code!*
2631
@@ -117,11 +122,8 @@ None.
117122
##### Example
118123
119124
```c++
120-
/* a button or switch is connected from pin 2 to ground
121-
5000 μs sample interval (default)
122-
pullup enabled (default)
123-
inverted = false (default)
124-
algorithm = 2 glitches "Robust Mode" (default) */
125+
// a button or switch is connected from pin 2 to ground, 5000 μs sample interval (default),
126+
// pullup enabled (default), inverted = false (default)
125127
Toggle myInput(2);
126128
127129
// same as above, but a 3 position switch is connected to pins 2 and 3
@@ -155,7 +157,7 @@ None.
155157

156158
## Primary Functions
157159

158-
There are 5 primary functions when using 1 input pin or data bit. Shown below is a plot showing the returned values that are verically offset for clarity. Here, the algorithm was set to 0 glitches. In this case, the debounce interval is hard coded to 10 sample periods. The response is near instant "press" detection and delayed "release" detection which is similar to how most common debouncers operate:
160+
There are 5 primary functions when using 1 input pin or data bit. Shown below is a plot showing the returned values that are verically offset for clarity:
159161

160162
![image](https://user-images.githubusercontent.com/63488701/169307791-e4b02e03-4399-4984-87a2-755dafaf3f47.png)
161163

@@ -476,26 +478,6 @@ Elapsed milliseconds *(unsigned int)*.
476478

477479

478480

479-
## setAlgorithm()
480-
481-
##### Description
482-
483-
Sets the debouncer algorithm to one of three modes.
484-
485-
- **Robust Mode (2):** This is the default mode where up to 2 spurious signal transitions (glitches) are ignored. This adds 2 sample periods time lag to the output signal.
486-
- **Average Mode (1):** This is mode ignores up to 1 spurious signal transition (glitch) and adds 1 sample period time lag to the output signal.
487-
- **Common Mode (0):** This is mode is similar to most debouncers where the response is near instant to a button or switch press, and the release won't be recognized until a debounce time period has expired. In this case, the debounce time period is calculated and set at 10 times the sample period.
488-
489-
##### Syntax
490-
491-
`myInput.setAlgorithm(2);`
492-
493-
##### Returns
494-
495-
Control and Status Register (csr) value *(byte)*.
496-
497-
498-
499481
---
500482

501483

examples/Input_Bit_Test/Input_Bit_Test.ino

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ void setup() {
2525
Serial.begin(115200);
2626
myInput.begin(Input);
2727
myInput.setInputMode(myInput.inMode::input_port);
28-
myInput.setAlgorithm(2); // ignore(2), (1) or (0) glitches for robust, normal and quick response
2928
myInput.setSamplePeriodUs(20); // 0-65535μs
3029

3130
for (int i = 0; i < 47; i++) {

examples/Input_Port_Test/Input_Port_Test.ino

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ void setup() {
5858
Serial.begin(115200);
5959
myInput.begin(Input);
6060
myInput.setInputMode(myInput.inMode::input_port);
61-
myInput.setAlgorithm(2); // ignore(2), (1) or (0) glitches for robust, normal and quick response
6261
myInput.setSamplePeriodUs(20); // 0-65535μs
6362

6463
for (int i = 0; i < 15; i++) {

keywords.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,9 @@ sw9 KEYWORD1
2525
##########################################
2626

2727
poll KEYWORD2
28-
setAlgorithm KEYWORD2
2928
setInputMode KEYWORD2
3029
setInvertMode KEYWORD2
3130
setSamplePeriodUs KEYWORD2
32-
setTimerMode KEYWORD2
33-
getTimerMode KEYWORD2
3431
getElapsedMs KEYWORD2
3532
isPressed KEYWORD2
3633
isReleased KEYWORD2
@@ -42,7 +39,6 @@ blink KEYWORD2
4239
pressedFor KEYWORD2
4340
releasedFor KEYWORD2
4441
retrigger KEYWORD2
45-
retrigger KEYWORD2
4642
pressCode KEYWORD2
4743
debounceInput KEYWORD2
4844
isUP KEYWORD2

library.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Toggle",
3-
"version": "3.1.2",
4-
"description": "Arduino bounce library for deglitching and debouncing hardware, signals and data. Works with all switch types, port expander and other 8-bit data sources. Flexible algorithm with Robust, Normal and Quick response modes.",
3+
"version": "3.1.3",
4+
"description": "Arduino bounce library for debouncing hardware, signals and data. Works with all switch types, port expander and other 8-bit data sources. Robust debounce algorithm.",
55
"keywords": "debounce, toggle, button, switch, data, deglitch",
66
"repository":
77
{

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=Toggle
2-
version=3.1.2
2+
version=3.1.3
33
author=David Lloyd
44
maintainer=David Lloyd <[email protected]>
55
sentence=Arduino bounce library for deglitching and debouncing hardware, signals and data. Works with all switch types, port expander and other 8-bit data sources.
6-
paragraph=Flexible algorithm with Robust, Normal and Quick response modes.
6+
paragraph=Robust debounce algorithm.
77
category=Signal Input/Output
88
url=https://github.com/Dlloydev/Toggle
99
architectures=*

src/Toggle.cpp

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/************************************************
2-
Toggle Library for Arduino - Version 3.1.2
2+
Toggle Library for Arduino - Version 3.1.3
33
by dlloydev https://github.com/Dlloydev/Toggle
44
Licensed under the MIT License.
55
************************************************/
@@ -46,27 +46,15 @@ void Toggle::poll(uint8_t bit) {
4646
if (csr & 0b00000100) dat = ~dat; // if invert mode
4747
if (bit > 7) bit = 0;
4848
debounceInput(bit);
49-
if ((csr & 0xF0) < 0xA0) csr += 0x10; // increment debounceCount (10 max)
5049
} // run sample
5150
} // poll
5251

53-
uint8_t Toggle::setAlgorithm(uint8_t glitches) {
54-
csr |= 0b00000010; // 2 glitches ignored (default)
55-
csr &= ~0b00000001;
56-
if (glitches == 1) { // 1 glitch ignored
57-
csr |= 0b00000001;
58-
csr &= ~0b00000010;
59-
}
60-
else if (glitches == 0) csr &= ~0b00000011; // 0 glitches ignored
61-
return csr;
62-
}
63-
6452
void Toggle::setInputMode(inMode inputMode) {
6553
_inputMode = inputMode;
6654
}
6755

6856
void Toggle::setInvertMode(bool invert) {
69-
if (invert)csr |= 0b00000100; //set
57+
if (invert) csr |= 0b00000100; //set
7058
else csr &= ~0b00000100; //clear
7159
}
7260

@@ -86,7 +74,6 @@ bool Toggle::isReleased(uint8_t bit) {
8674

8775
bool Toggle::onPress() {
8876
if (lsr & 0b00000001) { // onPress
89-
if ((csr & 3) == 0 && (csr & 0xF0) == 0xA0) csr &= ~0xF0; // debounceCount = 0;;
9077
lsr &= ~0b00000001; // clear onPress flag
9178
pOut = out;
9279
return true;
@@ -96,7 +83,6 @@ bool Toggle::onPress() {
9683

9784
bool Toggle::onRelease() {
9885
if (lsr & 0b00000010) { // onRelease
99-
if ((csr & 3) == 0 && (csr & 0xF0) == 0xA0) csr &= ~0xF0; // debounceCount = 0;
10086
lsr &= ~0b00000010; // clear onRelease flag
10187
pOut = out;
10288
return true;
@@ -162,7 +148,6 @@ uint8_t Toggle::pressCode(bool debug) {
162148

163149
switch (_state) {
164150
case PB_DEFAULT:
165-
//setTimerMode(2); // onChange
166151
elapsedMs = getElapsedMs();
167152
if (pCode && isReleased() && (elapsedMs > (CLICK::LONG + CLICK::MULTI))) _state = PB_DONE;
168153
if (onChange()) startUs = micros();
@@ -227,29 +212,13 @@ uint8_t Toggle::pressCode(bool debug) {
227212
**************************************************************************************************/
228213
uint8_t Toggle::debounceInput(uint8_t bit) {
229214
pOut = out;
230-
uint8_t a, b, c, bits = 2;
215+
uint8_t bits = 2;
231216
if (_inputMode == inMode::input_bit) bits = 1;
232217
if (_inputMode == inMode::input_port) bits = 8;
233218

234219
for (int i = bit; i < bit + bits; i++) {
235-
a = dat & (1 << i);
236-
b = pDat & (1 << i);
237-
c = ppDat & (1 << i);
238-
239-
if (csr & 0b00000010) { // 2 glitches ignored
240-
if (a && b && c) out |= (1 << i);
241-
else if (!a && !b && !c) out &= ~(1 << i);
242-
243-
} else if (csr & 0b00000001) { // 1 glitch ignored
244-
if (a && b) out |= (1 << i);
245-
else if (!a && !b) out &= ~(1 << i);
246-
247-
} else { // immediate ON response, delayed OFF
248-
if ((csr & 0xF0) == 0xA0) { // if samples == 10
249-
if (a) out |= (1 << i);
250-
else if (!a) out &= ~(1 << i);
251-
}
252-
}
220+
if ((dat & (1 << i)) && (pDat & (1 << i)) && (ppDat & (1 << i))) out |= (1 << i);
221+
else if (!(dat & (1 << i)) && !(pDat & (1 << i)) && !(ppDat & (1 << i))) out &= ~(1 << i);
253222
}
254223
if ((pOut & (1 << bit)) && !isReleased(bit)) {
255224
lsr |= 0b00000001; // set onPress

src/Toggle.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ class Toggle {
1818

1919
void begin(uint8_t inA, uint8_t inB = 255); // required in setup
2020
void poll(uint8_t bit = 0); // required at top of loop
21-
22-
uint8_t setAlgorithm(uint8_t glitches = 2); // (2) robust mode, (1) average mode, (0) common mode
2321
void setInputMode(inMode inputMode); // input, input_pullup, input_pulldown, input_bit, input_port
2422
void setInvertMode(bool invert); // invert false: pullup resistors are used, invert true: pulldown resistors
2523
void setSamplePeriodUs(uint16_t samplePeriodUs); // sample period in microseconds
2624
uint32_t getElapsedMs(); // get elapsed ms since the last state change selected by timer mode
27-
2825
bool isPressed(uint8_t bit = 0); // returns true if pressed
2926
bool isReleased(uint8_t bit = 0); // returns true if released
3027
bool onPress(); // returns true if just pressed
@@ -37,7 +34,6 @@ class Toggle {
3734
bool retrigger(uint16_t ms); // returns true each time the given ms expires while the button is pressed
3835
uint8_t pressCode(bool debug = 0); // returns byte code for number of fast, short and long clicks
3936
uint8_t debounceInput(uint8_t bit = 0); // input debouncer
40-
4137
bool isUP(); // functions for using 2 inputs with 3-position switches
4238
bool isMID();
4339
bool isDN();
@@ -69,7 +65,7 @@ class Toggle {
6965
uint32_t startUs = 0; // for timing transitions
7066
uint32_t us_timestamp; // most recent sample time μs
7167
uint8_t out = 0xFF, pOut = 0xFF; // debounced output and previous debounced output
72-
uint8_t csr = 0b10101010; // B7-B4: debounceCount, B3: first run B2: invert, B1-B0 algorithm
68+
uint8_t csr = 0b00001010; // B3: first run B2: invert, B1-B0 algorithm
7369
uint8_t lsr = 0b00000000; // B5 lastState, B4 toggle, B1 onRelease, B0 onPress
7470

7571
};

0 commit comments

Comments
 (0)