Module 如何使KY-022红外接收器模块在Lua的NodeMCU上工作?

Module 如何使KY-022红外接收器模块在Lua的NodeMCU上工作?,module,lua,nodemcu,infrared,Module,Lua,Nodemcu,Infrared,我有一个KY-022红外模块,我无法在我的NodeMCU上工作。我一直在互联网上搜索Lua中的一些代码示例,但运气不好。谁能给我指出正确的方向吗?任何代码示例都将不胜感激 目前,我有以下代码: local pin = 4 gpio.mode(pin, gpio.OPENDRAIN, gpio.PULLUP) gpio.trig(pin, "down", function (level, micro) print(gpio.read(pin), level, micro) end) 当我

我有一个KY-022红外模块,我无法在我的NodeMCU上工作。我一直在互联网上搜索Lua中的一些代码示例,但运气不好。谁能给我指出正确的方向吗?任何代码示例都将不胜感激

目前,我有以下代码:

local pin = 4
gpio.mode(pin, gpio.OPENDRAIN, gpio.PULLUP)
gpio.trig(pin, "down", function (level, micro)
    print(gpio.read(pin), level, micro)
end)
当我按下遥控器上的一个按钮时,我得到如下结果:

0 0 571940709
0   0   571954086
0   0   571955257
1   0   571958694
1   0   571963275
1   0   571969917
0   0   571974347
0   0   571980989
1   0   571983203
1   0   571987709
0   0   571993359
1   0   572000078
0   0   572004508
0   0   572047513
0   0   572058674

那么,我如何才能从中找出遥控器上按下了哪个键呢

大约一个月后,我重新开始了这个项目,并对它进行了更多的研究。正如小猪建议的那样,我开始听高信号和低信号。数据仍然非常不一致,无法获得稳定的读数

(顺便说一句,谢谢你投票否决了《小猪》,我非常感激。我希望你在认定我无知之前能看看我的搜索历史。)

我要发布我现在的代码,也许有人能指出我做错了什么

local pin = 4
local prevstate = false
local prevmicro = 0
local prevtime = 0
local count = 0

gpio.mode(pin, gpio.INT)
gpio.trig(pin, "both", function (level, micro)
    --local state = gpio.read(pin)
    local state = level
    if (micro - prevmicro) > 90000 then
        prevmicro = 0
        prevstate = false
        count = 0
        print("\n#", "st", "lv", "microtime", "timing")
    end
    if prevstate ~= state then
        time = math.floor((micro - prevmicro)/100)
        prevstate = state
        prevmicro = micro
        if time > 3 and time < 1000 then
            if prevtime > 80 and prevtime < 100 then
                if time > 17 and time < 25 then
                    print('Repeat')
                elseif time > 40 and time < 50 then
                    print('Start')
                end
            else
                print(count, gpio.read(pin), level, micro, time)
                count = count + 1
            end
            prevtime = time
        end
    end
end)

您必须获得遥控器为每个按钮发送的序列

通过记录高-低和低-高转换的时间戳,记录IR发射器的开关顺序

请注意要使用或模拟的每个按钮的各种模式

这里有一个深入的教程


您可以在www.google.com上找到这些和类似的资源,事实证明,这所需的Lua代码实际上非常简单

上面的代码实际上是打印语句。这些都是非常昂贵的,基本上,杀死你的采样分辨率,直到它是无用的

本质上,您正在编写一个中断服务例程,在读取下一个边缘更改之前,您的时间预算有限,如果它发生在您完成处理之前,那就太倒霉了!因此,您需要尽可能提高ISR的效率

在下面的示例中,我们收听“两个”边缘事件,当一个边缘事件发生时,我们只需记录哪个边缘和持续时间的指示

我们定期(使用计时器)打印波形的内容

这与我的逻辑分析仪上的波形完全匹配,您仍然面临解码信号的挑战。不过,有很多很棒的协议文档解释了如何获取准确的波形数据并使用它来确定发送的信号。我发现很多便宜的“x品牌”遥控器似乎都在使用NEC协议,所以根据您的项目,这可能是一个开始的好地方

