Microcontroller - A Beginners Guide - Understanding Button Debouncing
Let's study button debouncing in a little more detail. The importance of button
debouncing should not be overlooked. Button switches are one of the many ways that
humans can provide input to the microcontroller. When a button is pressed, the human
will expect a reaction in some form, say an LED toggling, a menu on an LCD (moving
from one menu item to another), a motion controlled device (moving and stopping),
etc. If a button is not debounced in some way, the human may get quite frustrated.
Button debouncing can cause multiple false button presses. Imagine using a button
in the selection of a menu item. The button not being debounced, one click can cause
the menu to skip one or more menu items. Even worse, when trying to select a particular
item, and it continually skips when either button is toggled, making a particular
selection to be made.
To demonstrate this phenomenon, this project will contain two LEDs. When a button
is pressed, the LEDs will toggle between each other. A button press will turn one
off, and the other on. When the button is released, it can start this process again
and cause the LEDs to toggle again, once the button is pressed. You will notice
that the LEDs will toggle twice, or even more times with only one button press.
I will show two ways to eliminate debouncing. The in-circuit method (hardware) using
a capacitor, and software debouncing. The hardware will simply use a capacitor to
eliminate debouncing, and the software will introduce a variable that measures the
confidence level of the button stream of ones, or zeros. Disclaimer: the method
that I use for hardware debouncing is a very simple and poor mans method. The main
problem with this method is that the voltage climbs from 0 to 5v rather than an
immediate, or instantaneous change. This can put the signal in a range that the
microcontroller does not know how to deal with the voltage. This range is the area
between the thresholds of high and low signals, which is between 2 and 3 volts.
With this said, I have not personally seen any problem with this with my button
debouncing. If you would like to eliminate this climbing, use a schmitt trigger.
In the video, the circuit is connected together on the breadboard without the hardware
debouncing, so the problem can be experienced. Two LEDs are connected to the microcontroller,
both on port B, one on pin 0 and the other on pin 2. both of these pins will be
set to output and since the LEDs are green, a 330 ohm resistor is used for each
LED. The button switch is connected to pin 1, on port B. This pin will be set for
input and set to read high (pin set to a "1"). for the first "bounce" test, we will
not use a capacitor across the two leads of the button.
The program to make two LEDs toggle when the push button is pressed is very simple.
First, the pins are initialized: Pins outputting to the LEDs are set to output in
the DDR (Data Direction Register). One of the LEDs are toggled high, so at the start,
one is on and one is off. Then, the never ending loop is started and the code within
that block gets executed until the microcontroller loses power. Withing this loop,
the pin that is connected to the push button is constantly checked to determine
if it is on. If it is pressed, and exhibits a 1, then it checks if the button was
firsts released. This is important, because if we don't have this check, the button
will just toggle continuously while the button is pressed. We only want the button
to toggle if the button is pressed and then released.
#include <avr/io.h>
int main(void)
{
DDRB |= 1 << PINB0; //Set Direction for output on PINB0
PORTB ^= 1 << PINB0; //Toggling only Pin 0 on port b
DDRB |= 1 << PINB2; //Set Direction for Output on PINB2
DDRB &= ~(1 << PINB1); //Data Direction Register input PINB1
PORTB |= 1 << PINB1; //Set PINB1 to a high reading
int Pressed = 0; //Initialize/Declare the Pressed variable
while (1)
{
if (bit_is_clear(PINB, 1)) //Check is the button is pressed
{
//Make sure that the button was released first
if (Pressed == 0)
{
PORTB ^= 1 << PINB0; //Toggle LED in pin 0
PORTB ^= 1 << PINB2; //Toggle LED on pin 2
Pressed = 1;
}
}
else
{
//This code executes when the button is not pressed.
Pressed = 0;
}
}
}
So, when the microcontroller is programmed, and the button is pressed several times,
it is evident that the LEDs will toggle, sometimes correctly, and sometimes will
toggle multiple times with only one button press. Add the capacitor and check the
button pressing and LED toggling again. On the ocilliscope, with the capacitor installed,
a gradual rise of the voltage is created when the button is pressed, opposed to
a bunch of up and down voltages resulting from a bounce from the mechanical parts
of the button. But when the button is released, it shows that the voltage is a direct
change. This is because another capacitor is not installed between the button and
the microcontroller.
Next, the software debounce method
is investigated.