arduino / arduino-examples

Arduino IDE bundled examples
Creative Commons Zero v1.0 Universal
90 stars 41 forks source link

Problems with the Debounce tutorial #12

Open oakkitten opened 5 years ago

oakkitten commented 5 years ago

In the Debounce tutorial, a push button press is toggling a LED, which can lead people to think that the example shows how to reliably detect button presses. There are some problems with this:

These problems can be somewhat mitigated by using a lower debounceDelay value, if you have good buttons. Or straight away solved by firing event first, and waiting for the button to debounce later, e.g.

    check():
        current_reading = read_pin()

        if reading_is_settling():
            if last_reading != current_reading: 
                start_settling()

        else if current_reading != button_state:
            dispatch_change(current_reading)
            button_state = current_reading
            start_settling()

    reading_is_settling():
        return now - last_reading_change_time > SETTLE_TIME

    start_settling():
        last_reading = current_reading
        last_reading_change_time = now

If there's a need to detect voltage spikes, you can still do it by changing the logic of read_pin(), separating the concerns.

At the very least, the aforementioned problems and alternative solutions should be mentioned in the description.


Additionally, the example should probably use LED_BUILTIN instead of ledPin = 13 for clarity. And maybe not use confusing names such as lastDebounceTime.

pmmcmullen94 commented 5 years ago

The reason for the debounce is because most switches, especially those used for hobby purchases (cheap), don't cleanly go from 0 to 5V (or whatever the output level is). Usually the output bounces around before hitting 5V and likewise before hitting 0V when released. The debounce logic is used to ignore these.

The code above looks correct, but the way I've done that I think is quicker (I'm not familiar with the Python implementation of Arduino, only C/C++ variant) is by using interrupts which will get you a little quicker depending on where you put this code at. The way I've done in the past is trigger on CHANGE and then in the change code, first check if the time limit between presses has been met. If not, return. If so, record the current reading and time change.

Don't know if this helped at all, but I wanted to make sure the debounce reasoning was clarified as I couldn't tell completely by your description. Good luck