Debouncing Algorithms

  1. As soon as a transition is detected, accept the new state. This is an easy method for low-speed (25 Hz or less) polling applications, but it may mistake a glitch for a transition if the glitch happens exactly at the sample moment;
  2. After the detection of a transition, start a timer to check the input again 20 milliseconds or so later. Use as contact state the value at the input when the timer expires. This works with both polling and interrupts but requires a timer. Keeping the pin interrupt disabled while the timer is running will avoid unnecessary stress due to bouncing;
  3. A step further is to require two or more identical samples before accepting a state change, for instance three out of four or seven out of ten. This is the digital equivalent of the integrating RC debounce network. Instead of requiring x out of y valid reads, you can also require z consecutive valid samples. Its responsiveness depends on the number of samples and the sampling rate.

Example Code?

So now you probably expect example code that you can cut & paste into your program. Well, there isn’t. How to best implement debouncing algorithms highly depends on the cleverness of the programmer and the resources available. I did draw up some though flowcharts though that you can refer to.

 
naive debuncing
When a contact is read only every
once in a while, it is possible to get
away without more sophisticated
debouncing techniques.
 
debounce by reading twice
When polling is not too fast (<30 Hz or so) two consecutive
identical contact state values can be enough to accept a new state.
 
debounce with a timer
A contact transition starts a timer. The main program loop ignores the contact while the timer is running. The state of the contact is read again when the timer expires, i.e. when contact bouncing is expected to be over.
 
X out of Y debouncing
A flowchart-equivalent of an RC debounce network. This one will trigger when at least 'max count' valid samples have been read.


Schematics

Here is an LTspice simulation of the RC debounce circuit that we started with. To make the simulation produce different results for every run, you should check the option ‘Use the clock to reseed the MC generator[*]’ on the ‘Hacks!’ tab of the ‘Control Panel’ (the button with the little hammer on it) of LTspice. The ‘{100*mc(1,1)}’ part in the value for B1 makes this possible. Play with the different R/C values to change the debounce characteristics.
 
LTspice switch debounce
V2 produces the contact closure pulse, B1 adds bounce to it.
The value of B1 determines the minimum bounce glitch length (here it is 1 ms).
Change the values of R3/C2 and/or R4/C3 to modify bounce characteristics.
LTspice switch debounce simulation
Simulated contact bounce (pink) and the debounced result (blue).

So, What Do I Use?

As with every subject in electronics, in engineering and in general, there is much more to be said about it. Every switch bounces in its own way, and its bounce characteristics may change over time. Bounce behavior may be different on opening or closing. Contacts wear and the surface properties change; contact surface has an influence on conductivity. Some systems require fast response times, others don’t care and so on and so further. As a result, it is impossible to say which debounce method is best for you. Learn and understand your system first before deciding on a technique.