RBD_Button
RBD_Button copied to clipboard
button.onReleased() is true before the button is ever pressed
This is strange. In the example program, button.onReleased() is only called after the button is pressed.
But in my sketch, button.onReleased() is true the first time through my loop(), before the button has been pressed.
I'm using an Adafruit m0 board, and pin 11 is a standard GPIO pin (docs)
#include <RBD_Timer.h> // https://github.com/alextaujenis/RBD_Timer
#include <RBD_Button.h> // https://github.com/alextaujenis/RBD_Button
#include <stdio.h>
// input pullup enabled by default
RBD::Button button(11);
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
}
void loop() {
if(button.onPressed()) {
Serial.println("Button Pressed");
}
if(button.onReleased()) {
Serial.println("Button Released");
}
}
This could be any number of problems:
- The wires are loose or crossed to your button.
- Your button is faulty. Try a different one.
- Your button is on by default, and you press it to turn it off.
- You might need to increase your debounce time.
I’d check all of these things. Let me know if you find the problem or if your are still stuck.
Alex, your sample works fine, but mine doesn't.
I wonder if there's something special about GPIO 11 on my board?
Sorry about closing this issue, that was an accidental click. Try changing pins, or buttons, or rewiring it. Do you have a different Arduino board to test the button?
When I start with your example sketch, and change the pin to 11, it works. When I take my own sketch, and remove everything else, it doesn't work.
The only difference I see from your sample is the #include <stdio.h>
, and that my serial port is at 9600 and yours was 115k. So strange.
Your .cpp file looks fine too.
I solved it with a flag that gets set to true the first time the button is pressed, but that's messy in my own code. Maybe we just need to add that state flag to the library?
Have you heard of this issue from anyone else?
Do you need to include stdio.h? If you take that out does the the button behave properly?
It still happens if I don't include #stdio.h
I also encountered this on esp8266 and esp32, but works fine on uno
I have same issue on Arduino IDE + RP2040: You can remove this line: btn[i].onReleased(); //!!!!!!<-Remove onReleased() default: true!!!!!! after that, you can see all button's onReleased value is true by default. (PS. No any wire connected on dev board)
#include <RBD_Timer.h>
#include <RBD_Button.h>
RBD::Button btn[16] = {
RBD::Button(0),
RBD::Button(1),
RBD::Button(2),
RBD::Button(3),
RBD::Button(4),
RBD::Button(5),
RBD::Button(6),
RBD::Button(7),
RBD::Button(8),
RBD::Button(9),
RBD::Button(10),
RBD::Button(11),
RBD::Button(12),
RBD::Button(13),
RBD::Button(14),
RBD::Button(15)
};
unsigned short onPressed;
unsigned short onReleased;
unsigned short isPressed;
void setup() {
Serial.begin(115200);
onPressed = 0b0;
onReleased = 0b0;
isPressed = 0b0;
for (int i = 0; i < 16; i++) {
btn[i].onPressed();
btn[i].onReleased(); //!!!!!!<-Remove onReleased() default: true!!!!!!
}
Serial.print("onPressed: ");
Serial.println(onPressed);
Serial.print("onReleased: ");
Serial.println(onReleased);
delay(5000);
}
void loop() {
unsigned short onPressedUpdate = 0b0;
unsigned short onReleasedUpdate = 0b0;
for (int i = 0; i < 16; i++) {
if (btn[i].onPressed()) {
bitSet(onPressedUpdate, i);
}
if (btn[i].onReleased()) {
bitSet(onReleasedUpdate, i);
}
}
onPressed |= onPressedUpdate;
onReleased |= onReleasedUpdate;
Serial.print("onPressed: ");
for (int i = 0; i < 16; i++) {
Serial.print(bitRead(onPressed, 15 - i));
}
Serial.println("");
Serial.print("onReleased: ");
for (int i = 0; i < 16; i++) {
Serial.print(bitRead(onReleased, 15 - i));
}
delay(3000);
}
@peter58228 There are a few things going on here...
-
Don't use
delay()
in your loop. You need to keep the event loop running for the RBD libraries to behave correctly. Your sketch here only executes the event loop once every three seconds, this code won't identify button presses correctly. -
The
for
loop in thesetup
doesn't store any values or perform any actions besides executing the.onPressed()
and.onReleased()
functions across all buttons stored in your button array. Nothing is happening here. Why is this code significant? -
This library initializes all variables as
false
by default, and thexxPressed()
functions returnfalse
unless the registered button pin isHIGH
. This is extensively backed by unit tests for this library (look inextras/unit_test
in this library to see the tests). Buttons do not initialize aspressed
, period.
In summary; your code won't register button events because you use delay()
in your loop()
: Remove delay()
from your sketch.
Also, there are several other reasons why your code might not work as intended. You could have wiring issues or a faulty Arduino board... or you most likely have normally closed buttons. They are "pressed" by default and when you push the button it opens the circuit. If this is the case you should run this code once in your setup()
to invert all button readings instead:
void setup() {
for (int i = 0; i < 16; i++) {
btn[i].invertReading();
}
}
Let me know if you are still having issues after adjusting your code. Others have reported this issue and I still think there might be hardware or library compatibility issues across all of the different flavors of Arduino development.