电视遥控器、空调遥控器、投影仪遥控器……这些遥控器都是用红外信号来传递指令的。
今天这节课,我们就来学习如何用ESP32接收红外信号,让ESP32能“看懂”遥控器按了哪个键。
学会了这节课,你就能用任意遥控器来控制ESP32——开灯、关灯、播放音乐、调节音量……统统不在话下!
第一步:找到课程,看看成品效果
打开逗脑IDE,点击顶部“文档”,在“课程” → “ESP32 + MicroPython”分类下,找到红外接收。
打开课件,你会看到本节课的最终效果:按下遥控器上的任意按键,ESP32的终端立刻打印出对应的按键名称——“1”、“2”……
第二步:红外遥控的原理
发送端(遥控器):
当你按下遥控器上的按键时,遥控器会发出一串红外光信号,这串信号叫做一帧数据。
一帧数据包含:
- 前导码:9ms高电平 + 4.5ms低电平,告诉接收器“我要开始发数据了”
- 用户码(16位):标识遥控器身份,防止不同设备的遥控器互相干扰
- 数据码(8位):标识具体按了哪个按键
- 数据反码(8位):用于校验数据是否正确
接收端(ESP32 + 红外接收头):
红外接收头将光信号转换为电信号,ESP32解码后就知道按了哪个键。
第三步:什么是中断?
在学习代码之前,先认识一个非常重要的概念——中断。
用大白话解释:
你正在看书(正常执行程序),突然手机响了(中断事件),你放下书去接电话(执行中断处理函数),接完电话继续看书(回到原来程序)。
为什么需要中断?
如果没有中断,程序只能一直盯着某个引脚,等待数据到来(堵塞式检测)。这样一来,程序什么都干不了,效率极低。
使用中断后,程序可以正常执行其他任务,当红外信号到来时,ESP32会自动暂停当前任务,去处理红外数据,处理完再回来继续。这就是中断的价值——不浪费CPU,响应还快。
MicroPython中配置中断:
pin.irq(trigger=触发条件,handler=回调函数)trigger:触发中断的条件(上升沿、下降沿或两者)handler:中断发生后要执行的函数
第四步:动手接线
红外接收模块只有3个引脚,接线非常简单:
| 红外接收头引脚 | 连接ESP32 | 说明 |
|---|---|---|
| VCC | 3.3V | 电源正极 |
| GND | GND | 电源地 |
| OUT | GPIO15 | 信号输出(接中断引脚) |
第五步:代码——中断 + 解码
importmachineimportutimefrommachineimportPinclassIR(object):CODE={162:"ch-",98:"ch",226:"ch+",34:"prev",2:"next",194:"play/stop",152:"0",104:"*",176:"#",224:"-",168:"+",144:"EQ",104:"0",152:"100+",176:"200+",48:"1",24:"2",122:"3",16:"4",56:"5",90:"6",66:"7",74:"8",82:"9"}def__init__(self,gpioNum):self.irRecv=machine.Pin(gpioNum,machine.Pin.IN,machine.Pin.PULL_UP)self.irRecv.irq(trigger=machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING,handler=self.__handler)# 配置中断信息self.ir_step=0self.ir_count=0self.buf64=[0foriinrange(64)]self.recived_ok=Falseself.cmd=Noneself.cmd_last=Noneself.repeat=0self.repeat_last=Noneself.t_ok=Noneself.t_ok_last=Noneself.start=0self.start_last=0self.changed=Falsedef__handler(self,source):""" 中断回调函数 """thisComeInTime=utime.ticks_us()# 更新时间curtime=utime.ticks_diff(thisComeInTime,self.start)self.start=thisComeInTimeifcurtime>=8500andcurtime<=9500:self.ir_step=1returnifself.ir_step==1:ifcurtime>=4000andcurtime<=5000:self.ir_step=2self.recived_ok=Falseself.ir_count=0self.repeat=0elifcurtime>=2000andcurtime<=3000:# 长按重复接收self.ir_step=3self.repeat+=1elifself.ir_step==2:# 接收4个字节self.buf64[self.ir_count]=curtime self.ir_count+=1ifself.ir_count>=64:self.recived_ok=Trueself.t_ok=self.start#记录最后ok的时间self.ir_step=0elifself.ir_step==3:# 重复ifcurtime>=500andcurtime<=650:self.repeat+=1def__check_cmd(self):byte4=0foriinrange(32):x=i*2t=self.buf64[x]+self.buf64[x+1]byte4<<=1ift>=1800andt<=2800:byte4+=1user_code_hi=(byte4&0xff000000)>>24user_code_lo=(byte4&0x00ff0000)>>16data_code=(byte4&0x0000ff00)>>8data_code_r=byte4&0x000000ffself.cmd=data_codedefscan(self):# 接收到数据ifself.recived_ok:self.__check_cmd()self.recived_ok=False# 数据有变化ifself.cmd!=self.cmd_lastorself.repeat!=self.repeat_lastorself.t_ok!=self.t_ok_last:self.changed=Trueelse:self.changed=False# 更新self.cmd_last=self.cmd self.repeat_last=self.repeat self.t_ok_last=self.t_ok# 对应按钮字符print(self.cmd)s=self.CODE.get(self.cmd)returnself.changed,s,self.repeat,self.t_okif__name__=="__main__":t=IR(15)while(True):changed,s,repeat,t_ok=t.scan()print(changed,s,repeat,t_ok)utime.sleep(0.2)代码核心逻辑:
| 函数 | 作用 |
|---|---|
__init__ | 初始化引脚,配置中断 |
__handler | 中断回调函数,记录每个脉冲的时间间隔 |
__check_cmd | 将64个脉冲数据解码为4个字节 |
scan | 返回解码后的按键信息 |
第六步:保存运行,拿起遥控器试试!
按Ctrl + S保存,选择ESP32开发板设备,给文件命名(比如ir_receiver.py),点击保存。
点击运行按钮,终端显示日志。
拿起红外遥控器,对准接收头,按下按键,观察终端日志的变化:
红外接收能做什么?
| 应用场景 | 用途 |
|---|---|
| 智能家居控制 | 用遥控器控制灯光、风扇、空调 |
| 万能遥控器 | ESP32学习并模拟各种遥控器信号 |
| 红外防盗报警 | 检测到红外信号变化触发报警 |
| 互动装置 | 用遥控器控制音乐播放、LED效果切换 |
| 智能电视盒子 | 自制红外遥控的媒体播放器 |
全程回顾
| 步骤 | 操作 | 效果 |
|---|---|---|
| 找到课程 | 文档→课程→ESP32+MicroPython→红外接收 | 了解红外接收 |
| 认识原理 | 学习前导码、用户码、数据码 | 理解红外数据格式 |
| 认识中断 | 理解“暂停当前任务去处理紧急事件” | 知道为什么要用中断 |
| 动手接线 | VCC→3.3V, GND→GND, OUT→GPIO15 | 硬件就位 |
| 打开代码 | 点击“打开”按钮 | 代码进入编辑器 |
| 保存运行 | Ctrl+S → 选择ESP32 → 运行 | 开始监听红外信号 |
| 按遥控器 | 按下任意按键 | 终端打印按键名称! |
如果你对本节课感兴趣,去官网(www.dounao.cn)下载逗脑IDE,准备好相关配件,跟着课件走一遍。
有任何问题或建议,欢迎在评论区留言告诉我们。