I get error using the bounce code

I try to figure out how to use the Bounce code from the arduino.cc site. The sketch is by Maik Schmidt and the book "Arduino - A Quick-Start Guide". When using examples from the Bounce.zip file it works, but not the sketch from Schmidt.

This is the error I get when running the sketch:
ae_Binary_dice_digital_tarning_ver2:21: error: no matching function for call to 'Bounce::Bounce(const unsigned int&, const unsigned int&)'
C:\Users\jimmy_000\Documents\Arduino\libraries\Bounce/Bounce.h:40: note: candidates are: Bounce::Bounce()
C:\Users\jimmy_000\Documents\Arduino\libraries\Bounce/Bounce.h:36: note: Bounce::Bounce(const Bounce&)

This is the sketch I try to use:
#include <Bounce.h>

const unsigned int LED_BIT0 = 12;
const unsigned int LED_BIT1 = 11;
const unsigned int LED_BIT2 = 10;
const unsigned int START_BUTTON_PIN = 5;
const unsigned int GUESS_BUTTON_PIN = 7;
const unsigned int BAUD_RATE = 9600;

void setup() {
pinMode(LED_BIT0, OUTPUT);
pinMode(LED_BIT1, OUTPUT);
pinMode(LED_BIT2, OUTPUT);
pinMode(START_BUTTON_PIN, INPUT);
pinMode(GUESS_BUTTON_PIN, INPUT);
randomSeed(analogRead(A0));
Serial.begin(BAUD_RATE);
}

const unsigned int DEBOUNCE_DELAY = 20;
Bounce start_button(START_BUTTON_PIN, DEBOUNCE_DELAY);
Bounce guess_button(GUESS_BUTTON_PIN, DEBOUNCE_DELAY);
int guess = 0;

void loop() {
handle_guess_button();
handle_start_button();
}

void handle_guess_button() {
if (guess_button.update()) {
if (guess_button.read() == HIGH) {
guess = (guess % 6) + 1; //
output_result(guess);
Serial.print("Guess: ");
Serial.println(guess);
}
}
}

void handle_start_button() {
if (start_button.update()) {
if (start_button.read() == HIGH) {
const int result = random(1, 7);
output_result(result);
Serial.print("Result: ");
Serial.println(result);
if (guess > 0) {
if (result == guess) {
Serial.println("You win!");
hooray();
} else {
Serial.println("You lose!");
}
}
delay(2000);
guess = 0;
}
}
}

void output_result(const long result) {
digitalWrite(LED_BIT0, result & B001);
digitalWrite(LED_BIT1, result & B010);
digitalWrite(LED_BIT2, result & B100);
}

void hooray() {
for (int i = 0; i < 3; i++) {
output_result(7);
delay(500);
output_result(0);
delay(500);
}
}

But doesn't these lines do that?:
const unsigned int DEBOUNCE_DELAY = 20;
Bounce start_button(START_BUTTON_PIN, DEBOUNCE_DELAY);
Bounce guess_button(GUESS_BUTTON_PIN, DEBOUNCE_DELAY);
int guess = 0;

How would you create a new bounce object?

Regards / Jimmy

Jimmyalenius:
But doesn't these lines do that?:

Bounce start_button(START_BUTTON_PIN, DEBOUNCE_DELAY);

[/quote]

Those lines create a new Bounce object... but they are trying to call a constructor that doesn't exist. The line I kept above is the same as:

Bounce start_button;  //merely a declaration

start_button = new Bounce(START_BUTTON_PIN, DEBOUNCE_DELAY); //creation of the object instance




If you coded it that way, it should error on the second line, because there is no constructor that takes two arguments like that.

In the examples, the object is declared and created/instantiated in the global section, and initialized in the setup function:



Bounce debouncer = Bounce();

void setup() {
 // Setup the button
 pinMode(BUTTON_PIN,INPUT);
 // Activate internal pull-up
 digitalWrite(BUTTON_PIN,HIGH);
 
 // After setting up the button, setup debouncer
 debouncer.attach(BUTTON_PIN);
 debouncer.interval(5);
 
 //Setup the LED
 pinMode(LED_PIN,OUTPUT);
 
}

