7

I need debouncing/stateChange for a push button configuration. Is there a good library for debouncing/stateChange buttons in Arduino (without delay)?

3
  • 1
    I usually check the button state every few milliseconds, and store the state in an array. Next I check if the stored values are all HIGH or all LOW.
    – Gerben
    Mar 16 '15 at 20:01
  • 3
    "Best", especially without offerimg any (or enough) criteria, would elicit entirely subjective answers and so is not a good fit for stackexchange.com. If you can re-word your question make it more objective, it will get more useful results (not to mention, it will remain open!)
    – JRobert
    Mar 22 '15 at 17:35
  • There is no such thing as debouncing without delay. Some small amount of delay by definition needs to be introduced for the input system to be sure that the event is not a false positive.
    – Reinderien
    Jan 20 at 0:13
7

The Button library in the Arduino playground works perfectly.

2
  • 1
    This library is great! BUTTTT dosn't work with the ESP8266 because meanwhile the Arduino has an internal Pull-up resistor the ESP doesn't (in all pins)!!!
    – k.Cyborg
    Aug 28 '18 at 13:15
  • This link is now broken
    – m3z
    Jan 2 '20 at 2:13
5

I think what you need is an interrupt-based detection of the button. This way, your Arduino can do what it needs to do without stalling for the delay function.

// Example code usage

int pin = 13; // LED on board
int interrupt0pin = 2; // pin attached to int0 if you're using Uno
int buttonState;

void setup()
{
  pinMode(pin, OUTPUT);
  pinMode(interrupt0pin, INPUT);
  attachInterrupt(0, buttonUpdate, CHANGE); // calls buttonUpdate() when button input changes (you can also use high-to-low or low-to-high)
}

void loop()
{
    if (buttonState)
        digitalWrite(pin, HIGH);
    else
        digitalWrite(pin, LOW);
}

void buttonUpdate()
{
  buttonState = digitalRead(interrupt0pin);
  delay(50); // 50ms works for most switches - adjustable
}

Find out more here: http://arduino.cc/en/Reference/AttachInterrupt

Good luck!

2

You can use my library

https://github.com/anlgncr/Buttons

This library lets you use buttons as many as you wish with only one instance of class.

You can also call a function when button is pushed or released.

2

I'm on this subject right now and I'll use this to note my findings.

I found many libs on this, and this is my wishlist:

  • support many buttons
  • support toggles or switches
  • support debouncing and maybe de-glitching
  • non-blocking functions
  • support long-press, double-click

Candidates:

Here are my findings for each lib:

Switch

  • it's really easy to use
  • you can use it as a switch or a button, same class handles both
  • supports callbacks
  • supports many buttons
  • supports debouncing and de-glitching
  • supports double click and long press
  • most configs have defaults, and you define them at the Button setup
  • as I use PlatformIO, some warnings from this lib are shown while compiling my project

EasyButton

  • it's really easy to use
  • very good docs
  • supports callbacks
  • supports many buttons
  • does not support toggles/switches, although you can simulate it by checking the wasPressed and wasReleased properties
  • supports debouncing
  • supports double click, triple click, or a given number of clicks
  • you may have a different action for single, double or triple click for the same button
  • supports multiple times of long press, if needed
  • most configs have defaults, and you define them at the Button setup

JC Button

  • easy to use, not as easy as Switch and EasyButton tough
  • you can use it as a Button or a switch (ToggleButton), different class for each
  • supports many buttons
  • does not support callbacks
  • supports debouncing
  • supports multiple times of long press, if needed
  • most configs have defaults, and you may define them at the Button setup, but long press time is something you define while querying it's status rather than defining it once at the button setup

ezButton

  • easy to use, not as easy as Switch and EasyButton tough
  • supports many buttons
  • does not support toggles/switches, although you can simulate it by checking the isPressed and isReleased events
  • does not support long press
  • does not support callbacks
  • supports debouncing, does not debounce by default (you must call setDebounceTime on setup)
  • supports an easy way to count button clicks

Veredict

I chose avdweb/Switch. Reasons:

  • in terms of debouncing AND de-glitching, it did better according to my tests
  • I need a solution for Buttons and Switches, and it provides them in the same class
1

I can receommend the following library:

http://log.liminastudio.com/itp/physical-computing/arduino-a-new-improved-button-library-with-some-handy-features https://github.com/virgildisgr4ce/Button

On the website you will find some examples on how to use it. I have implemented this library already in several sketches and it works very reliably.

1

You can put a capacitor in parallel with the switch - 100nf should do the trick. Some capacitors have a minus on the packaging, next to one of the pins - if so, make sure that side is to negative (ground).

1

I put this together for a guy the other day. Its not a library but it achieves reading and debouncing all of your buttons and works very well maybe it could help you

const byte numbuttons = 15;                                                     // DEFINE HOW MAY DIGITAL INPUTS TO MONITOR(NUMBER OF BELOW PINS TO USE)
const byte digitalpin[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16 };   // DECLARE ALL DIGITAL INPUT PINS WHICH CAN BE USED IN THE ORDER IN WHICH THEY WILL BE PHYSICALLY USED(DONT INCLUDE ANY PINS USED FOR OTHER THINGS
const byte debouncetime = 50;                                                   // THIS VALUE IS THE TIME TO WAIT BEFORE RECHECKING (FOR DEBOUNCE
byte readstate[numbuttons];                                                     // READ ARRAY
byte laststate[numbuttons];                                                     // HOLDS THE BUTTON LAST STATE FOR STATE CHANGE DETECTION
byte NumBut;                                                                     // THIS IS THE VARIABLE FOR DIGITAL FORLOOP COUNTER
unsigned long checktime;                                            // RECORDS THE TIMES (IN MILLIS() TO RECHECK THE STATE FOR EACH BUTTON. FOR DEBOUCING

byte CURRENT_SETTING;
void setup() {

  // SET INITIAL STATES FOR DIGITALS
  for (NumBut = 0; NumBut < numbuttons; NumBut++) {
    pinMode(digitalpin[NumBut], INPUT_PULLUP);
    laststate[NumBut] = digitalRead (digitalpin[NumBut]);
    checktime = 0;
  }
}

void loop() {
  //call the read button method
  READBUTTONS();
  PROGRAM_OUTPUT();
}

void READBUTTONS() {
  for (NumBut = 0; NumBut < numbuttons; NumBut++) {

    readstate[NumBut] = (digitalRead (digitalpin[NumBut]));                                                                   // READ DIGITAL INPUTS INTO ARRAY

    if (readstate[NumBut] != laststate[NumBut] && millis() >= checktime )   {
      if (readstate[NumBut] == 0 && laststate[NumBut] == 1) {
        checktime = millis() + debouncetime;
        CURRENT_SETTING = NumBut;
      }
      laststate[NumBut] = readstate[NumBut];
    }
  }
}

void PROGRAM_OUTPUT(){
    switch ( CURRENT_SETTING ) {
    case 0:   //do something to turn off output break;
    case 1:   //do something with setting 1 break;
    case 2:   //do something with setting 2 break;
    case 3:   //do something with setting 3 break;
    default:    break;
}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.