How to properly debounce with software alone?
Posted: Fri Nov 06, 2015 6:05 pm
I'm looking for a way to properly debounce GPIO readings. So far I failed.
I have a reed switch (magnetic switch, http://j.mp/1Hy4nGf) connected to the ESP.
The first attempt was to debounce based on timer and delay. This works fine for a few dozen minutes until it simply stalls. I don't get any change events anymore at all, the rest of the application runs fine. I suspect that the cause is 'tmr.now()' which behaves not as you'd expect (https://github.com/nodemcu/nodemcu-firmware/issues/690).
The next attempt was to do it simple and straight forward by registering two separate functions for GPIO up/down events. This runs stable for days. However, a few times per day I get 'down' events even though the switch wasn't triggered physically at all.
Could it be that the false 'down' event has nothing to do with the debounce at all but is simply a characteristic of the reed switch?
I have a reed switch (magnetic switch, http://j.mp/1Hy4nGf) connected to the ESP.
The first attempt was to debounce based on timer and delay. This works fine for a few dozen minutes until it simply stalls. I don't get any change events anymore at all, the rest of the application runs fine. I suspect that the cause is 'tmr.now()' which behaves not as you'd expect (https://github.com/nodemcu/nodemcu-firmware/issues/690).
Code: Select all
-- source: https://github.com/hackhitchin/esp8266-co-uk/blob/master/tutorials/introduction-to-gpio-api.md
local pin = 4 --> GPIO2
function debounce (func)
local last = 0
local delay = 200000
return function (...)
local now = tmr.now()
if now - last < delay then return end
last = now
return func(...)
end
end
function onChange ()
print('The pin value has changed to '..gpio.read(pin))
end
gpio.mode(pin, gpio.INT, gpio.PULLUP)
gpio.trig(pin, 'both', debounce(onChange))
The next attempt was to do it simple and straight forward by registering two separate functions for GPIO up/down events. This runs stable for days. However, a few times per day I get 'down' events even though the switch wasn't triggered physically at all.
Code: Select all
-- inspired by: http://www.esp8266-projects.com/2015/03/buttons-pushbuttons-and-debouncing-story.html
local GPIO14 = 5
gpio.mode(GPIO14, gpio.INT, gpio.PULLUP)
gpio.trig(GPIO14, "down", doorLocked)
function doorLocked()
print("Door locked")
tmr.delay(50) -- time delay for switch debounce
gpio.trig(GPIO14, "up", doorUnlocked) -- change trigger on falling edge
end
function doorUnlocked()
print("Door unlocked")
tmr.delay(50)
gpio.trig(GPIO14, "down", doorLocked) -- trigger on rising edge
end
Could it be that the false 'down' event has nothing to do with the debounce at all but is simply a characteristic of the reed switch?