Push-button Debouncing question - Page 1
Forum section: electronics / projects

author: Lucky-Luka
author_rank: Unknown
timestamp: February 29, 2020, 05:04:35 pm
content: Hi allI have a simple circuit: a push-button with a pull-down 10 kohm resistor connected to an LED.I'm using an Arduino UNO. The loop has a freq of 100Hz.Every time I push the button I would like to change the state of the LED.Not every single time I can change its state.I know that I have to do some kind of debouncing (software or hardware).I've tried to look at the signal with the scope but it isn't clear to me why I have to do the debouncing.I have connected the yellow probe through a yellow cable to the pull down resistorI have read that signals >3V are considered HIGH while signals <1.5V are considered LOW by Arduino.In the signal on the scope I don't see what causes the problem to che change of the state of the LED.https://youtu.be/KYbxU-7bnGsCheers

author: Chriss
author_rank: Frequent Contributor
timestamp: February 29, 2020, 05:33:43 pm
content: Hi!I would prefer to you to make an experiment.Write a code with a counter variable lets say "counter" where this counteris will inrease by 1 and is triggered every time when you press the button.So, the counter will inrease even after you release the button.And check the counter value afte button pressed. You will see how many time your button bounced.In your circuit you must have a hardware or software debounce.

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 29, 2020, 05:45:40 pm
content: Your current logic is "If the button is down, change the LED state."Instead, you should only change the LED state when the button changes state; either from high to low, or low to high. (The difference is one changes state when you press, the other when you release; but which one is which depends on how you wire your buttons.)When the button is pressed or released, there is a very short duration when the connection is intermittent. Depending on the type of the button, the duration varies. If you are unlucky, you check the button state during such an intermittent connection, and get the "wrong" state. You will get the correct state on a later check, but if you check purely state changes --edges-- you can see more changes than the actual button does, due to contact bounce.Consider the following example code:Code:#define LED_PIN 2#define BUTTON_PIN 3#define LOOP_PIN 4static int led_state;static int button_state;static int loop_state;void setup(void) {pinMode(LED_PIN, OUTPUT);pinMode(LOOP_PIN, OUTPUT);pinMode(BUTTON_PIN, INPUT);led_state = 0;loop_state = 0;button_pressed = 0;}void loop(void) {if (digitalRead(BUTTON_PIN)) {if (button_pressed) {// Button is kept depressed} else {button_pressed = 1;// Button pressled_state = !led_state;digitalWrite(LED_PIN, led_state);}} else {if (button_pressed) {button_pressed = 0;// Button was releasedled_state = !led_state;digitalWrite(LED_PIN, led_state);} else {// Button is not being pressed}}loop_state = !loop_state;digitalWrite(LOOP_PIN, loop_state);delay(10); // 10ms = 0.01s, 1000/10 = 100 iterations per second.}This example changes the state of the LED on both press (transition from not-pressed to pressed) and release (transition from pressed to not-pressed).Because of how it is written, I do believe it is immune to contact bounce -- it is, after all, just a four-state finite state machine.The intent of the above example is to show how to properly check button state changes, but without (software) debouncing to keep it as simple as possible.If you get flicker on the LED pin, that will be due to button contact bounce. (You'll need an oscilloscope to capture it, though.)If the button was e.g. "Move up in menu", it'd cause the selection to move by more than one entry per button press. Or game character to do the action several times instead of just once. Not good.That contact bounce can be suppressed using a capacitor, or in software in various ways. I personally prefer software debounce that reacts to the state change immediately, but is "numb" to any further changes for a short period (typically on the order of 20ms, or 0.020 seconds). Any contact bounce occurs during the "numb" period, and any extra transitions during that period are ignored. I get immediate response, with a quaranteed interval between press and release events (transitions -- the "numb" period), and it also makes implementing autorepeat (by keeping the button down for longer) easy. (It basically uses a state-and-counter variable per button.)

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 29, 2020, 06:00:18 pm
content: From your short piece of code, debouncing or not debouncing is not even your primary concern here.As you wrote the code, the state of the LED IO will toggle every 10 ms for as long as you push the button. Not sure this is what you intended, as it would basically be uncontrollable from a user's POV. It's hard to push a button for just as long as to see the button level as high only ONCE, but not twice.It's a simple logic problem, re-read your code.Once you get that fixed, you can think of adding some simple debouncing, for instance with some hold-off period as Nominal suggested, simple and effective.

author: Lucky-Luka
author_rank: Unknown
timestamp: February 29, 2020, 07:46:02 pm
content: Quote from: Chriss on February 29, 2020, 05:33:43 pmI've done what you have said.It looks like the bouncing thing has nothing to do with the fact that I can't always change the LED state (at least not that my eyes can see).Since I'm still learning to use the 'scope I tried different settings.Now I've tried 50ms/divWith a brief push the yellow signal can stays high for about 100ms.The counter goes at 10 since the loop freq is 100Hz.With my actual code I change the LED state 10 times and at the end I may set LOW again the LED not because ot the bouncing problem but because of the way the sketch is written, right?

author: bson
author_rank: Unknown
timestamp: February 29, 2020, 07:50:29 pm
content: You only want to delay when you detect a change.

author: Lucky-Luka
author_rank: Unknown
timestamp: February 29, 2020, 07:50:53 pm
content: Quote from: SiliconWizard on February 29, 2020, 06:00:18 pmYes, you're right. Thanks