Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

button.onReleased() is true before the button is ever pressed #14

Open
mshulman opened this issue Oct 10, 2021 · 9 comments
Open

button.onReleased() is true before the button is ever pressed #14

mshulman opened this issue Oct 10, 2021 · 9 comments

Comments

@mshulman
Copy link

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");
  }
}
@alextaujenis
Copy link
Owner

alextaujenis commented Oct 10, 2021

This could be any number of problems:

  1. The wires are loose or crossed to your button.
  2. Your button is faulty. Try a different one.
  3. Your button is on by default, and you press it to turn it off.
  4. 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.

@mshulman
Copy link
Author

Alex, your sample works fine, but mine doesn't.

I wonder if there's something special about GPIO 11 on my board?

@alextaujenis
Copy link
Owner

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?

@mshulman
Copy link
Author

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?

@alextaujenis
Copy link
Owner

alextaujenis commented Oct 11, 2021

Do you need to include stdio.h? If you take that out does the the button behave properly?

@mshulman
Copy link
Author

It still happens if I don't include #stdio.h

@fishdaa
Copy link

fishdaa commented Jun 7, 2022

I also encountered this on esp8266 and esp32, but works fine on uno

@peter58228
Copy link

peter58228 commented Sep 25, 2023

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);
}

@alextaujenis
Copy link
Owner

@peter58228 There are a few things going on here...

  1. 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.

  2. The for loop in the setup 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?

  3. This library initializes all variables as false by default, and the xxPressed() functions return false unless the registered button pin is HIGH. This is extensively backed by unit tests for this library (look in extras/unit_test in this library to see the tests). Buttons do not initialize as pressed, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants