Microcontroller - A Beginners Guide - Button Debouncing Through Software
Ok, so now your saying to yourself, we JUST went over debouncing, and it seemed
to work fine... Why go deeper into this subject?!? Well, basically, software debouncing,
if the program space and microcontroller cycles will allow it, is essentially free.
It's just a few lines of code, and you can provide much more control of how the
debouncing methods work with the particular button you are using. Debouncing in
hardware may add a cost to each board that is developed, and it is more difficult
to determine a good debouncing for all the push button switches that will be used.
However, if you want to preserve program execution cycles, it's best to go the hardware
route.
My method of debouncing with software uses only two variables that measure the confidence
level of the actual button press. With the help of the Pressed variable introduced
in the Button Debouncing, there will be a stream of 1's when the button is pressed,
and a stream of 0's when the button is released. If there is bouncing going on,
the stream of 1's or 0's will be very short, so we can take advantage of this by
introducing two variables that measure the length of these streams. The variables
are called, Pressed_Confidence_Level, to measure the button's pressed state, and
Released_Confidence_Level to measure the button's released state.
So, if the button is pressed, the Pressed_Confidence_Level will rise, and the same
with Released_Confidence_Level when the button is released. But, these variables
will also become reset to 0 if the opposite condition exists. For instance, say
the button was pressed for a time and the Pressed_Confidence_Level became a very
large number, like 153,356. If the button was released (or a bouncing happened),
the variable would be reset to 0. The trick to these variables is to determine a
good threshold to determine a good button press or release state. Say, if the Pressed_Confidence_Level
shows that after rising to 500, that this number s a strong indication of a button
press, then the LEDs will toggle once. The same goes for the Released_Confidence_Level
because bouncing could also happen on a button release. So, let's see how we do
this in code:
int main(void)
{
DDRB |= 1 << PINB0; //For Notes on what these actions mean
PORTB ^= 1 << PINB0;
DDRB |= 1 << PINB2;
DDRB &= ~(1 << PINB1);
PORTB |= 1 << PINB1;
int Pressed = 0;
int Pressed_Confidence_Level = 0; //Measure button press cofidence
int Released_Confidence_Level = 0; //Measure button release confidence
while (1)
{
if (bit_is_clear(PINB, 1))
{
Pressed_Confidence_Level ++; //Increase Pressed Conficence
Released_Confidence_Level = 0; //Reset released button confidence since there is a button press
if (Pressed_Confidence_Level >500) //Indicator of good button press
{
if (Pressed == 0)
{
PORTB ^= 1 << PINB0;
PORTB ^= 1 << PINB2;
Pressed = 1;
}
//Zero it so a new pressed condition can be evaluated
Pressed_Confidence_Level = 0;
}
}
else
{
Released_Confidence_Level ++; //This works just like the pressed
Pressed_Confidence_Level = 0; //Reset pressed button confidence since the button is released
if (Released_Confidence_Level >500
{
Pressed = 0;
Released_Confidence_Level = 0;
}
}
}
}