[ Log In ]
thumbnail: 8 channel logic analyzer - iLogic

4 Channel Logic Analyzer

Thumbnail: quad buffer line driver 74HC126E

Quad Buffer Line Driver (Through Hole)

Image of the Atmega324p


Serial to USB converter with Micro USB cable

USB to Serial Converter

Thumbnail: Crystal Oscillator 18.432 MHz for UART

18.432 MHz Crystal Oscillator 18pf 30ppm

Thumbnail: 22 pF Capacitor

22 pF Multilayer Ceramic Capacitor

Thumbnail: Quartz crystal oscillator - 16 MHz

16 MHz Crystal Oscillator 20 pF Through Hole

Thumbnail: 4x4 keypad top view.

4x4 Keypad with Adhesive Backing

USB AVR programmer

USB AVR Programmer

3 pin slide switch

SPDT Slide Switch 3 pin 30V

Skip Navigation Links

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;
//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.