ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ESP32-S3红外遥控器实战教程:从原理到智能家居应用

ESP32-S3红外遥控器实战教程:从原理到智能家居应用 大家好很久没有更新 ESP32 系列实战教程了。之前不少朋友在做智能家居遥控方案时都会纠结一个问题家里的空调、电视、风扇遥控器太多能不能用一个设备统一控制答案是可以的ESP32-S3 就是一个非常合适的硬件平台。这篇文章我准备手把手带大家完成一个 ESP32-S3 红外遥控器既能学习红外通信原理又能做出一台可以学习、发射红外信号的小设备。无论你是刚开始接触 ESP32-S3 开发还是想给自己的项目增加红外控制能力这篇文章都能给你一套完整的闭环思路。1. 红外遥控器与 ESP32-S3 开发背景1.1 为什么选择 ESP32-S3 做红外遥控器先聊一个问题市面上几块钱就能买到红外遥控器为什么还要自己用开发板做常规遥控器的逻辑是固定的按键发什么码、按键布局是什么样出厂就写死了。如果家里设备多桌面上可能摆着电视遥控器、机顶盒遥控器、空调遥控器、风扇遥控器。每一只遥控器内部一般是一颗几毛钱的 MCU 加红外发射管功能单一没法互相兼容。用 ESP32-S3 做红外遥控器核心优势在于可编程、可学习、可联网。可编程你可以把任意按键映射到任意红外编码甚至用手机 App、网页端、小爱同学语音来控制。可学习通过外接红外接收头记录家里已有遥控器的原始红外码再用发射管复现。可联网ESP32-S3 自带 Wi-Fi 和 BLE这意味着一台设备可以变成局域网内的红外网关手机远程控制红外家电。所以这个项目不仅是一个玩具它本质上是一个“万能红外遥控器 智能家居红外网关”的雏形。1.2 红外遥控的基本原理红外遥控利用红外线Infrared波长一般在 940nm 左右作为载波遥控器把按键编码调制到 38kHz 左右的载波频率上通过发射管发出。接收端比如电视面板上的红外接收头解调出编码数据然后执行对应操作。人眼看不到红外光但如果你拿手机摄像头对着红外发射管按下按键时通常可以看到紫色或白色的光点。这是一个很实用的硬件自检技巧。常见的红外协议有很多NEC、Sony SIRC、Philips RC-5、RC-6、Sharp、三星等。国内家电尤其是电视、机顶盒、风扇很多都采用 NEC 协议或 NEC 变种。NEC 协议的特征是一帧数据包含引导码9ms 低电平 4.5ms 高电平地址码 8 位地址反码 8 位命令码 8 位命令反码 8 位每位数据用 560us 脉冲 1.69ms 或 2.25ms 间隔区分 0 和 1后面我们写代码时会使用现成的 IRremote 库来处理协议细节但理解这个时序对排查问题非常重要。因为很多“发射了但设备没反应”的故障本质上是载波频率不对、发射管驱动电流不够或者时序被中断破坏了。1.3 本项目适合哪些读者这个项目属于软硬件结合的嵌入式入门实战适合以下人群正在学 ESP32 或 ESP32-S3想做点实际硬件的同学想把家里遥控器统一管理折腾智能家居的爱好者打算做“红外学习遥控器”产品原型、毕设项目的开发者完成本文之后你可以掌握硬件接线、NEC 协议收发、IRremote 库使用、红外码学习与重新发射以及一套排查硬件问题的思路。2. 环境准备与硬件清单2.1 硬件清单做这个项目不需要特别昂贵的设备大部分材料都能在开发板商店一次性买到。硬件型号/规格数量用途开发板ESP32-S3 DevKitC 或兼容板1主控红外发射管5mm 940nm 红外发射管1-2发射红外信号三极管S8050 NPN 三极管1驱动发射管电阻1kΩ 1 个、10Ω 或 22Ω 1 个若干限流、偏置红外接收头HS0038B 或 VS1838B1学习红外码面包板400 或 800 孔1接线调试杜邦线公对母、公对公若干连接电路OLED 显示屏0.96 寸 I2C SSD1306可选1显示工作状态如果你不想用三极管驱动也可以尝试让 GPIO 直连红外发射管需要串一个 100Ω 左右的限流电阻。但 ESP32-S3 的 GPIO 驱动能力有限推 940nm 发射管时距离很难超过 1-2 米而用三极管驱动可以把距离提升到 5 米以上。这里我强烈建议使用三极管驱动方案。2.2 软件环境我选择使用 Arduino 框架进行开发。原因很简单IRremote 生态成熟、示例代码多、上手快。ESP32-S3 完全可以跑 Arduino 框架后续如果你要迁移到 ESP-IDF 或 MicroPython也可以参考同样的硬件接线和协议思路。你需要准备以下软件环境Arduino IDE 2.x 或 1.8.xESP32 开发板包在“开发板管理器”中搜索esp32选择 Espressif Systems 官方包并安装IRremote 库在“库管理器”中搜索IRremote by shirriff安装最新版如果需要 OLED 显示可安装Adafruit SSD1306和Adafruit GFX库版本需要根据你的实际环境调整。ESP32 开发板包版本升级比较频繁不同版本对 Arduino 框架的 API 兼容性略有差异如果编译报错优先检查开发板包和库版本。2.3 开发板选择说明ESP32-S3 有几个常见封装形式比如ESP32-S3-DevKitC-1ESP32-S3-WROOM-1 / N8R2 模组合宙 ESP32-S3 系列开发板它们的主芯片都是 ESP32-S3GPIO 编号基本通用。但需要注意不同开发板的板载 USB 转串口芯片不同有些使用板载 USB 烧录有些外挂 CH340/CP2102。在“开发板管理器”中选择具体型号时如果你用的是官方 DevKitC-1直接选ESP32S3 Dev Module即可。选择板子时还要注意供电能力。红外发射管瞬间电流不小如果用开发板自带的 LDO 供电长期发射可能导致电压跌落。建议在实验阶段用 USB 供电即可后续做网关产品建议用 5V/2A 以上的电源。3. 硬件接线与电路设计3.1 红外发射电路红外发射管本质是 LED需要限流否则电流过大会烧毁。同时为了让发射管有更大的驱动电流我们用三极管做开关放大。推荐连接方式ESP32-S3 GPIO 4 - 1kΩ 电阻 - S8050 基极 S8050 发射极 - GND S8050 集电极 - 10Ω 电阻 - 红外发射管负极 红外发射管正极 - 5V 或 3.3V注意S8050 是 NPN 三极管发射极接地基极输入高电平时三极管导通集电极电流通过发射管形成回路。10Ω 电阻用来限制峰值电流如果在 5V 供电下发射管压降约 1.2V电流大约在 300mA 左右对短时间发射是安全的。如果长时间连续发送建议适当增大限流电阻。我实际测试时使用 3.3V 供电、10Ω 限流电阻配合 940nm 发射管距离 5 米内遥控电视没问题。如果你发现距离近优先检查供电电压、限流电阻、发射管方向。红外发射管和其他 LED 一样有正负极长脚为正极。如果接反了电流不会通过设备自然无法收到信号。3.2 红外接收电路红外接收头 HS0038B 或 VS1838B 是一个三引脚元件正面有一个半球形凸起引脚间距是 2.54mm可以直接插面包板。引脚定义引脚作用OUT信号输出接 ESP32-S3 GPIO 5GND接地VCC电源正极接 3.3V从正面看凸起面向你通常从左到右依次是 OUT、GND、VCC。但这个排序不同品牌可能不同建议看具体数据手册或商家说明。接错会发热甚至损坏接收头。最后给接收头 VCC 和 GND 之间并一个 10uF 电解电容和 0.1uF 陶瓷电容可以有效滤除电源噪声提升接收稳定性。当然实验阶段不接电容也能工作但如果你发现接收距离很近或经常丢码电源滤波是非常值得加的一步。3.3 完整接线表模块引脚连接到红外发射管经三极管GPIO 4集电极回路红外接收头 OUTGPIO 5接收信号红外接收头 VCC3.3V电源红外接收头 GNDGND地OLED SDA可选GPIO 8I2C 数据OLED SCL可选GPIO 9I2C 时钟GPIO 的选择需要注意ESP32-S3 的某些引脚在默认启动时有特殊功能比如 GPIO 0、GPIO 3、GPIO 46 等最好避开。GPIO 4 和 GPIO 5 是安全的选择也是 IRremote 示例常用的引脚。4. 红外发射与接收核心代码4.1 安装与引入 IRremote 库打开 Arduino IDE在“项目 - 加载库 - 管理库”中搜索IRremote选择来自 shirriff 的版本并安装。安装完成后可以在“文件 - 示例 - IRremote”中看到大量示例包括SimpleReceiver、SimpleSender等。在代码里我们这样引入库#include IRremote.hIRremote 库会自动判断平台并选择底层实现。在 ESP32-S3 上它使用 RMTRemote Control外设来进行红外信号的发送和接收这样可以避免 CPU 中断被频繁打断时序更稳定。4.2 红外发送示例代码先看一个最简单的发送示例。假设我们要发送 NEC 协议地址为 0x00命令为 0x45。// 文件路径esp32s3_ir_sender/esp32s3_ir_sender.ino #include IRremote.h const int IR_SEND_PIN 4; void setup() { Serial.begin(115200); IrSender.begin(IR_SEND_PIN); Serial.println(IR Sender Ready); } void loop() { // 发送 NEC 协议地址 0x00命令 0x45重复 0 次 IrSender.sendNEC(0x00, 0x45, 0); Serial.println(Sent NEC: addr0x00 cmd0x45); delay(2000); }这段代码的作用是每 2 秒发送一次 NEC 编码。IrSender.begin()初始化发送引脚IrSender.sendNEC()的第三个参数是重复次数表示长按按键时重复帧的次数。如果我们想模拟电视遥控器的“音量”按键需要知道这个按键具体对应的地址和命令码。怎么知道呢两种办法查阅你家电器的红外码表网上很多开源项目整理了常见电视品牌的红外码库。自己用红外接收头学习这也是本文第 5 节要做的核心功能。4.3 红外接收示例代码接收代码用于读取红外遥控器发来的编码并把 NEC 协议的地址和命令打印出来。// 文件路径esp32s3_ir_receiver/esp32s3_ir_receiver.ino #include IRremote.h const int IR_RECEIVE_PIN 5; void setup() { Serial.begin(115200); IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); Serial.println(IR Receiver Ready); } void loop() { if (IrReceiver.decode()) { // 打印解析结果 IrReceiver.printIRResultShort(Serial); if (IrReceiver.decodedIRData.protocol NEC) { Serial.print(NEC Address: 0x); Serial.print(IrReceiver.decodedIRData.address, HEX); Serial.print( Command: 0x); Serial.println(IrReceiver.decodedIRData.command, HEX); } // 接收完一帧后必须调用 resume 准备接收下一帧 IrReceiver.resume(); } }IrReceiver.decode()在有完整红外数据帧时返回true。printIRResultShort会打印协议、地址、命令、原始数据等信息。最后必须调用IrReceiver.resume()否则无法接收后续帧。这里有一个新手容易忽略的点IrReceiver.begin()的第二个参数我们传了ENABLE_LED_FEEDBACK这会让开发板上的板载 LED 在收到红外信号时闪烁方便调试。如果你的开发板没有板载 LED 或者 LED 引脚冲突可以改为DISABLE_LED_FEEDBACK。4.4 关于“学习-发射”设计的思路红外学习遥控器本质上是“接收红外码 - 存储编码 - 按键触发发射”。但这里有一个关键概念红外协议有标准协议和非标准协议。标准协议如 NEC、Sony SIRC可以直接解析出地址和命令存储量很小。非标准协议或乱码无法解析成协议字段需要保存原始时序数据。IRremote 库提供了IrReceiver.decodedIRData.decodedRawData它保存了原始数据帧内容。对于 NEC 协议这个原始数据就是地址、地址反码、命令、命令反码的组合。如果要保存学习结果可以把它保存到文件系统或 PreferencesFlash 存储下次开机直接恢复。我建议初学者先把标准 NEC 协议的学习-发射做通再考虑扩展非标准协议。因为非标准协议的调试复杂度和时间成本会成倍上升。5. 实战ESP32-S3 万能红外遥控器现在我们把前面的知识整合起来做一个能学习、能发射的完整项目。硬件接线沿用第 3 节的方案GPIO 4 接发射管GPIO 5 接收收头。5.1 功能设计这个版本实现三个核心功能学习模式按开发板上的 Button A 进入学习状态然后用家里的遥控器对准红外接收头发送按键开发板解析并保存 NEC 编码。发射模式按 Button B 发射上次学习到的红外码。串口日志把当前操作状态打印到串口监视器。如果需要扩展成多个按键可以在按键数组里扩展多个槽位。这里先做一个“学习-发射”的闭环方便验证硬件和逻辑。5.2 完整代码// 文件路径esp32s3_ir_study_remote/esp32s3_ir_study_remote.ino #include IRremote.h #include Preferences.h const int IR_SEND_PIN 4; const int IR_RECEIVE_PIN 5; const int BUTTON_LEARN_PIN 0; const int BUTTON_SEND_PIN 14; // 使用 Preferences 保存学习到的红外码到 Flash Preferences preferences; bool isLearning false; uint32_t learnedRawData 0; uint8_t learnedProtocol UNKNOWN; uint16_t learnedAddress 0; uint16_t learnedCommand 0; void setup() { Serial.begin(115200); pinMode(BUTTON_LEARN_PIN, INPUT_PULLUP); pinMode(BUTTON_SEND_PIN, INPUT_PULLUP); IrSender.begin(IR_SEND_PIN); IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK); preferences.begin(ir_remote, false); // 读取上次保存的数据 learnedRawData preferences.getUInt(raw, 0); learnedProtocol preferences.getUChar(proto, UNKNOWN); learnedAddress preferences.getUShort(addr, 0); learnedCommand preferences.getUShort(cmd, 0); if (learnedRawData ! 0) { Serial.println(Loaded saved IR code.); } else { Serial.println(No saved IR code found.); } Serial.println(Press Button A to learn, Button B to send.); } void loop() { // 进入学习模式 if (digitalRead(BUTTON_LEARN_PIN) LOW) { isLearning true; Serial.println(Learning mode: point your remote to the receiver...); delay(500); } // 如果是学习模式等待接收红外码 if (isLearning IrReceiver.decode()) { IrReceiver.printIRResultShort(Serial); learnedRawData IrReceiver.decodedIRData.decodedRawData; learnedProtocol IrReceiver.decodedIRData.protocol; learnedAddress IrReceiver.decodedIRData.address; learnedCommand IrReceiver.decodedIRData.command; // 保存到 Flash preferences.putUInt(raw, learnedRawData); preferences.putUChar(proto, learnedProtocol); preferences.putUShort(addr, learnedAddress); preferences.putUShort(cmd, learnedCommand); IrReceiver.resume(); Serial.print(Learned and saved. cmd0x); Serial.println(learnedCommand, HEX); isLearning false; } // 发送模式 if (digitalRead(BUTTON_SEND_PIN) LOW) { if (learnedRawData 0) { Serial.println(No IR code stored. Learn first.); } else { Serial.print(Sending saved IR code. addr0x); Serial.print(learnedAddress, HEX); Serial.print( cmd0x); Serial.println(learnedCommand, HEX); // 优先尝试按标准协议发送 if (learnedProtocol NEC) { IrSender.sendNEC(learnedAddress, learnedCommand, 2); } else if (learnedProtocol SONY) { IrSender.sendSony(learnedAddress, learnedCommand, 2, 12); } else { // 非标准协议使用原始数据发送这里只演示 NEC 场景 Serial.println(Protocol not supported for raw send in this demo.); } } delay(500); } }这里用到了Preferences库来把红外码保存到 Flash这样可以避免每次重启都要重新学习。注意不同的 ESP32-S3 开发板 Flash 分区大小不同但Preferences使用的是 NVS 分区默认就支持。5.3 代码解释与关键点Preferences是 ESP32 Arduino 框架自带的存储库类似 Arduino UNO 的 EEPROM但接口更面向键值对。preferences.begin(ir_remote, false)打开命名空间第二个参数false表示读写模式如果为true则只读。preferences.putUInt()、preferences.getUInt()写入和读取无符号整数。按键使用INPUT_PULLUP模式意味着按键按下时引脚读到低电平。这种接法不需要外接上拉电阻接法简单是开发板按键最常见的方式。代码中learnedProtocol的类型是uint8_t而IrReceiver.decodedIRData.protocol返回的是decode_type_t枚举赋值时会被隐式转换为整数。在读取回来时我们需要用decode_type_t(learnedProtocol)进行类型转换但因为默认值直接和UNKNOWN值为 0比较所以代码中直接比较也没有问题。如果你在实际编译中遇到类型警告可以改成decode_type_t typedProtocol static_castdecode_type_t(learnedProtocol); if (typedProtocol NEC) { ... }5.4 运行与验证把代码编译上传到 ESP32-S3 开发板之后打开串口监视器波特率设置为 115200。测试流程按下 Button A串口打印Learning mode...。拿起家里电视机遥控器对准红外接收头按一下“电源”键。串口打印类似NEC Address: 0x00 Command: 0x45说明接收成功。按下 Button B开发板会通过红外发射管发送刚才学习到的编码观察电视是否能被关闭或打开。如果你没有真实家电测试也可以用另一个红外接收头再接一块开发板或者把接收头接到同一块开发板上观察自己发出的信号是否被解析到。5.5 预期输出示例IR Receiver Ready Press Button A to learn, Button B to send. Learning mode: point your remote to the receiver... ProtocolNEC Address0x0 Command0x45 Raw-Data0x45BA00FF 32 bits LSB first Learned and saved. cmd0x45 Sending saved IR code. addr0x0 cmd0x45这里的Raw-Data0x45BA00FF就是 NEC 协议完整的一帧数据。接收成功后你会看到发射时数据的逻辑状态。如果发射管正常工作你可以在另一个红外接收模块上看到同样的打印信息。6. 常见问题与排查思路做红外项目时遇到问题不要慌下面是几个高频问题及排查方法。6.1 编译报错failed to set target esp32s3: non zero exit code 2这个问题在从 ESP-IDF 环境或某些扩展工具链开发时比较常见。报错信息通常提示“your environment is not correctly set up”本质是编译工具链无法正确识别esp32s3目标平台。可能的原因ESP32 开发板包没有正确安装或版本过旧。使用了旧版本的 Arduino ESP32 核心对 ESP32-S3 的支持不完整。系统环境变量IDF_PATH或PATH被修改过影响了 Arduino 的编译脚本。同时安装了 ESP-IDF 和 Arduino IDE两者环境变量冲突。解决思路在 Arduino IDE 的“开发板管理器”中重新安装esp32 by Espressif Systems到最新稳定版。尝试卸载后重启 Arduino IDE 再安装。如果电脑上装了 ESP-IDF 命令行工具暂时把相关环境变量从系统 PATH 中移除再测试。确认选择的开发板类型是 “ESP32S3 Dev Module”而不是ESP32或ESP32S2。6.2 发射了但家电没反应这是最让人头疼的问题。按顺序检查以下几点第一发射管方向是否接反。用万用表二极管档测一下发射管或者用手机摄像头看是否发光。如果完全不发光先解决电路问题。第二驱动电流是否不足。直接 GPIO 驱动时距离往往很短建议使用三极管驱动并保证供电不要低于 3.3V。第三发射管频率是否匹配。大多数家电接收头工作在 38kHz如果你手里的发射管型号是用于其他载波的效果可能很差。940nm 是最常见的红外波长。第四载波频率与协议时序是否被破坏。IRremote 库在 ESP32-S3 上使用 RMT 外设但如果在发射过程中执行了比较耗时的操作比如大量串口打印、Wi-Fi 连接可能导致时序漂移。发射前最好关闭不必要的任务。6.3 学习到的编码不全或地址都是 0如果你用接收头学习遥控码发现打印出来的地址总是0x00命令也能收到但重新发射后设备没反应可能是 N 个原因遥控器直接按一下按键只发一帧接收时丢失了重复帧但标准 NEC 帧本身足够识别。学习的是 NEC 扩展地址模式需要使用 16 位地址。IrReceiver.decodedIRData.address在某些情况下会被截断为 8 位。更常见的是你学习的是非标准协议IRremote 把它尝试解析成了 NEC但字段并不完全匹配。建议直接打印decodedRawData和protocol对比已有的红外协议库资料。必要时可以使用 Raw 数据发送IrSender.sendRaw(irData, irDataLen, 38);但sendRaw需要你保存原始时序数组而不是简单的 32 位数据所以学习非标准协议需要更复杂的设计这里先不展开。6.4 轻触开关能否用红外接收头代替很有趣的问题说明你对“感应控制”有想法。从原理上讲轻触开关是机械触点你按下去电路接通红外接收头是光电传感器它检测到红外光信号后输出电平变化。两者不能直接等同替换因为轻触开关是“人手指按”触发而红外接收头必须接收特定频率的红外信号才动作。如果你想做“遥控器控制开关”正确思路是红外接收头 - 解码 - GPIO 控制继电器或 MOS 管最终模拟开关通断。而不是把接收头直接串联在开关回路里。6.5 ESP32-S3 用 Python 如何开发这也是读者经常问的问题。ESP32-S3 可以使用 MicroPython 开发如果只做简单的红外收发MicroPython 也有相关库。但如果你是做本文这种需要精确时序和较高性能的遥控器项目我建议还是用 Arduino 或 ESP-IDF。原因是 MicroPython 的时序精度受解释器影响发射 NEC 这类依赖微秒级定时的协议时容易出现时序抖动。如果你坚持用 Python也可以先用 MicroPython 配合machine.PWM生成 38kHz 载波再用machine.time_pulse_us做接收测量。这是一种“半手工”实现红外协议的方式能加深你对协议的理解但开发效率相对较低。7. 优化方向与工程化实践7.1 增加 OLED 显示做产品原型时光靠串口打印看状态不够直观。给项目加一个 0.96 寸 OLED可以在屏幕上显示当前模式、学习到的协议类型、命令码和发射结果。SSD1306 的接线非常简单I2C 只需要 SDA、SCL 两根线。在代码里初始化#include Wire.h #include Adafruit_SSD1306.h #include Adafruit_GFX.h #define OLED_SDA 8 #define OLED_SCL 9 #define OLED_ADDR 0x3C Adafruit_SSD1306 display(128, 64, Wire, -1); void initDisplay() { Wire.begin(OLED_SDA, OLED_SCL); display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println(IR Remote); display.display(); }注意I2C 引脚需要根据开发板实际定义调整。ESP32-S3 可以通过Wire.begin(SDA, SCL)指定任意 GPIO 作为 I2C。7.2 扩展多按键和码库把学习到的红外码保存到 Preferences 时可以加上索引比如key0、key1、key2。设计成一个数组槽位每个槽位保存一个按键的红外编码。硬件上可以接 4x4 矩阵键盘或者使用 ESP32-S3 的触摸引脚作为触控按键。这样你就得到了一个多按键的万能遥控器。更进一步可以在 Flash 中预置常用品牌的红外码库。开源社区有很多 IR 码库比如 Arduino-IRremote 的ir_Remote示例、IRremoteESP8266 库的IRrecvDump码表。你可以从中提取电视、空调的常用码直接烧录到设备里。7.3 增加 Wi-Fi 远程控制ESP32-S3 的 Wi-Fi 能力是这个项目最大的扩展点。你可以通过局域网 UDP、HTTP Server 或 MQTT 接收指令再发送红外码。典型场景手机 App 发送{cmd: 0x45}到开发板。开发板接收后调用IrSender.sendNEC(0x00, 0x45, 2)。电视被关闭整个过程不需要人在旁边按遥控器。实现时要注意红外发射期间尽量避免 Wi-Fi 底层任务抢占否则可能导致时序漂移。使用 FreeRTOS 时可以考虑把红外发射放到高优先级任务中或者使用 IRremote 库基于 RMT 的发射实现因为 RMT 是硬件控制不依赖 CPU 实时响应。7.4 安全与生产环境注意事项如果你要把这个方案做成产品需要关注几个实际问题发射管电流长时间连续发射会导致发射管发热建议软件层面控制发射间隔避免死循环无限发码。电源隔离红外接收头对电源噪声比较敏感尽量在电源入口加滤波电容。Flash 寿命Preferences直接写 NVS有写入次数限制通常十万次级别不要在loop里频繁写入。合规认证这个偏产品阶段的话题如果是毕设或原型可以暂时忽略但量产时需要考虑无线模块的认证和红外辐射功率要求。7.5 代码工程化建议在实际项目中不要把全部逻辑都塞进.ino文件。建议按模块拆分esp32s3_ir_remote/ ├── esp32s3_ir_remote.ino ├── ir_learn.h ├── ir_learn.cpp ├── ir_store.h ├── ir_store.cpp ├── display.h ├── display.cpp └── config.hconfig.h里统一放引脚定义和常量#ifndef CONFIG_H #define CONFIG_H #define IR_SEND_PIN 4 #define IR_RECEIVE_PIN 5 #define BUTTON_LEARN_PIN 0 #define BUTTON_SEND_PIN 14 #endif这样做的好处是后续扩展硬件时只需要改配置文件核心逻辑不用动。8. 总结与下一步学习建议到目前为止我们已经完成了 ESP32-S3 红外遥控器的核心链路硬件接线、红外发送、红外接收、学习-发射闭环、编码保存和常见故障排查。你可以用这个设备控制家里支持红外遥控的电视、机顶盒、风扇甚至空调空调通常使用更复杂的协议需要进一步处理。下一步你可以从以下几个方向继续深入尝试用IRrecvDump示例采集家里各种家电的红外码建立自己的码库。把本文的发射代码与 ESP-NOW、MQTT 结合实现局域网内手机控制。深入研究 NEC 协议的扩展 16 位地址模式搞懂空调设备为什么偶尔控制不了。如果对底层感兴趣可以切换到 ESP-IDF 的 RMT 驱动手动编写红外时序生成逻辑体会硬件外设的妙处。同时建议你在学习过程中多准备一个红外接收头和一块便宜的开发板。双板调试能极大提高排查效率一块板负责发另一块板负责收。当你看到发射板的数据被另一块板完整解析并打印出来时说明整条链路是通的剩下的问题只可能是距离、角度或设备兼容性。如果本文对你有帮助可以收藏备用。后面我会继续更新基于 ESP32-S3 的 MQTT 红外网关实战以及空调红外码解析的详细教程。遇到问题也欢迎在评论区留言我会根据你提供的现象和日志给出排查思路。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进