Mechanical switches do not make or break a connection cleanly due to microscopic conditions on the contact surface. This is referred to as “Switch Bounce” and can cause problems in digital circuits. In this tutorial we will build a circuit that demonstrates this problem, then modify it slightly to resolve it.
We will be reusing the circuit from the ATmega8 breadboard circuit tutorial. The schematic is shown below.
Next we write and upload some code to the microcontroller. This program waits for you to press a button, then records how many times you press
that button until it senses a quiet period. At this point it flashes the LED for as many times as button presses were recorded.
-
-
#include <avr/io.h>
-
#include <util/delay.h>
-
-
-
//Define functions
-
//======================
-
void ioinit(void);
-
void led_on(void);
-
void led_off(void);
-
//======================
-
-
int main (void)
-
{
-
ioinit(); //Setup IO pins and defaults
-
-
while (1)
-
{
-
int num_presses; //Number of times button has been iterations
-
int num_nopress_iterations; //Number of loop iterations since last button press
-
char button_state; //1=pressed, 0=not pressed
-
-
//Wait for button to be pressed
-
while (!bit_is_clear(PINC, 5)) {}
-
num_presses=1;
-
button_state=1;
-
-
while (1)
-
{
-
if (bit_is_clear(PINC, 5)) //button is pressed
-
{
-
if (button_state==0) //was previously not pressed)
-
{
-
num_presses++;
-
}
-
button_state=1;
-
}
-
else //button is not pressed
-
{
-
if (button_state==1) //was previously pressed
-
{
-
num_nopress_iterations=0;
-
}
-
num_nopress_iterations++;
-
button_state=0;
-
if (num_nopress_iterations>20000) //If we haven’t seen a button press for a while, terminate the loop
-
{
-
break;
-
}
-
}
-
}
-
-
for (int i=0;i<num_presses;i++)
-
{
-
led_on();
-
_delay_ms(300);
-
led_off();
-
_delay_ms(300);
-
}
-
-
if (bit_is_clear(PINC, 5))
-
{
-
}
-
}
-
}
-
-
-
void ioinit (void)
-
{
-
DDRC = 0b11011111; //1 = output, 0 = input
-
PORTC = 0b00100000; //Enable pin 5 internal pullup
-
}
-
-
void led_on(void)
-
{
-
PORTC |= _BV(PC4);
-
}
-
-
void led_off(void)
-
{
-
PORTC &= ~_BV(PC4);
-
}
-
When you run the program and press the button, you will often notice the LED blinking too many times. This is due to the button bounce.
The figure below shows how we normally think a button press looks like.
Whereas this one is closer to the truth (even this one is a bit too clean and elegant)
Fixing the problem is very easy. All you need to do is add a capacitor. I used a 100nF capacitor, but experiment with what works best for you.
Note: The problem isn’t too pronounced on a breadboard as it has a lot of natural capacitance. On a PCB the problem is much more severe.
Related posts:

Feed









Comments