Skip to content

Instantly share code, notes, and snippets.

@marcelstoer
Last active December 7, 2019 06:05
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save marcelstoer/59563e791effa4acb65f to your computer and use it in GitHub Desktop.
Save marcelstoer/59563e791effa4acb65f to your computer and use it in GitHub Desktop.
NodeMCU debounce based on timer with GPIO pullup
-- inspired by https://github.com/hackhitchin/esp8266-co-uk/blob/master/tutorials/introduction-to-gpio-api.md
-- and http://www.esp8266.com/viewtopic.php?f=24&t=4833&start=5#p29127
local pin = 4 --> GPIO2
function debounce (func)
local last = 0
local delay = 50000 -- 50ms * 1000 as tmr.now() has μs resolution
return function (...)
local now = tmr.now()
local delta = now - last
if delta < 0 then delta = delta + 2147483647 end; -- proposed because of delta rolling over, https://github.com/hackhitchin/esp8266-co-uk/issues/2
if delta < 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) -- see https://github.com/hackhitchin/esp8266-co-uk/pull/1
gpio.trig(pin, 'both', debounce(onChange))
@pastukhov
Copy link

Thanks for the solution, but i can't it compile with

> node.compile('button.lua')
stdin:1: value too big or small for target integer type
stack traceback:
	[C]: in function 'compile'
	stdin:1: in main chunk
> 

@marcelstoer
Copy link
Author

Hhhmm, not much to work with... "value too big" - which value?

@vsky279
Copy link

vsky279 commented Jul 30, 2017

Can't compile issue is discussed in #1691.

@shinji2009
Copy link

if you need to make something work on push then change
print('The pin value has changed to '..gpio.read(pin))
to
if (gpio.read(pin)) == 0 then dofile("yourfile.lua") end
or if you need to make something work on release then change to
if (gpio.read(pin)) == 1 then dofile("yourfile.lua") end

@shinji2009
Copy link

aaaaaaaaaand can't make this work flawlessly to. it is work for micro switch from mouse, but still send two of three on big red stop button or microwave terminal switch, with any local delay. maybe i miss something or something has changed very bad in modemcu since time this script was released :c

@Bop4yN
Copy link

Bop4yN commented May 27, 2018

How is it supposed to work with
local last = 0
Every call of debounce function will set last to 0. And delta will always be equal to now. So delta < delay will never become true.

Or am I missing something?

@xuehaoying
Copy link

xuehaoying commented Jun 21, 2018

I'm using the same routine for debouncing and the switch is having issues with controlling inductive loads. The button would get triggered as soon as the relay is switched remotely. I think the code would need to include some kind of logic to detect minimum time the button is pressed.

Also there is some chance (0.002%) that the code doesn't respond to button press due to the rollover of tmr.now() and the initial value of "last". Obviously not a problem for majority of applications but good to keep in mind.

@marcelstoer
Copy link
Author

@Bop4yN you're missing that debounce returns a function (line 9-17). So, every time the GPIO triggers it doesn't run debounce but the function it returned when it was once (i.e. initially) called. That inner function has access to last and keeps changing it.

-> https://en.wikipedia.org/wiki/Closure_(computer_programming)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment