Hello everyone, I have a problem with the code.
Every time I press the button, the if works twice.
I want to press the button and what happens inside the if will be only once.
It is important to me that there is a delay within the if because the original code is longer and it runs an array of motors.
Attaches the two codes here
Thanks for the helpers
#include <ezButton.h>
ezButton limitSwitch(7); // create ezButton object that attach to pin 7;
void setup() {
Serial.begin(9600);
limitSwitch.setDebounceTime(50); // set debounce time to 50 milliseconds
}
void loop() {
limitSwitch.loop(); // MUST call the loop() function first
if(limitSwitch.isPressed())
{
Serial.println("A");
delay(500);
}
if(limitSwitch.isReleased())
{
Serial.println("B");
}
}
I think that you would be better off without the library. Just use the state change example to detect a rising edge.
It appears that the problem is the debounce time. When you press the button, once the debounce time is up, the press is registered, you print "A", wait a bit and by the end of the delay you have released the button.
The next time around loop, the library notices that the button was released so it sets the debounce timer again. It needs 50mS to be sure that the state is stable, but microseconds later, you check again to see if the button is pressed. The library is still waiting for the debounce time to elapse, so it hasn't changed any of it's local variables that are used to figure out pressed or released. In consequence, even though it knows that the button was released, it is not ready to say so and it returns pressed a second time.
You'll have to figure out a way to pay better attention to the button if you use exButton.
You could just do your own button handling, it is not hard or, better, figure out a way to do the thing you are using delay() as a proxy for in your tests without killing your loop frequency.
It would be better for the future development and enhancements you will no doubt be getting to.
That solution is a patch to the limitations of the library. Sooner later you will have more trouble, and more patches like this.
ezButton reports edges, so the additional variable is just making up for your failure to use the library as it is coded.
There is no need for a library here, and no need to use delay(). This below sets flags on the edges, and it is up to you to handle those facts and clear the flags when you have done as deomonstrated. It will provide the fastest possible response, and the minimum use of time.
# define limitSwitch 7
void setup() {
Serial.begin(115200);
Serial.println("hello world!\n");
pinMode(limitSwitch, INPUT_PULLUP);
}
void loop() {
unsigned long now = millis();
static unsigned long lastCheck;
static bool lastState = true; // normall HIGH
static bool gotPressed = false, gotReleased = false;
if (now - lastCheck > 25) {
lastCheck = now;
bool state = digitalRead(limitSwitch);
if (state != lastState) {
lastState = state;
if (state) gotPressed = true; // clear when you handle this fact
else gotReleased = true; // clear when you handle this fact
}
}
if (gotPressed) {
Serial.println("Saw it go down!");
// whatever... any time consumption = sluggish button
delay(500);
gotPressed = false; // handled that
}
if (gotReleased) {
Serial.println("Saw it go up!");
// whatever...
delay(500);
gotReleased = false; // handled that
}
}
Another good one to curl up with in front of the fireplace is
No problem, but as some people here already pointed out, there are cleaner ways of dealing with this in this particular case.
At first glance, the ezButton library does not seem to have edge detecting capability, but upon closer inspection, the count functions seem to do the trick. You could have a look at the setCountMode() example in the documentation.
Using no library is an educational exercise which I can recommend, but wrappers like ezButton will make working with multiple buttons (e.g., an array of buttons) easier and cleaner in my opinion.
My debounce reads the pin every 500 micros and updates a history byte with the last 8 reads in the bits. New read is in bit 0, oldest in bit 7. Bit order is 76543210.
Numbers to look for:
0b00000000 = 0 is button is held down
0b10000000 = 128 is button just pressed
0b01111111 = 127 is button just released
0b11111111 = 255 is button held down
everything else is unstable.
reading twice a ms , it takes 3.5 ms of stable to "prove it"
//Update pin history:
history = history << 1; // shifts all bits left 1, new bit 0 == 0
history += digitalRead( buttonPin ); // new bit 0 now == pin state
// elsewhere
if ( history == 128 ) // if button just pressed, transition as opposed to state
{
Every button needs 4 bytes. All buttons use the same unsigned interval.
1 byte for pin number
1 btye for history
1 unsigned for time start, timer = micros() gets the low 16 bits, good for 65.535 ms.
LOL! My previous method is more overkill, more noise-sensitive and cycle-hogging!
Reading once or twice a milli instead or 40 to 60 times possible is NOT overkill!
But pray tell please, how this debounce is not suited to buttons on Arduino?
This one is tight so it can be used for multi and matrix buttons with less overhead.
This one might be fast enough to debounce limit switches, my old one is. Buttons and switches are not just for finger presses that "debounce by ignoring 20 to 50ms" "is good enough for slow people".
I picked 500 usec reads to set a good stable period to mark transition. 3.5ms same state.
0b10000000
0b01111111
It makes knowing button state one byte-byte compare.
If you want to give your Opinion then at least back it up with facts.
In the debounce before I kept current pin state in bit 0 and previous state in bit 1, saving 1 byte over having prev and curr vars to detect state changes.
Then I looked at what 8 bits of history could indicate and it works over a wide range of read speeds. The outcome is either bouncing or 1 of 4 meaningful states possible.