-
-
Save mbainrot/ce492eedd3aba1727b4d to your computer and use it in GitHub Desktop.
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!") |
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
Noting I disabled my first attempt at debouncing because i found it was unreliable at detecting a rising edge