Skip to content

Instantly share code, notes, and snippets.

@mbainrot
Created February 23, 2015 09:41
Show Gist options
  • Save mbainrot/ce492eedd3aba1727b4d to your computer and use it in GitHub Desktop.
Save mbainrot/ce492eedd3aba1727b4d to your computer and use it in GitHub Desktop.
Work in progress script, having problems with debouncing and reliable triggering
m = mqtt.Client()
-- Configuration
host = "172.16.4.50"
port = 1883
queue = "/hello_8266"
bounceTimeout = 200
targetGpIO = 5
-- Internal Variables
bAntiBounce = 0
bMqttOnline = 0
m:on("connect",function(con)
m:subscribe("/hello_8266",0)
tmr.alarm(1,150,0,function()
m:publish(queue,"!hello|" .. wifi.sta.getmac(),0,0)
end)
bMqttOnline = 1
end)
m:on("offline",function(con)
print ("offline")
bMqttOnline = 0
tmr.alarm(1,1500,0,function()
print("Reconnecting...")
m:connect(host,port,0)
end)
end)
m:on("message",function(con,topic,message)
if message == "!ping" then
m:publish(queue,"!pong",0,0)
end
end)
-- Wait until the ip address is done
tmr.alarm(0,500,1,function()
ipaddr = wifi.sta.getip()
print(ipaddr)
if ipaddr == nil then
-- Nothing to see here...
else
tmr.stop(0)
m:connect(host,port,0)
print("Found an IP!")
end
end)
function trigger (level)
if bAntiBounce == 0 and level == 0 then
-- bAntiBounce = 1
-- tmr.alarm(3,bounceTimeout,0,function()
-- bAntiBounce = 0
-- end)
if (bMqttOnline == 1) then
m:publish(queue,"!event|" .. wifi.sta.getmac() .. "|button1|" .. gpio.read(targetGpIO),0,0)
end
end
if level == 1 then gpio.trig(targetGpIO, "down") else gpio.trig(targetGpIO, "up") end
end
gpio.mode(targetGpIO,gpio.INT)
gpio.trig(targetGpIO,"up",trigger)
print("Ready to go!")
@mbainrot
Copy link
Author

Noting I disabled my first attempt at debouncing because i found it was unreliable at detecting a rising edge

@AlexSatrapa
Copy link

Here is an example of a better debounce method — use the interrupt to trigger a poll of the button GPIO. Every time you poll the button, increment a "button is pressed" counter if the button is pressed, decrement the counter if the button is open. If you hit the target (in the example, 5 polling cycles), consider the button pressed.

Back to your code though: how did it display the behaviour of being "unreliable at detecting a rising edge"? Note that what you are publishing in line 61 is the current value of the GPIO at the time the m:publish line is executed. This could be anything at all, since the switch might still be bouncing. So you're going to the effort of attempting to debounce the switch, but then just taking whatever value the switch displays afterwards.

To extend your example along the lines of the debouncing example, I would declare the (anonymous?) function that increments or decrements the bAntiBounce counter based on the GPIO, then pass that function into six sequential 2ms timers. This means you have 7 samples taken at approximately 2ms intervals. If your bAntiBounce is greater than the starting value, your switch is on, otherwise it's off.

Something along the lines of:

bAntiBounce=5
bounce_count = function()
    bAntiBounce += (gpio.read(targetGpIO))? 1 : -1; // is the switch more on-ish or off-ish?
end
tmr.alarm(2, bounceTimeout, 0, bounce_count)
tmr.alarm(2, bounceTimeout, 0, bounce_count)
tmr.alarm(2, bounceTimeout, 0, bounce_count)
tmr.alarm(2, bounceTimeout, 0, bounce_count)
tmr.alarm(2, bounceTimeout, 0, bounce_count)
button_state = (bAntiBounce > 5) ? 1 : 0

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