我正在尝试从截至2017年8月19日的主构建中运行Lua 5.1.4的NodeMCU读取IR信息。
我可能误解了GPIO是如何工作的,而且我很难找到与我正在做的事情有关的例子。
pin = 4
pulse_prev_time = 0
irCallback = nil
function trgPulse(level, now)
gpio.trig(pin, level == gpio.HIGH and "down" or "up", trgPulse)
duration = now - pulse_prev_time
print(level, duration)
pulse_prev_time = now
end
function init(callback)
irCallback = callback
gpio.mode(pin, gpio.INT)
gpio.trig(pin, 'down', trgPulse)
end
-- example
print("Monitoring IR")
init(function (code)
print("omg i got something", code)
end)
我在低电平时触发初始中断,然后在trgPulse
中从低电平变为高电平。在这样做时,我希望水平在完美模式中从1到0交替。但输出显示不然:
1 519855430
1 1197
0 609
0 4192
0 2994
1 589
1 2994
1 1198
1 3593
0 4201
1 23357
0 608
0 5390
1 1188
1 4191
1 1198
0 3601
0 3594
1 25147
0 608
1 4781
0 2405
1 3584
0 4799
0 1798
1 1188
1 2994
所以我显然做错了什么或从根本上不明白GPIO是如何工作的。如果这是预期的,如果低/高电平没有改变,为什么要多次调用中断?如果这看起来不对,任何想法如何解决它?
答案 0 :(得分:0)
我明显做错了什么或从根本上不了解GPIO的运作方式
我怀疑它有点是两者的结合 - 后者可能是前者的原因。
从机械/电子角度(不是我的世界),我的解释可能不是100%正确,但就编写GPIO软件而言,它应该足够了。开关往往会在0到1之间反弹,直到它们最终稳定为1。阅读这篇文章的好文章是https://www.allaboutcircuits.com/technical-articles/switch-bounce-how-to-deal-with-it/。可以使用硬件和/或软件解决该问题。
使用软件进行操作通常需要引入某种形式的延迟来跳过弹跳信号,因为您只对“已解决的状态”感兴趣。我在https://gist.github.com/marcelstoer/59563e791effa4acb65f
记录了我使用的NodeMCU Lua函数-- 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))
注意:delay
是特定于传感器/开关的经验值!