红外传输,因为它的性质是不完全无错误的,所以你可能会不时得到一个虚假的边缘信号,但下面的代码是相当稳定的,运行相当好的隔离,我还没有测试它时,微控制器是在更多的负载下,而不仅仅是听红外

事实可能证明,出于这个目的使用Lua并不是最好的,因为它是一种解释语言(发出的每个命令都被解析,然后在运行时执行,这一点都不高效)。但在我决定编写c模块之前,我将看看我能走多远

local irpin = 2
local lastTimestamp = 0
local waveform = {}
local i = 1

gpio.mode(irpin,gpio.INT)
gpio.trig(irpin, "both", function(level, ts)
    onEdge(level, ts)
end)

function onEdge(level, ts)
    waveform[i] = level
    waveform[i+1] = ts - lastTimestamp
    lastTimestamp = ts
    i = i+2   
end

-- Print out the waveform
function showWaveform ()
    if table.getn(waveform) > 65 then
        for k,v in pairs(waveform) do
            print(k,v)
        end
        i = 1;
        waveform = {}
    end
end
tmr.alarm(0, 1000, 1, showWaveform)

print("Ready")

下面的代码适用于我的17键遥控器,它与我的廉价KY-022模块一起提供。我刚刚完成它,还没有时间清理它,也没有时间优化它,所以请容忍我

local IR = 2
local lts, i, wave = 0, 0, {}

local keys = {}
keys['10100010000000100000100010101000'] = '1'
keys['10001010000000100010000010101000'] = '2'
keys['10101010000000100000000010101000'] = '3'
keys['10000010000000100010100010101000'] = '4'
keys['10000000000000100010101010101000'] = '5'
keys['10101000000000100000001010101000'] = '6'
keys['10101010000000000000000010101010'] = '7'
keys['10100010001000000000100010001010'] = '8'
keys['10100000100000000000101000101010'] = '9'
keys['10100000101000000000101000001010'] = '0'
keys['10001010001000000010000010001010'] = '*'
keys['10100010100000000000100000101010'] = '#'
keys['10000000101000000010101000001010'] = 'U'
keys['10000000100000000010101000101010'] = 'L'
keys['10001000101000100010001000001000'] = 'R'
keys['10001000001000100010001010001000'] = 'D'
keys['10000010101000000010100000001010'] = 'OK'

local function getKey()
    local data = ''
    local len = table.getn(wave)
    if len >= 70 then

        local pkey = 0
        local started = false
        for k, v in pairs(wave) do
            v = math.floor(v/100)
            if (pkey == 87 or pkey == 88 or pkey == 89) and (v > 40 and v < 50) then
                started = true
            end
            pkey = v
            if started then
                if v > 300 then
                    started = false
                end
                --this is just to fix some random skipped edges
                if (v > 20 and v < 25) or v == 11 then
                    if v > 20 and v < 25 then
                        d = 17
                    else
                        d = 6
                    end
                    v1 = v - d
                    data = data .. '' .. math.floor(v1/10)

                    v2 = v - (v - d)
                    data = data .. '' .. math.floor(v2/10)
                else
                    if v < 40 then
                        data = data .. '' .. math.floor(v/10)
                    end
                end
            end
        end
        control = data:sub(0, 32)
        if control == '00000000000000000101010101010101' then
            data = data:sub(32, 63)
            print(len, data, keys[data] or '?')
        end
    end
    lts, i, wave = 0, 0, {}
end

local function onEdge(level, ts)
    local time = ts - lts
    wave[i] = time
    i = i + 1
    if time > 75000 then
        tmr.alarm(0, 350, 0, getKey)
    end
    lts = ts
end

