Arduino: Working with “Bouncy” Buttons

Posted by Unknown on Friday, July 11, 2014 with No comments
When was the last time you had to hold a button down to keep a light on?
Probably never. It makes more sense to be able to click the button once to turn it
on and to click the button again to turn it off. This way, you do not have to hold
the button down to keep the light on. Unfortunately, this is not quite as easy as
you might first guess. You cannot just look for the value of the switch to change
from low to high; you need to worry about a phenomenon called switch bouncing.
Buttons are mechanical devices that operate as a spring-damper system. In
other words, when you push a button down, the signal you read does not just
go from low to high, it bounces up and down between those two states for a
few milliseconds before it settles.


The button is physically pressed at the 25ms mark. You would expect the
button state to be immediately read as a high logic level as the graph on the left
shows. However, the button actually bounces up and down before settling, as
the graph on the right shows.

If you know that the switch is going to do this, it is relatively straightforward
to deal with it in software. Next, you write switch-debouncing software that
looks for a button state change, waits for the bouncing to finish, and then reads
the switch state again. This program logic can be expressed as follows:

1.  Store a previous button state and a current button state (initialized
to LOW).
2.  Read the current button state.
3.  If the current button state differs from the previous button state, wait 5ms
because the button must have changed state.
4.  After 5ms, reread the button state and use that as the current button state.
5.  If the previous button state was low, and the current button state is high,
toggle the LED state.
6.  Set the previous button state to the current button state.
7.  Return to step 2

Within the program flow (listed in the preceding steps) is a series of repeating steps that need to be applied to changing variable values. Because you’ll want to repeatedly debounce the switch value, it’s useful to define the steps for debouncing as a function that can be called each time. This function will accept the previous button state as an input and outputs the current debounced button
state. The following program accomplishes the preceding steps and switches the LED state every time the button is pressed.

Sketch:
const int LED=9; //The LED is connected to pin 9
const int BUTTON=2; //The Button is connected to pin 2
boolean lastButton = LOW; //Variable containing the previous
//button state
boolean currentButton = LOW; //Variable containing the current
//button state
boolean ledOn = false; //The present state of the LED (on/off)
void setup()
{
pinMode (LED, OUTPUT); //Set the LED pin as an output
pinMode (BUTTON, INPUT); //Set button as input (not required)
}
/*
* Debouncing Function
* Pass it the previous button state,
* and get back the current debounced button state.
*/
boolean debounce(boolean last)
{
boolean current = digitalRead(BUTTON); //Read the button state
if (last != current) //if it's different…
{
delay(5); //wait 5ms
current = digitalRead(BUTTON); //read it again
return current; //return the current value
}
void loop()
{
currentButton = debounce(lastButton); //read deboucned state
if (lastButton == LOW && currentButton == HIGH) //if it was pressed...
{
ledOn = !ledOn; //toggle the LED value
}
lastButton = currentButton; //reset button value
digitalWrite(LED, ledOn); //change the LED state
}
Categories: