NodeMCU gpio 触发错误

我正在尝试从运行 Lua 5.1.4 版本的 NodeMCU 上读取 IR 信息,该版本是自 2017 年 8 月 19 日的主版本构建而成。

我可能误解了 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

-- 例子
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 的工作原理。如果这是预期的,为什么如果低/高电平没有发生变化,中断仍然会被多次调用?如果这似乎是错误的,有什么办法可以解决?

点赞
用户131929
用户131929

我明显做错了些什么或者根本不理解 GPIO 的工作方式。

我怀疑两者结合在一起是导致前者的原因。

就写 GPIO 的软件而言,我的解释可能并非从机械/电子角度完全正确(这不是我的专业领域),但对于 GPIO,这已足够了。开关在最终选择一个状态之前会在 0 和 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 是特定传感器/开关的经验值!

2017-08-21 07:35:45