Ok, I try to figure out how to implement this in my code. Thanks for taking your time!

Regards / Jimmy

Jimmyalenius:
Ok, I try to figure out how to implement this in my code.

You have the library, so you also have the examples. Make sure you understand how those examples work, and you should be able to figure out anything.

hello i have the same problem , and this example not help me too
help pls

hello i have the same problem , and this example not help me too
help pls

You have the library, so you also have the examples. Make sure you understand how those examples work, and you should be able to figure out anything.

Go through the examples that come with the library. This will give you an understanding of how to use it.

1-5-2014 6-05-49 PM.jpg

Those lines create a new Bounce object... but they are trying to call a constructor that doesn't exist. The line I kept above is the same as:

Code:

Bounce start_button; //merely a declaration
start_button = new Bounce(START_BUTTON_PIN, DEBOUNCE_DELAY); //creation of the object instance

If you coded it that way, it should error on the second line, because there is no constructor that takes two arguments like that.

I guess the problem comes from the changes in the library "Bounce". The old version defined a constructor with two parameters and the most recent has a constructor with no parameters. In principle, the new library should be called "Bounce2" to avoid confusion.

The former can be downloaded at the URL: Arduino Playground - HomePage

To know which syntax is correct, as jasmine2501 said, you can open the "Bounce.h" file located in the folder "libraries\Bounce" where the class Bounce is defined or examine the examples files (as "\libraries\Bounce\examples\bounce\bounce.ino ")

IMO, constructors that don't initialize the object shouldn't exist, but c#, for example, requires that there exist a constructor with no parameters - a 'default' constructor must exist. So, the way we prevent programmers from creating invalid objects is to make the default constructor private. That was an epic thread on the C# discussion group - I think "private constructors" is the best thread we ever had.

So, the new library isn't much of an improvement in terms of being robust. A class should protect itself from bad usage. If it needs a pin number and a delay value to work, it should be impossible to create the object without setting those values.

If it needs a pin number and a delay value to work, it should be impossible to create the object without setting those values.

I disagree. The no argument constructor should create an object that can't do anything.

But, then methods that are called on that object should not do anything (stupid) if all the data the object needs is missing. If the object needs a pin number and delay value, a reasonable default delay value should be assumed, and an invalid pin number (-1, maybe). Then, any member should check that the pin number is valid before using it.

PaulS:

If it needs a pin number and a delay value to work, it should be impossible to create the object without setting those values.

I disagree. The no argument constructor should create an object that can't do anything.

But, then methods that are called on that object should not do anything (stupid) if all the data the object needs is missing. If the object needs a pin number and delay value, a reasonable default delay value should be assumed, and an invalid pin number (-1, maybe). Then, any member should check that the pin number is valid before using it.

And if it's not? If I was making a C# library and the object was in an invalid state, and methods were called which couldn't work, I would throw an exception. In microcontrollers though, we shouldn't be throwing exceptions, right? Typically, when exceptions can't be thrown, I would just have the method return a failure code or null object. I don't think that makes any sense in Arduino, and one way to prevent it from happening is not let users call the default constructor, or to assign default values so the object can function. It's probably an issue of personal preference, but I like to make it impossible to write invalid code - the more that can be caught by the compiler, the better.

BTW, that's a critical part of the factory pattern - make it impossible to create objects other than through the factory.

In the case of the Bounce library, if an instance is created without a valid pin number or delay (though I can't imagine that scenario), a call to get the state of the pin should be able to return a negative value, to indicate that the state is not HIGH or LOW.

Most classes that deal with the hardware should have a begin() method that actually does the hardware setup stuff (pinMode(), etc.). That method is where the pin number should be supplied, in my opinion.

I have dozens of classes at work whose constructors require arguments, but I have hundreds that do not. Those that don't have methods that set the values needed. Any method that is called before those that need to be called to supply arguments throw exceptions, return error codes, or simply do nothing. Sometimes, doing nothing IS the right thing to do.

Yeah there's two patterns - one where the constructor must do everything and one where there is a constructor and an initializer, and for classes that do something like threading, there's often start and stop functions. That second pattern was common when I learned C++ many years ago. I just don't personally like it - it's perfectly valid and sometimes you have to use it.