Saturday, May 31, 2014

eRCaGuy_ButtonReader Library for Arduino - Debounce and read the current button state, & most recent action ("just pressed" or "just released") easily!


Subscribe by Email! (via FeedBurner)
By Gabriel Staples
Written: 31 May 2014
Last Updated: 25 July 2015
Article History (newest on top)
-added button image & updated download links - 25 July 2015

Other Articles to Check Out:
This Article:

Library History (newest on top):

20141031: major bug fix; added multi-button support with a new 5-button-reader example!
20140531: first release.
Misc. push buttons which can greatly
benefit from digital debouncing. 
(Image source here).


I wanted a simple and universal, yet very powerful & reliable library to read a button or switch in such a way that I can easily implement toggled actions and momentary actions, know the true, debounced state of a button or switch at any given time, and specify whether I want an action to take place when the button is *pressed* or *released.* This library makes implementing all of these things easy for me, and I now use it on all of my projects that require reading a button or switch, so I wanted to share it with others. Hopefully you find it useful too. Check out the included examples.  

This code is an elaboration of, and library form of, the main Arduino-sponsored "Debounce" example found here.  Thanks to David A. Mellis, Limor Fried (LadyAda), and Mike Walters for writing that excellent and well-thought-out example code.

Download the eRCaGuy_ButtonReader Library from Gumroad by clicking here --> Type in the maximum amount you are willing to pay in the box where it says, "Name a fair price," then click the "I Want This!" button. Next, you must enter your email so you can get a receipt with download and support links. What is Gumroad? Gumroad is a secured 3rd party file hosting service; see Wikipedia here for more info. Though you certainly may enter $0 to get my download for free, I'd appreciate any donation you make to help keep my projects open source. Install the library into the Arduino IDE (using Sketch --> Import Library --> Add Library), then run the examples to see how to use the library.

List of Functions (see .h and .cpp files in the library for details):

  • eRCaGuy_ButtonReader(uint8_t buttonPin,unsigned int debounceDelay,boolean pinStateWhenButtonPressed) //class constructor
  • setDebounceDelay(unsigned int debounceDelay)
  • setButtonPin(uint8_t buttonPin)
  • setPinStateWhenButtonPressed(boolean pinStateWhenButtonPressed)
  • getDebounceDelay()
  • readButton(int8_t* button_action, boolean* button_state)

Example code:

-This code differs from readButton.ino ONLY in that it also outputs the button status every 0.5 seconds; rather than just outputting the button status when a 
 button *press* or *release* is detected.
eRCaGuy_ButtonReader example
By Gabriel Staples
30 May 2014

Library webpage:
-I wanted a simple and universal, yet very powerful & reliable library to read a button or switch in such a way that I can
 easily implement toggled actions and momentary actions, know the true, debounced state of a button or switch at any given time, 
 and specify whether I want an action to take place when the button is *pressed* or *released.*  This library makes implementing all of
 these things easy for me, and I now use it on all of my projects that require reading a button or switch, so I wanted to share it with others.  
 Hopefully you find it useful too.
License for Library and Examples: GNU Lesser General Public License Version 3 (LGPLv3) -
-See library .h and .cpp files for details

-This example will print out data to the Serial Monitor either: 
 1) every time the button is pressed, or released, OR
 2) every 1/2 second that the button remains in its current state
 --it will also toggle LED 13 every time a button press is detected

-Connect a button from digital pin 5 to GND
--the internal pull-up resistor is enabled on pin 5 to protect the pin from over-current

Upload the code, open the serial monitor, and play around pressing, releasing, and holding down the button, to see what happens!

//include the library
#include <eRCaGuy_ButtonReader.h>

//Global Constants:
const byte buttonPin = 5; //the number of the pushbutton pin
const byte ledPin = 13; // the number of the LED pin
//Define Button States:
const boolean BUTTON_PRESSED = LOW; //if using a pull-up resistor (ex: INPUT_PULLUP) on your button, the buttonPin will be LOW when the button is pressed; 
const boolean BUTTON_NOT_PRESSED = HIGH; //if using a pull-up resistor (ex: INPUT_PULLUP) on your button, the buttonPin will be HIGH when the button is NOT pressed

