I’m dealing with debouncing issues on another part of my project and that raises the issue about debouncing with the switches I use to give GPIO pins input data. When I watch the logs on the web page for my ESPHome devices, I don’t see multiple events logged when I use a non-debounced switch and when I was using the Arduino console to upload a program and test it, I never saw an indication of multiple events for a state change on a switch.
I also don’t know how quickly ESPHome updates status for a GPIO.
Do I need to debounce switches connected to GPIO pins or is that done by the ESP32 or the ESPHome software?
Quite hard to believe, there is always some debounce and if I have switch on interrupt, I definitely trigger it. But back to your question, I don’t know if esphome have some small “default” debounce on normal binary sensor.
I guess so…
If you use interrupts, you get every trigger independently from your code.
If you use some digitalRead pin X, you only get the state when that line it’s passing your loop. If your code is busy to do other things, you don’t get trigger.
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.
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.
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.
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?
(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.