Wednesday, May 20, 2009

The Best Switch Debounce Routine Ever

Switch debouncing is the process of filtering out the mechanical chatter that comes from switches (and relays) when their contacts touch or release. The duration of the chatter depends on the physical properties of the contacts but can last for as long as several tens of milliseconds. A comprehensive backgrounder to switch debouncing can be found here so I won’t repeat that content here. But I want to share with you an effective software debounce routine that is elegant in its simplicity, efficient and perfectly scalable.

Consider the following ‘bouncy’ signal.

Up until t=3, the input signal is in a low state. At t=3, some EMI induces some spurious noise on the wire that we want to reject. At t=5, the switch is in a bouncy state as a result of being activated. And at t=6 and beyond, the switch is in a stable high state.

The goal of the debounce routine is to reject spurious signals such as those found at t=3 while still reporting a valid transition within a timely fashion. This can be done by taking periodic samples of the signal and reporting an update once several samples agree with one another. The exact number of samples and periodicity will depend on the environment that your application will be used in and the immediacy that you need to report an update.

So let:
A = Current Switch Sample (T=0)
B = Previous Switch Sample (T=-1)
C = Sample taken prior to B (T=-2)
Z = Last reported debounce value
Z’ = New debounce value

If (A = B = C) then
Z’ = A
Z’ = Z

We can create a karnaugh map for Z’ using the inputs A, B, C and Z.

There are a number of benefits to this routine over other routines I've seen:

  1. It works for debouncing an entire input port as well as individual bits.
  2. It doesn’t consume any timer resources other than those required to periodically call the routine.
  3. It can be readily implemented in programmable hardware, and
  4. It is perfectly scalable. So you can expand the number of samples without modifying the basic algorithm. For instance, the equation for debouncing across 4 samples is:
    Z’ = Z(A+B+C+D)+A.B.C.D
    And the equation for sampling across 5 samples would be:
    Z’ = Z(A+B+C+D+E)+A.B.C.D.E

A sample C routine is listed below (please excuse the formatting):
int debounce(int SampleA)
static int SampleB = 0;
static int SampleC = 0;
static int LastDebounceResult = 0;

LastDebounceResult = LastDebounceResult & (SampleA | SampleB | SampleC)
| (SampleA & SampleB & SampleC);
SampleC = SampleB;
SampleB = SampleA;
return LastDebounceResult;