//instantiate an object of this library class; call it "button1"
//if not explicitly stated, debounceDelay defaults to 50ms, and the _BUTTON_PRESSED value in the library defaults to LOW; see .h file for details
eRCaGuy_ButtonReader button1 = eRCaGuy_ButtonReader(buttonPin); 
//alternatively, the object instantiation could be explicit, as follows:
//eRCaGuy_ButtonReader button1 = eRCaGuy_ButtonReader(buttonPin,50,BUTTON_PRESSED);

void setup() 
  //configure pins
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  // set initial LED state to OFF
  //configure button1
  //button1.setDebounceDelay(50); //(optional); set debounceDelay to 50ms; uncomment this and increase the debounceDelay if the button_state jitters unexpectedly
  //button1.setButtonPin(buttonPin); //(optional), since this was established during the object instantiation above
  //button1.setPinStateWhenButtonPressed(HIGH); //uncomment this line if using a pull-down resistor on the button or switch instead of the internal pull-up resistor

void loop() 
  //local variables
  int8_t button_action; //see details below
  boolean button_state; //see details below
  //read button; use the ampersands (&) to pass the address to (pointers to) the variables as input parameters, so that the variables can be updated by the function
    //read the button action, and store it into the button_action variable; and read the button state, & store it into the button_state variable
    //The button state can be 0 or 1, for LOW or HIGH, respectively
    // button action indicates what just happened to the button: 
    // 0 = no-change in true, debounced button state since last time reading the button, or debounceDelay time not yet elapsed
    // 1 = button was just pressed by a human operator (debounceDelay had elapsed)
    // -1 = button was just released by a human operator (debounceDelay had elapsed)
  //output data, & toggle LED
  if (button_action != 0) //if an action has occured on the button
    Serial.print("button_action = "); Serial.print(button_action); Serial.print(", "); 
    if (button_action==1)
      Serial.print("Button PRESS detected");
    else //button_action==-1
      Serial.print("Button RELEASE detected");
    Serial.print("; button_state = "); Serial.print(button_state); 
    Serial.print(", "); 
    if (button_state==BUTTON_PRESSED)
    else //button_state==BUTTON_NOT_PRESSED
    //toggle the led on every button press
    if (button_action==1) //if button just pressed
      toggleLED(); //turn the LED on if off, and off if on
    //alternately, you could comment out the above if statement, and use this one below instead, if you desire to do an action on the *release* of the button
    //instead of on the *press* of the button
//    if (button_action==-1) //if button just released 
//    {
//      toggleLED(); //turn the LED on if off, and off if on
//    }
  //THE BELOW SEGMENT OF CODE (else statement) IS COMMENTED OUT FOR readButton.ino, but NOT for readButtonVerbose.ino
  else //button_action==0
    //if there is no new action on the button, let's print out the button_state every 0.5 seconds, to see whether the button is currently NOT being pressed, 
    //or whether it is being held down continuously
    static unsigned long t_start = millis(); //ms; a time stamp to ensure printouts only happen every 0.5 seconds
    if (millis() - t_start >= 500) //if 500ms (0.5 sec) has elapsed
      t_start = millis(); //ms; update
      if (button_state==BUTTON_PRESSED)
        Serial.println("button is being held down");
      else //button_state==BUTTON_NOT_PRESSED
        Serial.println("button is just sitting there, NOT pressed");
} //end of loop()

//Here you will do something useful, determined by the press or release of the button; I am simply toggling led 13 on and off in order 
//to demonstrate one use of a button as a toggle switch
void toggleLED()
  static boolean ledState = HIGH;
  ledState = !ledState; //invert led state
  digitalWrite(ledPin, ledState); //write to led

***Subscribe by Email! (via FeedBurner)***


  1. This comment has been removed by a blog administrator.

    1. SPAM IS NOT TOLERATED. You have been reported to Google+. Hopefully your account is deleted soon.


Thanks for your comment or question! If it is a question, I will try to get back to you quickly.

Note: some HTML tags are allowed in your comments. To learn how to add bold (<b>...</b>), italics (<i>...</i>), or hyperlinks (<a href="URL">NAME</a>) to your comments, read here.

~Sincerely, Gabriel Staples.

P.S. Yo hablo español también. Je parle français aussi. (I speak Spanish & French too).