In this project, we will write a software sketch to identify and correct the effects of button bounce on the chipKIT⢠microcontroller boards.
In this project, when the button is pressed the LED shines and the computer receives the number of times the button has been pressed.
For this project, we will use a resistor and a capacitor to debounce a circuit.
Create a more complex and sophisticated button circuit that will activate when pressed with the right amount of force.
In Debouncing via Software, we introduced the concept of debouncing a button was introduced, but we had to explicitly program the debounce. In this project, the Bounce library will be used to debounce the input from a button. Just like in Debouncing via Software, this project will use a single button and LED, and it will count the number of times the button has been pressed and display the result through the serial monitor. This project will use a library to debounce rather than manually coding or using a hardware solution.
Qty | Description | Typical Image | Schematic Symbol | Breadboard Image |
---|---|---|---|---|
1 | Button | ![]() |
||
2 | 10 kΩ resistor | ![]() |
||
1 | LED | ![]() |
The circuit for this project is the same as the one used in Debouncing via Software, but instead of the full breadboard, this project will use a mini breadboard and pins 7 and 8. Other than these minor differences the result should be the exact same as in Debouncing via Software, when the button is pressed the LED shines and the computer receives the number of times the button has been pressed.
What is a library in programming? Why do we need them? A library is simply a collection of functions and classes that are used to make a task or collection of tasks easier to deal with. The Bounce library, which we'll be using for this project, is a library to make debouncing a button or switch as easy as calling digitalRead(). Debouncing using a library is conceptually the same as debouncing via software, but the debouncing code is inside the Bounce class instead of inside the loop function.
The bounce library can be found at http://playground.arduino.cc/code/bounce. Once the library has been downloaded, unzip the folder that was just downloaded. Then place the resulting folder in the libraries folder of your sketchbook. If you do not know where this is, it can be found by going to FILE->preferences and looking at the Sketchbook location. Alternatively, hitting Ctrl+comma(,) takes you to the same screen. Figure 2 should be the window that opens and the sketchbook location will be at the top of that window.
The screenshots above are of MPIDE running on Microsoft Windows 7.
Now that you know where the location of your sketchbook in MPIDE, navigate to it and you'll see a bunch of folders with the same names as the various projects you've saved in the computer. To install a library, since this is going to be the first library you have installed, you will need to make a folder called libraries, which will hold the user installed “Libraries,”. So, now that we have a location to install the bounce library, copy the unzipped bounce folder and paste it into the newly created “Libraries” folder. You can check to see if the library was installed by starting (or restarting if already open) MPIDE, selecting Sketch->Import Library, and look towards the bottom of that menu for Bounce. It should be under “Contributed”, which simply means that it was added by the user and not included by default. Figure 3 is the window you should see if the library was installed correctly. Also, this is the same process to import a library into a sketch, except that you would click on the library name to do so.
When you click on the Bounce library in the import library menu, you should see #include <Bounce> at the top of your sketch. What this means is that when the sketch is verified/compiled, it will include the Bounce library.
Well, we've included the Bounce library, but what does that mean? What is a library? A library is simply a collection of functions and classes that are used to make a task or collection of tasks easier to deal with. The Bounce library is a library to make debouncing a button or switch as easy as calling digitalRead(). The concept is the same as in Software Debouncing project, but with the debouncing code inside the Bounce class instead of the loop function.
We will be using four methods in the Bounce class to accomplish what was done in Software Debouncing project. The first method is the constructor for the Bounce class, which is used to initialize the class. The second method is the update method, which contains the debouncing code that was in Debouncing via Software. The third method is the read method, which simply returns the value of the pin from the last update. The final method is the risingEdge method, which returns a true if the pin had a rising edge during the last update and a false otherwise.
The Bounce class does not have a default constructor, which prevents initialization of a variable without any inputs. It only has a copy constructor and a constructor that requires two inputs, a pin to debounce and the time to delay. Because of this, when we initialize the class, we have to include the pin and debounce delay that we want to use. An explicit example of what will work and what won't work may be helpful:
// This won't compile/give errors.
Bounce failToBounce;
// This will compile by using the two input constructor.
Bounce simple(2, 50);
/* This is a java style initialization of a class.
* This uses both the copy constructor (the = sign),
* And the two input constructor.
*/
Bounce javaBounce = Bounce(2, 50);
The update method is the most important method in this class, in addition to the constructor method. This method contains the logic that is used to debounce the button or switch. It returns true if the state has changed and false if the state hasn't changed. This method is the main reason to use the Bounce library. Instead of using two blocks of code at the beginning and end of the loop() function with the functional code in the middle of those two blocks of code. We can now just call the update() method and the rest of the code in the loop() function can be functional and focused on what you are trying to do instead of worrying about debouncing the button.
The read method simply returns the state of the pin determined from the last time the update method was called. This is presented in contrast to the code in Debouncing via Software where two button state variables and two time state variables were required to read the button without any bounce.
The rising edge method is used to determine if the button's state is going from LOW to HIGH. Previously (in Debouncing via Software), the LED state was used to determine if a rising edge occurred. The rising edge method simply checks if the current state is HIGH and if there was a change during the last update.
We have five global variables that will be used in the sketch. The first two variables are simply the pins for the button and the LED. We are making them global because we want access to them in both the setup() and loop() function. They are const because the pins won't change during the program. We will call these variables “btnPinGlb” and “ledPinGlb” where the PinGlb part simply means that the variable represents a pin and that it is a global variable (all functions can use it).
The next variable is the amount to delay for the button debouncing. This variable is const unsigned int because we won't change the delay in the debounce and a negative delay makes no sense. This variable will be called debounceDelayGlb. See Debouncing via Software for more information on why we need a debounce delay.
The next variable is the count of the times the button has been pressed. It is an unsigned int since there can't be negative button presses. The name of this variable will be countGlb because it is a global variable. The final variable is actually a class object (a variable that is a class), and that is the Bounce class. Due to how the Bounce class does not have a default constructor, it requires two inputs: the pin to debounce and the time to delay for debouncing. We will just call the variable bouncerGlb because it is a global variable. However, to create this variable with the inputs it requires, we must treat it like we would a function. Observe the following code on how to create this variable:
Bounce bouncerGlb(btnPinGlb, debounceDelayGlb);
As you can see in the code, we use the pin which the button is connected to and the debounce delay. We insert them into the Bounce class variable as if it were a function to initialize it with the values of btnPinGlb and debounceDelayGlb.
The setup() function in this project is fairly straightforward. All we have to do is set the pin modes and start serial communications. The button will obviously be INPUT and the LED will be OUTPUT. Observe how we define the setup() function:
void setup()
{
pinMode(btnPinGlb, INPUT);
pinMode(ledPibGlb, OUTPUT);
Serial.begin(9600);
}
The first thing to do in the loop() function is to update the state of the button. This is done by simply using the update() method on the variable bouncerGlb. This will take care of the button debounce. The next thing is to create an integer and set it to the current button state. So we will call this variable “currentBtnState.” To get the current button state we use the read() method on the variable bouncerGlb. We then have an if statement where we use the risingEdge() mode on bouncerGlb to determine whether we increment countGlb and sent the result to the computer. We then end the loop() function by writing the state of the button to the LED. The loop() should look something like this:
void loop()
{
bouncerGlb.update();
int currentBtnState = bouncerGlb.read();
if(bouncerGlb.risingEdge()){
countGlb++;
Serial.println(countGlb);
}
digitalWrite(ledPin, currentBtnState);
}
Now we have all of the information we need to debounce a button using the bounce library. The code for our sketch should look something like this:
#include <Bounce.h>
// Define variables for the pins we are using.
const int btnPinGlb = 7;
const int ledPinGlb = 8;
// Used for the initialization of the Bounce class.
const unsigned int debounceDelayGlb = 50;
// Times the button has been pressed.
unsigned int countGlb = 0;
/* Initialize the Bounce class on pin 7 (btnPin) with
* a delay of 50 (debounceDelayGlb)
*/
Bounce bouncerGlb(btnPinGlb,debounceDelayGlb);
void setup()
{
// Set the button to INPUT and LED to OUTPUT
pinMode(btnPinGlb,INPUT);
pinMode(ledPinGlb,OUTPUT);
// Start Serial communications.
Serial.begin(9600);
}
void loop()
{
// Update the bounce class.
bouncerGlb.update();
// Get current button state from the bounce class.
int currentBtnState = bouncerGlb.read();
// If there is a rising edge, increment count and send it to the computer.
if(bouncerGlb.risingEdge()){
countGlb++;
Serial.println(countGlb);
}
// Write the current button state to the LED.
digitalWrite(ledPinGlb, currentBtnState);
}