Switch debounce

Switch bounce is non-ideal behavior of the contacts that creates multiple electrical transitions for a single button push or release.

One of approaches to handle the switch bouncing is to check button status (on/off) every 10 to 20 ms and store the stati in a byte variable. This variable is updated in a shift register after every button status check. The old variable value is shifter right on 1 bit, and the new bit is inserted as bit7. The bit value is 1 is button is off and 0 otherwise.

We accept the new button state as "ON" if the button press was detected for at least two last checkings. In other terms, the variable value is of the form 00xxxxxx, where x are the remaining bits in the shift register. This way we introduce a constant press_threshold = 0x3F. Therefore, once the shift register value after the next check becomes less than press_threshold or equal to it, we set the new button status as "ON" (and "OFF" otherwise).

Similarly the debouncing can be performed when the button is released. It turns out that tactile buttons bounce more when they are released compared to pressing them. We address this situation by waiting for the button to be released for at least 6 last checkings. That is, the value in the shift register must be not less than release_threshold = 11111100 = 0xFC.

Putting all together, every button is assigned with a separate shift register shift_reg and a binary variable state indicating its state (1 = "OFF", o = "ON"). The debouncing algorithm pseudocode becomes as follows:

1. press = current button state  // 1="OFF" 0="ON"
2. shift_reg = (shift_reg >> 1) + (press << 8)
3. if (state == "OFF")           // check old state
   {
     if (shift_reg <= press_threshold)
     {
       state = "ON"              // new state
       perform needed tasks      // button press is detected
     }
   }
   else                           // old state is "ON" 
   {
     if (shift_reg >= release_threshold)
     {                            // button release is detected
       state = "OFF"              // just update button state
                                  // usually do nothing else here
     } 
   }