micropython红外接收与发送

前言

最近回南天,想给以前买的小除湿机加个远程遥控功能。之前买的小除湿机已经配了红外遥控,于是在淘宝上买了个红外接收模块跟发送模块。参考了一下pico_ir的库(https://github.com/bartoszadamczyk/pico-ir)。

nec编码分析

大部分遥控器用的都是nec编码。nec编码的每个数据帧由32位组成。起始标志是一个9ms的Leader脉冲和一个4.5ms的Space脉冲。我们只要在收到脉冲后等待数据帧,对接收到的信号进行采样,分析低电平信号的长度就能进行解码。

折腾

录制红外信号

红外接收模块有三根针脚,分别是gnd、vcc、out,将gnc vcc与板子连好后,out随便与一个pwm针脚相连。
下面是测试的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import utime
from machine import Pin
pin_in = Pin(23, Pin.IN, Pin.PULL_UP) # 引脚23作为输入,设置为上拉
def read_code(pin):
raw = []

# 上拉默认是高电平状态,当被拉低的时候继续下面的逻辑
while pin.value() == 1:
pass

# nec编码 起始标志是一个9ms的Leader脉冲和一个4.5ms的Space脉冲
utime.sleep_us(13500)

# nec编码 562.5µs是38kHz载波频率下的一个周期
for i in range(1000):
raw.append(pin.value())
utime.sleep_us(56)

# 一个逻辑0由一个基准时间单元的高电平脉冲和一个基准时间单元的低电平脉冲组成,而一个逻辑1由一个基准时间单元的高电平脉冲和三个基准时间单元的低电平脉冲组成,也就是说我们可以用高电平信号作为分割,统计低电平信号的长度就能解码
code = ""
count = 0

for sample in raw:
if sample == 1:
# 计算低电平信号
count += 1
else:
# 高电平信号就是一个分隔
if count > 0:
# 低电平的信号长度大于562.5µs就是逻辑1 否则就是逻辑0
code += "1" if count > 10 else "0"
count = 0

# nec编码一共有32位
return code[0:32]


while True:
out = read_code(pin_in)
print(out)
utime.sleep(3)

发送红外信号

红外发射模块也是有三个针脚,下面是测试的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from machine import PWM, Pin
import utime

HIGH_SIGNAL = int((2 ** 16) / 2)
LOW_SIGNAL = 0
pin_out = Pin(23, mode=Pin.OUT)

def send_code(pin, code, freq=38000):
pwm = PWM(pin)
pwm.freq(freq)

# 产生9ms的leader脉冲
pwm.duty_u16(HIGH_SIGNAL)
utime.sleep_us(9000)

# 4.5ms的space脉冲
pwm.duty_u16(LOW_SIGNAL)
utime.sleep_us(4500)

# 逻辑0由一个基准时间单元的高电平脉冲和一个基准时间单元的低电平脉冲组成
# 逻辑1由一个基准时间单元的高电平脉冲和三个基准时间单元的低电平脉冲组成
for bit in code:
pwm.duty_u16(HIGH_SIGNAL)
utime.sleep_us(562)
pwm.duty_u16(LOW_SIGNAL)
utime.sleep_us(1687 if bit == "1" else 562)

# 停止位的持续时间是一个基准时间单元的高电平脉冲
pwm.duty_u16(HIGH_SIGNAL)
utime.sleep_us(562)
pwm.duty_u16(LOW_SIGNAL)
pwm.deinit()

while True:
send_code(pin_out,'00000001111111100100100010110111')
utime.sleep(15)
send_code(pin_out,'00000001111111100111100010000111')
utime.sleep(15)
send_code(pin_out,'00000001111111100010000011011111')
utime.sleep(15)

小结

经过测试确实能够解码&遥控身边的一些电器,只要esp32或者树莓派pico能连上WiFi,那么我就能够远程遥控了,又开了新的坑。

作者

ZhongHuihong

发布于

2024-04-14

更新于

2024-04-14

许可协议