[button library] : bounce / programming error or misunderstanding of the library

Hi,

I'm trying to implement a sample code with 2 buttons. Button A is a counter and button B is a starter. When B is pressed, a led blinks as many time button A was pressed. It sounds easy but my code has a strange behavior.

I placed on the breadboard just 2 buttons. No resistor. And one red led with a 220 ohms resistor.

Here is the code :

#include <Button.h>

Button buttonA = Button(12, PULLUP);
Button buttonB = Button(4,  PULLUP);

int cpt;
int once = false;
void setup(){
  pinMode(13,OUTPUT); //debug to led 13
  Serial.begin(9600);
}
 
void loop(){
  if (buttonA.uniquePress()) {
    if (!once) {
      cpt++; // blink cannot exceed 9
      if (cpt == 10) {
        cpt = 0;
      }
      once = true;
      Serial.println(cpt);
    }
  } else {
    once = false;
  }
  if (buttonB.isPressed()) {
    for (byte i=1;i<=cpt;i++) {
      digitalWrite(13,HIGH);
      delay(500);
      digitalWrite(13,LOW);
      delay(500);     
    }  
    cpt=0;
  }
}

First, I replaced the buttonA.isPressed() instruction by buttonA.uniquePress(). And I placed a once boolean to serve as a debounce. But... but... sometimes, the Serial.println shows me that the cpt++ happens more than once... So, I think I'm in front of a bounce effect and I cannot understand what / where / when it happens.

Can you light my brain ?

Thank you,

Vincent

From a quick look it seems the standard Button library does no debouncing, that's
up to you (just add a small delay inside the if for uniquePress?)

And I placed a once boolean to serve as a debounce.

You'll have to explain how that's supposed to work.

I placed on the breadboard just 2 buttons. No resistor.

Then, why this:

Button buttonA = Button(12, PULLUP);
Button buttonB = Button(4,  PULLUP);

?

You've lied to the class, telling it you HAVE wired a pullup resistor. If you want to use the internal pullup resistor, either use BUTTON_PULLUP_INTERNAL or omit the argument altogether. By the way, the second argument should be BUTTON_PULLUP, not PULLUP.

Hi Paul,

First at all, I think I forget to read the documentation of the Button class. I didn't take
any attention of the PULLUP parameter. I just rewrote the sample code. So thank to
open my eyes on this usage.

And now for my once variable, it's supposed to avoid to count twice or more my cpt++
instruction. As soon as I enter in the test (with !once), I change the once to true. So, only
the release of the button can change it again to false again and allow to go to the cpt++
instruction.

I'll perform more tests and dig into the tutorials to have a better knowledge or Arduino.

Thank you,

Vincent

Hi Paul (again),

I checked into the library source code and I didn't saw any 'BUTTON_PULLUP' or any other
parameter. So, the constructor just accept PULLUP (which set the digitalPin to HIGH, we are
in front of the internal pull up resistor) and PULLDOWN (which doesn't play with the internal
resistor, so I guess that a 1k? resitor on the breadboard is required). Just stop me if I'm wrong,
I'm a newbie...

So, I just changed my source code with the following code :

if (buttonA.uniquePress()) {
    delay (10);
    cpt++;
    if (cpt == 51) {
        cpt = 0;
    }
    Serial.println(cpt);
}

If you see any problem, please give me any advice.

Thank you,

Vincent

Apparently, we aren't talking about the same Button library. So, which one are you talking about?

Hi Paul,

Yes, we are talking about the same library. But according your first answer you told me :

If you want to use the internal pullup resistor, either use BUTTON_PULLUP_INTERNAL
or omit the argument altogether. By the way, the second argument should be BUTTON_PULLUP

So, I checked deeply into the source code of the library and I didn't saw other parameter
than PULLUP and PULLDOWN. And according this code source, I can see into the constructor

buttonMode==PULLDOWN ? pulldown() : pullup();

With the pull-up() method :

void Button::pullup(void){
	mode=PULLUP;
	digitalWrite(pin,HIGH);
}

So, now I think I'm totally lost. Can you please explain what's wrong
in my method to use the PULLUP parameter AND to not have any physical
resistor on my breadboard ? I made a mistake ?

Thank you for your patience and your answer,

Vincent

I'm looking at this library:

linked to by this page:
http://playground.arduino.cc/Code/Button#.UyXQrhAZ65R

It has:

#define BUTTON_PULLUP HIGH
#define BUTTON_PULLUP_INTERNAL 2
#define BUTTON_PULLDOWN LOW

and:

    Button(uint8_t buttonPin, uint8_t buttonMode=BUTTON_PULLUP_INTERNAL);

So, I don't think we are talking about the same library.

There are some issues with that library, that may exist in your version, too. The constructor calls pinMode() before the init() function has been called, to get the hardware ready, rendering the pinMode() call useless.

Ahh ! It becomes clearer...

My library is
http://playground.arduino.cc/Code/Button#.UyXUutwkHVk

(which as the same #include "button.h")

I'll have a look on your library too. According my last tests (with my
library) my small delay (delay (10)) just after the .uniquePress instruction
is efficient. I don't have any bounce effect.

Another time, thank you very much Paul !

Vincent