【问题标题】:NodeMCU gpio triggering incorrectlyNodeMCU gpio 触发不正确
【发布时间】:2018-01-28 11:26:57
【问题描述】:

我正在尝试从 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 的工作原理。如果这是预期的,如果低/高电平没有改变,为什么会多次调用中断?如果这看起来确实有问题,有什么想法可以解决它吗?

【问题讨论】:

  • 我不熟悉那个平台,但你确定你没有在 IR 输入上听到噪音吗?我要做的第一件事是断开它并将输入连接到地,看看会发生什么。也不确定该平台,但在某些微控制器上,更改中断边沿在中断例程中效果不佳,如果您有备用输入,则可以将两者都连接到 IR 接收器并为每个边沿设置一个。
  • 读取 IR 信息是什么意思?你用什么连接到引脚 4?
  • 我怀疑我听到了噪音,我只在点击遥控器上的按钮后立即看到数据中断变化。它在我按下按钮的过程中持续,所以它看起来相当稳定。我有一个红外接收器连接到针脚 4。

标签: lua esp8266 gpio nodemcu


【解决方案1】:

我显然做错了什么或根本不了解 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 是特定于传感器/开关的经验值!

【讨论】:

  • 听起来很有可能。我会试试看!
猜你喜欢
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 2022-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多