How important is debouncing switches for GPIO pins?

Thank you. I’ve done very little with my own code and am using ESPHome for almost everything, so I haven’t dealt with that yet. So I guess it comes down to how ESPHome handles this.

Yes. On arduino code you decide how to handle button presses. On esphome, you adapt to the way it handles it. Usually small debounce is good starting point.
Question is more valid if you need to trigger some specific signals like zero crossing of AC sine wave.

I’m still hoping to hear from someone in the ESPHome project itself is ESPHome does any debouncing in the software.

Got an answer on Discord. For Binary Sensors, you can use delayed_off, delayed_on, or delayed_on_off for debouncing. In my case, that will do the job. If anyone has more to add for this, please include it here for people searching for that info in the future.

You didn’t need Discord for that info, it’s jumping to your eyes when you open documentation. But you wrote that you don’t get any bounce on your switches, which made me wonder if there is a tiny debounce already baked in for binary sensor…

I had read that, but was using delayed_off for another function and had spent some time working that out. I got so focused on that particular use of it that I completely forgot about the original intent of the function.

I didn’t see any bounce. I wanted to be sure there wasn’t something I wasn’t seeing. While the logs aren’t showing a bounce, I wanted to be sure there wasn’t something I wasn’t seeing.

Doubts remain… Because normal switch has always bounce. Can be small or big, long or short.
But it probably fades while Esp is busy with other tasks in the loop.

1 Like

Right.

Which is why the delay function is there - it does the debouncing for us. Without that function, correct, doubts remain. Right now the best information I have is that there is no inherent software debouncing done unless we use the delay functions.

And that’s how it should be.
Maybe if you setup Esp32 with nothing else than one sensor, you catch the bounce…
Every step on the loop takes some time, especially logging, so 1ms bounce can easily been not detected if interrupts are not used.

ESPHome inherently debounces to some degree because it samples once per loop, which is around 16ms. There is no true interrupt driven processing in ESPHome for the most part.

Thank you. Both points are helpful!

I may be wrong - I still have so much to learn - but it seems to me that it’s possible that a GPIO could still be sampled right after the start of the stage change because of the point ESPHome is in the loop. That might be an infrequent or even rare event, but it seems like it’s still a possibility, so using either hardware debouncing or using the delay function is still a wise precaution. Am I right about that?

Just use filters:

delayed_on

(Required, time, templatable): When a signal ON is received, wait for the specified time period until publishing an ON state. If an OFF value is received while waiting, the ON action is discarded. Or in other words: Only send an ON value if the binary sensor has stayed ON for at least the specified time period. When using a lambda call, you should return the delay value in milliseconds. Useful for debouncing push buttons.

delayed_off

(Required, time, templatable): When a signal OFF is received, wait for the specified time period until publishing an OFF state. If an ON value is received while waiting, the OFF action is discarded. Or in other words: Only send an OFF value if the binary sensor has stayed OFF for at least the specified time period. When using a lambda call, you should return the delay value in milliseconds. Useful for debouncing push buttons.

I usually throw on at least a 100ms debounce (and up to 500ms) as there’s usually no harm and often does good for my typical applications.

That’s usually for push buttons/ endstops etc though.

You can always dig into the source code to check if there is default debouncing done at the component level, but the defaults would typically be called out in the docs.

https://esphome.io/api/gpio__binary__sensor_8h

Yes. Depending on the switch the bounces can range from a ms or two to hundreds.

From where is that coming from? Esphome has fixed loop time independent from processor used and tasks in the code??

It’s a minimum loop time actually. In ideal circumstances (all components being well-behaved) it will be fixed.

Thank’s. Some sources? I’d like to know more…

Also here.

on_loop
This automation will be triggered on every loop() iteration (usually around every 16 milliseconds).

I found this for additional info:

1 Like