恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
ESP32C3打造本地化Wi-Fi万能红外遥控器:从硬件到Web控制全解析
首页
资讯中心
/
ESP32C3打造本地化Wi-Fi万能红外遥控器:从硬件到Web控制全解析
ESP32C3打造本地化Wi-Fi万能红外遥控器:从硬件到Web控制全解析
发布时间:2026/10/9 4:43:12
1. 项目缘起与整体设计思路1.1 这个项目到底在做什么Universal Remote WIFI Based ESP32C3直译过来就是“基于 ESP32C3 的 Wi-Fi 万能遥控器”。核心思路非常朴素用一块巴掌大的 ESP32C3 开发板配上红外发射与接收模块把它变成一个可以通过浏览器访问的万能红外遥控中枢。家里的空调、电视、风扇、机顶盒只要是用红外遥控的理论上都能被它接管。我之所以盯上这个方案是因为市面上的万能遥控器要么依赖厂商云服务要么需要专门的网关盒子一旦断网或者厂商停止维护设备就成了砖头。而 ESP32C3 方案最大的优势在于本地化所有红外码存在板子上Web 界面由板子自己托管手机连上同一个局域网就能控制不依赖任何外部服务器。RemodazWifi 这个名字里的 “Wifi” 也点明了它的核心交互方式——通过 Wi-Fi 提供 Web 控制界面。这个项目适合谁如果你家里有一堆红外遥控器、又不想每次找遥控器翻沙发缝或者你想入门 ESP32 和物联网开发这个项目是很好的练手素材。它涉及 Wi-Fi 配网、Web 服务器、红外编解码、前端交互几个环节麻雀虽小五脏俱全。1.2 为什么选 ESP32C3 而不是别的芯片选型这件事我踩过坑。最早我用的是 ESP8266便宜是便宜但 RAM 太小跑一个稍微复杂点的 Web 界面就捉襟见肘而且 GPIO 数量有限接红外收发再加个 OLED 就紧张了。后来换到 ESP32 经典款性能够了但价格和体积上去了对于单纯做红外遥控有点浪费。ESP32C3 是 RISC-V 架构的单核芯片主频 160MHz自带 Wi-Fi 和蓝牙 LE关键是支持 ESP Web Tools 直接网页烧录不用装 Arduino IDE 或 ESP-IDF 就能刷固件。它的 GPIO 虽然不算多但做红外遥控绰绰有余一个引脚接红外发射 LED一个引脚接红外接收头剩下的还能接个状态指示灯。从成本看ESP32C3 开发板现在十几块钱就能拿下红外发射模块和接收头加起来不到五块。整个项目硬件成本控制在二十块以内比买一个品牌万能遥控器便宜得多而且可玩性高出一大截。1.3 整体架构是怎么搭的整个系统分三层硬件层负责红外信号的收发固件层跑在 ESP32C3 上处理 Wi-Fi 连接、Web 服务、红外编解码交互层是手机或电脑浏览器打开的网页用来选设备、按按钮、学习新遥控码。数据流是这样的你在网页上点“空调开机”浏览器发一个 HTTP 请求给 ESP32C3固件解析请求后调用红外发射库把预先存好的红外码通过 GPIO 驱动 LED 发出去。反过来当你按“学习”按钮时ESP32C3 进入接收模式红外接收头捕获遥控器发出的信号固件解码后存进内存或文件系统下次就能直接调用。这里有个关键设计决策红外码存哪里。ESP32C3 的 RAM 不大存几十个遥控码没问题但如果你想存几百个就得用 SPIFFS 或 LittleFS 文件系统。我实测下来用 LittleFS 存 JSON 格式的遥控码最方便读写快而且断电不丢。每个遥控码用“协议地址命令”的格式存比如 NEC 协议的空调码就是{protocol: NEC, address: 0x1234, command: 0x56}。注意红外接收头在强光下容易受干扰尤其是阳光直射或日光灯频闪。我一开始把接收头放在窗边结果学习模式经常误触发后来挪到背光位置就稳定了。2. 核心细节解析与实操要点2.1 硬件连接与引脚分配先把手头的元件理清楚。你需要一块 ESP32C3 开发板我用的是合宙的 C3 最小系统板、一个 940nm 红外发射 LED、一个 VS1838B 红外接收头、两个电阻发射端用 100Ω 限流接收端用 10kΩ 上拉、若干杜邦线。引脚分配我试过几套方案最终定下来这套最稳功能ESP32C3 引脚说明红外发射GPIO 3通过 100Ω 电阻接 LED 正极LED 负极接地红外接收GPIO 4接收头 OUT 脚接 GPIO4VCC 接 3.3VGND 接地状态指示灯GPIO 8板载 LED用于指示 Wi-Fi 连接状态配网按钮GPIO 9接一个轻触开关到地长按进入配网模式发射端为什么要加 100Ω 电阻红外 LED 的 forward voltage 大概 1.2VESP32C3 的 GPIO 输出 3.3V如果不加限流电阻电流会超过 LED 的额定值。按欧姆定律算(3.3V - 1.2V) / 100Ω 21mA这个电流在 ESP32C3 单个 GPIO 的安全范围内最大 40mA同时又能保证红外发射距离。我试过用 220Ω距离明显缩短用 47Ω 又太热100Ω 是平衡点。接收头的上拉电阻为什么是 10kΩVS1838B 的输出是开集电极结构需要外部上拉才能输出高电平。10kΩ 是数据手册推荐值太小会增加功耗太大上升沿变缓影响解码。2.2 红外协议与编码原理红外遥控的底层逻辑其实很简单用 38kHz 载波调制通过载波的“有”和“无”来表示二进制的 1 和 0。不同厂商定义了不同的协议常见的有 NEC、RC5、RC6、Sony SIRC 等。NEC 协议是最常见的它的帧结构是9ms 引导码 4.5ms 间隔 8位地址 8位地址反码 8位命令 8位命令反码 560us 结束位。逻辑 1 是 560us 载波 1690us 间隔逻辑 0 是 560us 载波 560us 间隔。这个协议的好处是有反码校验接收端可以验证数据是否正确。我在固件里用的是 IRremoteESP8266 库虽然名字带 8266但完全兼容 ESP32C3。这个库支持解码和编码几十种协议调用irsend.sendNEC(address, command)就能发码irrecv.decode()就能收码。但要注意这个库默认用定时器中断在 ESP32C3 上需要调整一下配置否则编译会报错。实操心得如果你要控制的空调是格力、美的这类品牌它们的红外码往往不是标准 NEC而是厂商自定义的长码。这种码用 IRremoteESP8266 的sendRaw()函数直接发原始时序最靠谱别硬套标准协议。2.3 Web 界面与交互设计Web 界面我一开始想用现成的框架后来发现没必要。ESP32C3 的资源有限跑一个 React 或 Vue 太吃力直接用原生 HTML CSS JavaScript 最轻量。整个页面就是一个单文件存在 LittleFS 里访问时直接读出来发给浏览器。页面布局分三块顶部是设备列表中间是当前设备的按钮网格底部是“学习新遥控码”和“设置”入口。按钮网格用 CSS Grid 布局每个按钮对应一个红外码。点击按钮时JavaScript 发一个fetch(/send?codexxx)请求ESP32C3 收到后发红外信号。这里有个细节按钮的防抖。红外发射需要时间如果用户快速连点可能会导致信号重叠。我在 JavaScript 里加了 200ms 的节流同时 ESP32C3 端也做了请求队列确保一次只处理一个发射任务。学习模式的交互稍微复杂一点。用户点“学习”后页面进入等待状态ESP32C3 开始监听红外接收头。当收到信号并成功解码后页面弹出一个输入框让用户给这个码命名然后保存到 LittleFS。如果解码失败比如遇到了不支持的协议页面会提示“无法识别该遥控码”并建议用户尝试调整遥控器与接收头的距离。3. 实操过程与核心环节实现3.1 开发环境搭建与固件烧录先说烧录。ESP32C3 支持 ESP Web Tools这意味着你不需要装任何本地开发环境直接用 Chrome 或 Edge 浏览器打开一个网页就能刷固件。具体步骤是把 ESP32C3 用 USB 线连到电脑按住 BOOT 键再按一下 RESET 键进入下载模式然后在浏览器里选择固件文件点“烧录”就行。但如果你要自己改代码还是得装 Arduino IDE 或 PlatformIO。我用的是 PlatformIO因为它的库管理更清晰。在platformio.ini里配置如下[env:esp32-c3-devkitm-1] platform espressif32 board esp32-c3-devkitm-1 framework arduino monitor_speed 115200 board_build.filesystem littlefs lib_deps crankyoldgit/IRremoteESP8266^2.8.6 bblanchon/ArduinoJson^6.21.3这里有几个关键点board_build.filesystem littlefs指定用 LittleFS 而不是 SPIFFS因为 LittleFS 更稳定lib_deps里声明了红外库和 JSON 库PlatformIO 会自动下载。烧录时要注意ESP32C3 的 USB 串口有时候会被识别成两个设备一个用于下载一个用于调试。如果 PlatformIO 找不到端口试试拔掉重插或者在设备管理器里看看有没有带 “USB JTAG/serial debug unit” 字样的设备。3.2 Wi-Fi 配网与 Web 服务器启动配网逻辑我设计成两种模式首次上电时如果 LittleFS 里没有保存 Wi-Fi 信息就进入 AP 模式自己发一个热点叫 “RemodazWifi-Setup”你用手机连上后打开配置页面输入家里的 Wi-Fi 名称和密码配网成功后ESP32C3 重启并连接到家里的 Wi-Fi之后每次上电都会自动连接。代码层面用WiFi.begin(ssid, password)发起连接然后轮询WiFi.status()直到连上或超时。超时时间我设的是 15 秒超过就回退到 AP 模式。连接成功后启动 Web 服务器WebServer server(80); server.on(/, handleRoot); server.on(/send, handleSend); server.on(/learn, handleLearn); server.on(/save, handleSave); server.begin();handleRoot读取 LittleFS 里的index.html并返回handleSend解析 URL 参数里的红外码并发射handleLearn启动红外接收handleSave把新学的码存进 LittleFS。注意ESP32C3 的 Wi-Fi 和蓝牙共用射频前端如果你同时开了蓝牙Wi-Fi 的稳定性会下降。这个项目不需要蓝牙所以在代码里把蓝牙关掉Wi-Fi 信号会好很多。3.3 红外码的采集与存储采集红外码是整个项目里最需要耐心的环节。把遥控器对准接收头距离控制在 5 到 10 厘米按一下你要学习的按键。ESP32C3 的串口会打印出解码结果比如Protocol: NEC Address: 0x1234 Command: 0x56 Raw: 9000,4500,560,560,560,1690,...如果解码成功就把协议、地址、命令存下来。如果解码失败但 Raw 数据看起来有规律可以手动分析。我遇到过一种情况遥控器用的是 RC5 协议但 IRremoteESP8266 默认没启用 RC5 解码需要在代码里加irrecv.enableIRIn()之前调用irrecv.enableRC5()。存储格式我用 JSON每个遥控码存成一条记录{ name: 空调开机, protocol: NEC, address: 0x1234, command: 0x56 }所有记录放在一个数组里存到/codes.json。读取时用 ArduinoJson 解析发射时根据协议类型调用对应的发送函数。如果协议是 “RAW”就直接把 Raw 数组传给irsend.sendRaw()。3.4 前端页面的动态渲染前端页面我写了一个简单的模板引擎逻辑页面加载时JavaScript 发一个fetch(/codes)请求拿到所有遥控码的 JSON 数组然后动态生成按钮。每个按钮的onclick事件绑定到sendCode(index)函数该函数再发fetch(/send?index index)。这样做的好处是当你新增或删除遥控码时不需要改 HTML页面刷新后自动更新。按钮的样式用 CSS 变量控制方便换主题。我默认给了一个深色主题因为晚上看电视时深色不刺眼。学习模式的页面交互是这样点“学习”按钮后页面显示“请对准接收头按下遥控器按键”同时每 500ms 轮询一次/learn/status。当 ESP32C3 收到码后/learn/status返回解码结果页面弹出命名对话框。如果 10 秒内没收到码页面提示“未检测到信号请重试”。4. 常见问题与排查技巧实录4.1 红外发射距离短或不稳定这是最常见的问题。原因通常有三个限流电阻太大、LED 方向不对、电源供电不足。先检查电阻。如果你用的是 220Ω 或更大换成 100Ω 试试。然后看 LED 的方向红外 LED 的长脚是正极短脚是负极接反了不亮。最后看供电ESP32C3 的 3.3V 输出电流有限如果你同时接了 OLED 屏幕和红外 LED可能会拉低电压。解决办法是用外部 5V 电源供电或者减少同时工作的外设。还有一个容易被忽略的点红外 LED 的发射角度。普通红外 LED 的发射角大概 20 到 30 度如果你把它藏在壳子里角度会被遮挡。我一开始把 LED 焊在板子上结果只能对准一个方向后来用导线引出来贴在盒子前面覆盖范围就大了。4.2 学习模式无法解码学习模式失败的原因比较多我整理了一个排查表现象可能原因解决办法串口无任何输出接收头接线错误检查 VCC、GND、OUT 是否接对有输出但解码失败协议不支持在代码里启用对应协议的解码解码结果乱跳环境光干扰避开阳光和日光灯加遮光罩偶尔成功偶尔失败距离太远或太近调整到 5-10 厘米一直显示未知协议遥控器电池电量低换新电池我踩过最坑的一次是接收头的 VCC 接成了 5V结果输出电平一直是高根本收不到信号。VS1838B 的工作电压是 2.7V 到 5.5V但 ESP32C3 的 GPIO 是 3.3V 逻辑接 5V 虽然不会立刻烧但长期用会缩短寿命。后来统一接 3.3V 就稳定了。4.3 Wi-Fi 连接不稳定或频繁掉线ESP32C3 的 Wi-Fi 性能其实不错但如果你把它放在金属盒子里信号会被屏蔽。我一开始用了一个铝合金外壳结果隔一堵墙就掉线。换成塑料外壳后信号强度从 -75dBm 提升到 -55dBm。另外如果你家里路由器开了 “双频合一”ESP32C3 可能会在 2.4G 和 5G 之间反复切换导致连接不稳定。解决办法是在路由器设置里把 2.4G 和 5G 分开让 ESP32C3 只连 2.4G。ESP32C3 不支持 5G Wi-Fi这一点在配网时要注意。还有一个隐藏问题Wi-Fi 省电模式。ESP32C3 默认开启省电模式在空闲时会降低射频功率导致响应变慢。在代码里加一行WiFi.setSleep(false)就能关掉代价是功耗稍微高一点但响应速度明显提升。4.4 网页加载慢或按钮无响应网页加载慢通常是 LittleFS 读取速度的问题。如果你把 HTML、CSS、JS 都塞在一个大文件里ESP32C3 读取和发送的时间会比较长。我的做法是把 CSS 和 JS 内联在 HTML 里减少 HTTP 请求次数。另外开启 gzip 压缩也能减小传输体积但 ESP32C3 的压缩库会占用一些 RAM需要权衡。按钮无响应一般是 JavaScript 报错。用浏览器的开发者工具看 Console如果提示fetch failed说明 ESP32C3 的 Web 服务器没响应。检查一下是不是同时发了太多请求ESP32C3 的 WebServer 库默认只能处理一个连接并发请求会排队。我在前端加了请求队列确保上一个请求完成后再发下一个。独家技巧如果你发现按钮点击后要等一两秒才有反应试试把 Web 服务器的端口从 80 改成 8080。有些路由器或运营商会拦截 80 端口的本地请求换端口能绕过这个问题。5. 进阶玩法与扩展思路5.1 接入语音助手如果你家里有智能音箱可以通过 MQTT 把 ESP32C3 接入 Home Assistant然后用语音控制红外设备。具体做法是在 ESP32C3 上跑一个 MQTT 客户端订阅一个主题比如home/ir/send当收到消息时解析并发射红外码。Home Assistant 那边配置一个 MQTT 开关就能用语音助手控制了。这个方案的难点在于 MQTT 的稳定性。ESP32C3 的 RAM 有限如果同时跑 Web 服务器和 MQTT 客户端内存会比较紧张。我的建议是二选一要么用 Web 界面要么用 MQTT别同时开。如果非要同时用把 Web 界面简化去掉不必要的功能。5.2 定时任务与场景联动ESP32C3 可以跑一个简单的定时器比如每天晚上 10 点自动发“空调关机”码。实现方式是用Ticker库或者millis()轮询。我更喜欢用Ticker因为它不占用主循环的时间。场景联动稍微复杂一点比如“开门后自动开灯”。这需要额外的传感器比如门磁开关。ESP32C3 的 GPIO 接门磁当门打开时触发中断然后发射红外码。这种联动逻辑可以写在固件里也可以通过 MQTT 让 Home Assistant 来处理。5.3 红外码的批量导入与导出如果你有很多遥控码一个个学习太慢了。我的做法是提供一个导出功能把/codes.json下载到电脑编辑后再上传回去。这样你可以从网上找到现成的红外码库批量导入。导入时要注意格式匹配。不同来源的红外码格式可能不一样有的用十六进制有的用十进制有的直接给 Raw 数组。我在固件里加了一个转换函数尽量兼容多种格式。如果遇到不兼容的就手动转一下。5.4 外壳设计与散热最后说说外壳。ESP32C3 发热不大但如果你把它塞在密闭盒子里夏天可能会过热。我在外壳上开了几个散热孔同时把红外 LED 和接收头露在外面。外壳材料用 PLA 打印就行别用金属金属会屏蔽 Wi-Fi 和红外信号。如果你没有 3D 打印机用塑料项目盒也能凑合。关键是红外 LED 和接收头要露出来Wi-Fi 天线区域不要被遮挡。ESP32C3 的板载天线在开发板的一端外壳设计时留出那个区域。我个人在实际操作中的体会是这个项目最大的乐趣不在于省了买遥控器的钱而在于你真正理解了一个红外遥控器从按键到发射的完整链路。每次成功解码一个陌生遥控器那种“破解了”的感觉比什么都值。如果你也想动手建议先从 NEC 协议的设备练手比如电视或风扇等熟悉了再挑战空调这种长码设备。