debouncer and changement of state

Hello everybody!
I need help to understand the debouncer and how integrate in my program and, I don’t know if the two thing are related, but I also need help to make work a function after a button is pressed.

The biggest problem that I have it is with the set and reset function. When i change the the status of setPin or resetPin the status of outUpPin and outDownPin doesn’t change. I tried to program a debouncer function because I thought the problem was the uncertainty of the status. but probably this gave more error than what it solved…

I attached my code as reference and sorry for the many error in this post but english it’s not my primary language! :sweat_smile:

Thank you!

Code.txt (8.73 KB)

If you post your code as described in the how to use this forum-please read stickies more people will see it. Also, in the stickies, there is some good advice about what we need to know to be able to answer questions.

If you want to elimate contact/switch bounce, then use a switch with a pair of fixed contacts, normally open and normally closed, e.g. micro switch. Wire the centre (moving contact) to i/o pin, and one fixed contact to +5V, the other to ground (using resistors if you like). Then, when it switches, it will not bounce from +5V to ground (or vice versa). (it will bounce however, but ignore any values that are not +5V or gnd.)The usual method of a switch pulling an i/o pin high or low, when it bounces, it will definitely switch i/o values, and will need a time delay to allow the bounce to settle.

Midarin:
Hello everybody!
I need help to understand the debouncer and how integrate in my program and, I don’t know if the two thing are related, but I also need help to make work a function after a button is pressed.

The biggest problem that I have it is with the set and reset function. When i change the the status of setPin or resetPin the status of outUpPin and outDownPin doesn’t change. I tried to program a debouncer function because I thought the problem was the uncertainty of the status. but probably this gave more error than what it solved…

I attached my code as reference and sorry for the many error in this post but english it’s not my primary language! :sweat_smile:

Thank you!

I like to accomplish debounce like this (pseudo code):

uint8_t count;
uint8_t n;
count = 0;
for n=0; n<100; n++
    if (digitalRead (buttonPin) == LOW) {
        count++;
    } else {
        delay (1); // a little delay for a bounce
    }

// if button closed less than 90% of the
// time, return 0 else return 1
return (count < 90) ? 0 : 1;

For real bad bouncers (like a big microswitch), use 16 bits for count and use a larger count threshold.

krupski: I like to accomplish debounce like this (pseudo code):

That suggested code blocks for 100 ms, and that alone makes it bad code.

You are not using INPUT_PULLUP in pinMode() in your code so presumably you have external pull-up/down resistors.

To debounce a button, I normally accept the first pulse and act on it immediately, then set a timer so I ignore subsequent pulses that occur within X (say 100) mS. That way there is no latency.

Thank you everybody!

6v6gt: You are not using INPUT_PULLUP in pinMode() in your code so presumably you have external pull-up/down resistors.

yes I have external pull down resistors

6v6gt: To debounce a button, I normally accept the first pulse and act on it immediately, then set a timer so I ignore subsequent pulses that occur within X (say 100) mS. That way there is no latency.

Maybe I don't understand what you mean but, it is not the same as the debounce_delay in my program?

raymw: If you want to elimate contact/switch bounce, then use a switch with a pair of fixed contacts, normally open and normally closed, e.g. micro switch. Wire the centre (moving contact) to i/o pin, and one fixed contact to +5V, the other to ground (using resistors if you like). Then, when it switches, it will not bounce from +5V to ground (or vice versa). (it will bounce however, but ignore any values that are not +5V or gnd.)The usual method of a switch pulling an i/o pin high or low, when it bounces, it will definitely switch i/o values, and will need a time delay to allow the bounce to settle.

The big problem here is that I am limited for the hardware part, let's say i'm try to upgrade an old system, where arduino is remoted controlled from relays (https://www.schmidiger.ch/assets/files/cobralight_empfaenger_v2_mit_drehschalter_bedienungsanl.pdf sorry for the german :sweat_smile: ) before the sistem was directly controlled with those relay but now we need to save the positions and here enter the use of arduino.

I hope I'll explained well and thank you again everybody for the answers!

If you want easy debounce, just grab a library like Bounce2 :) Non-blocking and easy to use :)

I'm currently using https://github.com/evert-arias/EasyButton for that matter. It also has some other interesting features. Take a look at it.

Midarin: . . . Maybe I don't understand what you mean but, it is not the same as the debounce_delay in my program?

nearly.

If you are debouncing a button "near" your MCU, and the button is pulled to one of the rails (normally the high one because then you can use the internal pullup resistor), the debouncing can be simplified and without latency. In such a situation, you can be sure the any pulses from the button result from an attempt to press it, so you can accept the first pulse and act on it immediately, i.e. not waiting for any stabilisation period. However, then, you must ignore pulses from the button for a certain number of milliseconds to eliminate any after-bounces.

. . .
static uint32_t lastButtonPressAtMs = 0 ;
if ( millis() - lastButtonPressAtMs > 200 && digitalRead( myButton ) ) {  // pressed = HIGH; 200mS ignore period. 
  // act on button here
  lastButtonPressAtMs = millis() ;
}
. . .

Naturally, it is different if you are trying to distingish a button press from a spurious pulse which could result from say connecting the button with long wires in an noisy electrical environment. In that case, you have to look for a state change which has been stable for X mS before accepting it (as you appear to be doing). . . .

wvmarle: That suggested code blocks for 100 ms, and that alone makes it bad code.

It only waits a max of 100 msec if the switch bounces a lot. Otherwise, only count++ is executed. Look at it again.

6v6gt: You are not using INPUT_PULLUP in pinMode() in your code so presumably you have external pull-up/down resistors.

To debounce a button, I normally accept the first pulse and act on it immediately, then set a timer so I ignore subsequent pulses that occur within X (say 100) mS. That way there is no latency.

OMG!!! It's pseudo-code.

wvmarle: That suggested code blocks for 100 ms, and that alone makes it bad code.

It blocks? Blocks what? You people make me laugh.

I'm not laughing ;) I agree that adding the possibility to block the code for 100ms is bad practice. 100ms is HUGE in uC land and really not necessary. Just use millis() and all problems are over :)

PS Hey, I'm not insulting you! Just saying, hopefully in a respectable way, that I also think it's not the most elegant solution. But you are right, you don't always need that ;)

septillion: I'm not laughing ;) I agree that adding the possibility to block the code for 100ms is bad practice. 100ms is HUGE in uC land and really not necessary. Just use millis() and all problems are over :)

PS Hey, I'm not insulting you! Just saying, hopefully in a respectable way, that I also think it's not the most elegant solution. But you are right, you don't always need that ;)

If you have some sort of a really bad switch, the debounce needs to take as long as necessary to handle it.

As I said previously, "my" code does not use 100 msec, it returns right after the switch stops bouncing (well, a few microseconds after it stops bouncing). As long as it takes the remaining "count++ " to execute.

Yeah, but if it's bad it will block... Also, you basically rely on the speed of the micro. Like I said, not to insult you, but come on, you can do better :D