gpio.mode(IR,gpio.INT)
gpio.trig(IR, "both", onEdge)
本地IR=2
局部lts,i,wave=0,0,{}
本地键={}
键['1010001000001000001000001001000']=“1”
键['1000101000000010001000010101000']=“2”
键['101010100000000000010101000']='3'
键['10000100000100010100010100010101000']=“4”
键['100000000000100010101010101000']='5'
键['10101000000000100000001010101000']='6'
键['10101010000000000000010101010']='7'
键['10100010000000100000001010']='8'
键['10100001000000000001000001010']='9'
键['1010000010000000010000010000010010']='0'
键['1000101000100000100000110010']='*'
键['1010000100000000000101000001010']='#'
键['1000000100000001010100001010']='U'
键['1000000100000000101010000101010']='L'
键['10001010001000010000100001000']='R'
键['1000000010001000010000100001000']='D'
键['1000001010000010100000010']='OK'
本地函数getKey()
本地数据=“”
本地len=table.getn(波形)
如果len>=70,则
本地pkey=0
本地启动=错误
对于k,v成对(波)do
v=数学楼层(v/100)
如果(pkey==87或pkey==88或pkey==89)和(v>40和v<50),则
开始=真
结束
pkey=v
如果从那时开始
如果v>300,则
开始=错误
结束
--这只是为了修复一些随机跳过的边
如果(v>20且v<25)或v==11,则
如果v>20且v<25,则
d=17
其他的
d=6
结束
v1=v-d
数据=数据“。。数学地板(v1/10)
v2=v-(v-d)
数据=数据“。。数学楼层(v2/10)
其他的
如果v<40,则
数据=数据“。。数学楼层(v/10)
结束
结束
结束
结束
控制=数据:子(0,32)
如果控件==“00000000000000000101010101010101”,则
数据=数据:sub(32,63)
打印(透镜、数据、键[数据]或“?”)
结束
结束
lts,i,wave=0,0,{}
结束
本地功能OneEdge(级别,ts)
本地时间=ts-lts
波[i]=时间
i=i+1
如果时间>75000,则
tmr.警报(0、350、0、getKey)
结束
lts=ts
结束
G
local IR = 2
local lts, i, wave = 0, 0, {}

local keys = {}
keys['10100010000000100000100010101000'] = '1'
keys['10001010000000100010000010101000'] = '2'
keys['10101010000000100000000010101000'] = '3'
keys['10000010000000100010100010101000'] = '4'
keys['10000000000000100010101010101000'] = '5'
keys['10101000000000100000001010101000'] = '6'
keys['10101010000000000000000010101010'] = '7'
keys['10100010001000000000100010001010'] = '8'
keys['10100000100000000000101000101010'] = '9'
keys['10100000101000000000101000001010'] = '0'
keys['10001010001000000010000010001010'] = '*'
keys['10100010100000000000100000101010'] = '#'
keys['10000000101000000010101000001010'] = 'U'
keys['10000000100000000010101000101010'] = 'L'
keys['10001000101000100010001000001000'] = 'R'
keys['10001000001000100010001010001000'] = 'D'
keys['10000010101000000010100000001010'] = 'OK'

local function getKey()
    local data = ''
    local len = table.getn(wave)
    if len >= 70 then

        local pkey = 0
        local started = false
        for k, v in pairs(wave) do
            v = math.floor(v/100)
            if (pkey == 87 or pkey == 88 or pkey == 89) and (v > 40 and v < 50) then
                started = true
            end
            pkey = v
            if started then
                if v > 300 then
                    started = false
                end
                --this is just to fix some random skipped edges
                if (v > 20 and v < 25) or v == 11 then
                    if v > 20 and v < 25 then
                        d = 17
                    else
                        d = 6
                    end
                    v1 = v - d
                    data = data .. '' .. math.floor(v1/10)

                    v2 = v - (v - d)
                    data = data .. '' .. math.floor(v2/10)
                else
                    if v < 40 then
                        data = data .. '' .. math.floor(v/10)
                    end
                end
            end
        end
        control = data:sub(0, 32)
        if control == '00000000000000000101010101010101' then
            data = data:sub(32, 63)
            print(len, data, keys[data] or '?')
        end
    end
    lts, i, wave = 0, 0, {}
end

local function onEdge(level, ts)
    local time = ts - lts
    wave[i] = time
    i = i + 1
    if time > 75000 then
        tmr.alarm(0, 350, 0, getKey)
    end
    lts = ts
end

gpio.mode(IR,gpio.INT)
gpio.trig(IR, "both", onEdge)