I'm trying to detect the state of the buttons on my board at boot time, to see if the user is holding a button down to request special boot behavior. I've been using Bounce2 for debouncing & button mgt.
However it appears that after I call Bounce::attach() and ::interval() and ::update() (called repeatedly for 5x the debounceInterval), ::read() does not return the correct state of the button (which is LOW/pressed) until the button has been released and pressed again. The button is LOW, but Bounce says it is HIGH until I release and re-press the button. Then Bounce starts working correctly.
Is this known/expected behavior, or is it just me?
Hi,
I'm trying to detect the state of the buttons on my board at boot time, to see if the user is holding a button down to request special boot behavior. I've been using Bounce2 for debouncing & button mgt.
However it appears that after I call Bounce::attach() and ::interval() and ::update() (called repeatedly for 5x the debounceInterval), ::read() does not return the correct state of the button (which is LOW/pressed) until the button has been released and pressed again. The button is LOW, but Bounce says it is HIGH until I release and re-press the button. Then Bounce starts working correctly.
Is this known/expected behavior, or is it just me?
Hi, think I'm also running into this same issue, or something similar.
In my case, I have two actions I want my button to trigger on: on a short-press and release, and immediately if the button is held past a certain duration. The problem I'm having is that on the first time through loop(), the 'long press' branch is getting activated.
However this behaviour only happens from a cold power-on -- a soft reset behaves like you'd expect. This makes me wonder if it might be due to something like floating pins during first power-on registering as a state change?
I've found a workaround by modifying the library to add a resetDuration() function that sets stateChangeLastTime = millis();. Calling this at the very end of setup() before going into loop() seems to work around the issue.
The relevant part of my code is something like (paraphrased from my hefty app):-
Hi, think I'm also running into this same issue, or something similar.
In my case, I have two actions I want my button to trigger on: on a short-press and release, and immediately if the button is held past a certain duration. The problem I'm having is that on the first time through loop(), the 'long press' branch is getting activated.
However this behaviour only happens from a cold power-on -- a soft reset behaves like you'd expect. This makes me wonder if it might be due to something like floating pins during first power-on registering as a state change?
I've found a workaround by modifying the library to add a resetDuration() function that sets `stateChangeLastTime = millis();`. Calling this at the very end of setup() before going into loop() seems to work around the issue.
The relevant part of my code is something like (paraphrased from my hefty app):-
```
#define LONGPRESS_MILLIS 250
void setup() {
pushButtonA.attach(PIN_BUTTON, INPUT);
pushButtonA.interval(10);
bushButtonA.setPressedState(LOW);
}
void loop() {
if (pushButtonA.update()) {
if (pushButtonA.relesaed() && pushButtonA.previousDuration()<=LONGPRESS_MILLIS) {
button_normal();
} else if ( pushButtonB.isPressed() && pushButtonB.currentDuration()>LONGPRESS_MILLIS) {
button_longpress();
}
}
```
Hi again. I had to clean up your code to test it out. I cannot replicate your error. Are you using an external pullup as indicated in your code? Can you post a working demonstration of your issue?
Here is the loop() code I used :
button.update();
if (button.released() && button.previousDuration() <= 250) {
Serial.println("normal");
} else if (button.isPressed() && button.currentDuration() > 250) {
Serial.println("long");
}
Hi again. I had to clean up your code to test it out. I cannot replicate your error. Are you using an **external pullup** as indicated in your code? Can you post a working demonstration of your issue?
Here is the *loop()* code I used :
```
button.update();
if (button.released() && button.previousDuration() <= 250) {
Serial.println("normal");
} else if (button.isPressed() && button.currentDuration() > 250) {
Serial.println("long");
}
```
Hi @thomasfredericks. Thanks for getting back to me. I'm not actually OP, but I think the problem I'm seeing could be the same root cause.
My project connects one side of the switch to ground, so I probably should be using INPUT_PULLUP there instead, thanks for catching that. However I did try using INPUT_PULLUP instead of INPUT, and it didn't solve the problem for me.
Sorry for the non-working example -- I took the snippets of code from my rather large project. I'll see if I can put together a working example that you can just test instead!
In case it helps in the meantime, this is the solution I've ended up with, which gets around the problem for me:-
class ResettableButton : public Bounce2::Button {
public:
/**
* @brief Resets the 'last state change' time.
*/
void resetStateChange() {
this->stateChangeLastTime = millis();
}
};
using Button = ResettableButton;
button.resetStateChange(); // do this at end of setup()
Hi @thomasfredericks. Thanks for getting back to me. I'm not actually OP, but I think the problem I'm seeing could be the same root cause.
My project connects one side of the switch to ground, so I probably should be using INPUT_PULLUP there instead, thanks for catching that. However I did try using INPUT_PULLUP instead of INPUT, and it didn't solve the problem for me.
Sorry for the non-working example -- I took the snippets of code from my rather large project. I'll see if I can put together a working example that you can just test instead!
In case it helps in the meantime, this is the solution I've ended up with, which gets around the problem for me:-
```
class ResettableButton : public Bounce2::Button {
public:
/**
* @brief Resets the 'last state change' time.
*/
void resetStateChange() {
this->stateChangeLastTime = millis();
}
};
using Button = ResettableButton;
```
```
button.resetStateChange(); // do this at end of setup()
```
I regret that I didn't try to reproduce this sooner for you. Now that I'm trying, I'm pretty sure this was my mistake all along. I cannot reproduce the bug I filed (at a moment when I was pretty loaded down with work.)
Anyway I'm the OP and I retract this bug. Pilot error. Sorry to bother you. Thanks for the free software!
I regret that I didn't try to reproduce this sooner for you. Now that I'm trying, I'm pretty sure this was my mistake all along. I cannot reproduce the bug I filed (at a moment when I was pretty loaded down with work.)
Anyway I'm the OP and I retract this bug. Pilot error. Sorry to bother you. Thanks for the free software!
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Hi,
I'm trying to detect the state of the buttons on my board at boot time, to see if the user is holding a button down to request special boot behavior. I've been using Bounce2 for debouncing & button mgt.
However it appears that after I call Bounce::attach() and ::interval() and ::update() (called repeatedly for 5x the debounceInterval), ::read() does not return the correct state of the button (which is LOW/pressed) until the button has been released and pressed again. The button is LOW, but Bounce says it is HIGH until I release and re-press the button. Then Bounce starts working correctly.
Is this known/expected behavior, or is it just me?
Hi, can you please post sample code? I will test.
Hi, think I'm also running into this same issue, or something similar.
In my case, I have two actions I want my button to trigger on: on a short-press and release, and immediately if the button is held past a certain duration. The problem I'm having is that on the first time through loop(), the 'long press' branch is getting activated.
However this behaviour only happens from a cold power-on -- a soft reset behaves like you'd expect. This makes me wonder if it might be due to something like floating pins during first power-on registering as a state change?
I've found a workaround by modifying the library to add a resetDuration() function that sets
stateChangeLastTime = millis();. Calling this at the very end of setup() before going into loop() seems to work around the issue.The relevant part of my code is something like (paraphrased from my hefty app):-
Hi again. I had to clean up your code to test it out. I cannot replicate your error. Are you using an external pullup as indicated in your code? Can you post a working demonstration of your issue?
Here is the loop() code I used :
Hi @thomasfredericks. Thanks for getting back to me. I'm not actually OP, but I think the problem I'm seeing could be the same root cause.
My project connects one side of the switch to ground, so I probably should be using INPUT_PULLUP there instead, thanks for catching that. However I did try using INPUT_PULLUP instead of INPUT, and it didn't solve the problem for me.
Sorry for the non-working example -- I took the snippets of code from my rather large project. I'll see if I can put together a working example that you can just test instead!
In case it helps in the meantime, this is the solution I've ended up with, which gets around the problem for me:-
I regret that I didn't try to reproduce this sooner for you. Now that I'm trying, I'm pretty sure this was my mistake all along. I cannot reproduce the bug I filed (at a moment when I was pretty loaded down with work.)
Anyway I'm the OP and I retract this bug. Pilot error. Sorry to bother you. Thanks for the free software!