资讯动态

基于ESP32的红外遥控改造:让传统家电接入智能家居

发布时间:2026/8/19 15:19:52 来源:尧图企业网站定制
1. 项目概述让“哑巴”家电开口说话家里那台老旧的空调遥控器找不到了电视、风扇、音响的遥控器堆满了茶几想用手机控制一切却发现很多老设备根本不支持Wi-Fi或蓝牙如果你也有这些烦恼那么这个项目就是为你量身定做的。它的核心目标很简单利用一块小小的ESP32开发板将任何带有红外遥控器的设备都变成可以通过手机网页或语音控制的智能设备。听起来像是魔法但原理其实很直接。红外IR是大多数家用电器遥控的通用语言而ESP32则是一位精通多种语言的“智能管家”。它既能接收并“听懂”红外遥控器发出的指令学习也能模仿红外遥控器“说出”同样的指令发射更厉害的是它自身还内置了Wi-Fi可以搭建一个本地网页服务器。这样一来你的手机浏览器就成了一个万能遥控器界面甚至可以通过接入智能家居平台实现语音控制。我折腾过不少智能家居方案这种自建本地化、零依赖云端的方案在响应速度、隐私安全和成本控制上优势非常明显。无论你是想拯救一台老古董空调还是想统一管理客厅里所有的影音设备这个项目都能给你一个稳定、可玩性极高的解决方案。2. 核心思路与方案选型2.1 为什么是ESP32在开始动手前我们先聊聊为什么选择ESP32作为核心。市面上常见的物联网开发板还有Arduino Uno、NodeMCUESP8266等。ESP32几乎是这个项目的“天选之子”原因有三点。第一是双核与性能。ESP32拥有两个处理器核心这意味着我们可以让一个核心专心处理Wi-Fi连接和网页服务ESPUI另一个核心来处理红外信号的实时接收与发射两者互不干扰系统响应更流畅。相比之下Arduino Uno单核处理多任务会非常吃力ESP8266性能也稍逊一筹。第二是丰富的外设与低成本。ESP32自带蓝牙、Wi-Fi价格却非常亲民国产开发板通常在20-40元。更重要的是它支持RMT远程控制外设。这个外设是专为生成精确的脉冲信号而设计的对于发射需要严格时序的红外信号特别是载波频率为38kHz的NEC、RC5等协议来说简直是硬件级支持比用软件模拟稳定和准确得多。第三是强大的社区与库支持。围绕ESP32的生态极其丰富有像IRremoteESP8266这样成熟且持续维护的红外库也有ESPUI这种轻量级、适合嵌入式设备的网页界面库。这意味着我们不需要从零造轮子站在巨人的肩膀上项目成功率大大提升。2.2 技术方案全景图整个项目的架构可以清晰地分为三层硬件层、逻辑层、交互层。硬件层就是我们的ESP32开发板加上一个红外接收头如VS1838B和一个红外发射二极管通常搭配一个限流电阻。接收头负责“听”发射管负责“说”。逻辑层是运行在ESP32上的程序固件。它的核心任务有三个红外学习通过接收头记录下原始遥控器每个按键发出的红外信号码值并存储在ESP32的闪存Flash中类似于给每个指令拍个“指纹”。红外发射当收到控制命令时从存储中调出对应的“指纹”通过RMT外设驱动发射管原样复现红外信号。网络服务启动一个Wi-Fi热点或连接家庭路由器运行一个轻量的Web服务器。服务器上托管着ESPUI生成的网页界面并处理来自网页的按钮点击等事件。交互层就是用户看到的界面。我们通过ESPUI创建一个简洁的网页上面有对应各个设备、各个功能的按钮。你在手机浏览器里打开这个网页点击“空调开”网页就会通过WebSocket或HTTP请求告诉ESP32ESP32随即发射对应的红外信号。整个过程在局域网内完成无需互联网速度极快。注意这里有一个关键选择——ESPUI。为什么不直接用更流行的WebServer库因为ESPUI专为资源受限的嵌入式设备优化它生成的界面是单页应用SPA通过WebSocket与设备通信响应速度快且UI组件足够我们做遥控器界面。如果自己用HTML/CSS/JS从头写开发效率会低很多。3. 硬件准备与电路连接3.1 物料清单与选型建议动手之前请准备好以下材料。我会给出具体的选型理由帮你避坑。ESP32开发板推荐选择NodeMCU-32S或ESP32 DevKit V1这类引脚引出完善的型号。注意区分版本选择带有内置USB转串口芯片如CH340、CP2102的这样直接用USB线就能供电和编程最方便。红外接收头VS1838B或TSOP38238。这两个是最常见、最通用的38kHz一体化红外接收头。它们内部已经集成了滤波、放大和解调电路输出的是干净的数字信号有信号时为低电平直接接ESP32的GPIO即可。千万别买成红外发射管接收头通常是黑色或深灰色的有三只引脚。红外发射二极管普通的5mm 红外发射管即可。注意它有正负极长脚为正。为了提高发射距离和角度可以并联2-3个但每个都需要独立的限流电阻。限流电阻用于保护红外发射管。根据欧姆定律计算电阻值 (电源电压 - 二极管压降) / 期望电流。ESP32的GPIO输出为3.3V红外管压降约1.2V工作电流建议在20-50mA。以30mA计算电阻 (3.3V - 1.2V) / 0.03A ≈ 70Ω。我们可以选用68Ω或100Ω的电阻。功率方面PI²R 0.03² * 100 0.09W选用1/4瓦0.25W的电阻绰绰有余。面包板、杜邦线用于连接和测试。USB数据线用于供电和烧录程序。3.2 电路连接详解与原理连接电路是硬件部分最关键的一步接错了可能烧坏元件或无法工作。请对照下图脑海想象或自行绘制和下方说明进行操作。红外接收电路红外接收头有三个引脚VCC、GND、OUT或DATA。将VCC接到ESP32的3.3V引脚。绝对不要接5V虽然很多接收头标称工作电压是5V但ESP32的GPIO耐压只有3.3V用5V供电可能导致输出信号损坏ESP32的IO口。将GND接到ESP32的任意GND引脚。将OUT接到ESP32的一个GPIO引脚例如我选择GPIO 4。这个引脚将用于接收信号。红外发射电路红外发射管有两个引脚阳极正极长脚和阴极负极短脚。将发射管的阴极直接接到ESP32的GND。在发射管的阳极和ESP32的一个GPIO引脚例如GPIO 5之间串联一个100Ω的限流电阻。电流流向是GPIO 5输出高电平 - 电阻 - 发射管阳极 - 阴极 - GND。这样当GPIO输出高电平时电流流过发射管使其发光。实操心得红外发射管的发射角度有限像手电筒一样是锥形光。为了能控制不同方向的设备你可以将2-3个发射管以不同角度比如120度焊接在一起或者直接购买那种“三发射头”的红外发射模块。另外红外信号会被墙壁等物体反射将发射管对准天花板有时能利用反射实现更广范围的控制适合藏在角落。4. 软件环境搭建与核心库配置4.1 Arduino IDE环境搭建我们将使用Arduino IDE进行开发因为它对新手最友好库管理也方便。安装Arduino IDE从官网下载并安装最新版建议1.8.x或2.x稳定版。添加ESP32开发板支持打开Arduino IDE点击文件-首选项。在“附加开发板管理器网址”中填入以下网址https://espressif.github.io/arduino-esp32/package_esp32_index.json点击工具-开发板-开发板管理器。搜索“esp32”找到由“Espressif Systems”提供的“ESP32”开发板包点击安装。安装必要的库点击项目-加载库-管理库...。搜索并安装IRremoteESP8266库。这个库虽然名字带8266但对ESP32的支持非常好功能强大协议支持全面。搜索并安装ESPUI库。这是一个用于创建Web界面的库。选择开发板与端口用USB线连接ESP32和电脑。在工具-开发板中选择你的ESP32型号如“ESP32 Dev Module”。在工具-端口中选择新出现的串口在Windows上是COMx在Mac/Linux上是/dev/cu.usbserial-xxx。4.2 核心代码逻辑剖析项目的完整代码较长我将分模块解释其核心逻辑。你可以在理解后将代码片段组合成一个完整的.ino文件。第一步引入库与定义引脚#include Arduino.h #include WiFi.h #include ESPUI.h #include IRremoteESP8266.h #include IRrecv.h #include IRsend.h #include IRutils.h // 定义红外接收和发射引脚 const uint16_t kRecvPin 4; // 红外接收头接在GPIO4 const uint16_t kIrLedPin 5; // 红外发射管接在GPIO5 // 创建红外接收和发送对象 IRrecv irrecv(kRecvPin); IRsend irsend(kIrLedPin); // 解码结果存储结构体 decode_results results; // 用于存储学习到的红外码这里以存储10个为例 String learnedIRCodes[10]; int codeIndex 0; // 定义Wi-Fi热点名称和密码设备将创建这个热点 const char* ssid IR-Smart-Controller; const char* password 12345678;这里我们初始化了红外和网络的核心对象。learnedIRCodes数组用来保存在学习模式下接收到的红外编码以十六进制字符串形式存储。第二步初始化设置setup函数void setup() { Serial.begin(115200); delay(1000); // 1. 初始化红外功能 irrecv.enableIRIn(); // 启动红外接收 irsend.begin(); // 启动红外发射 Serial.println(红外模块初始化完成。); // 2. 创建Wi-Fi热点 WiFi.softAP(ssid, password); IPAddress myIP WiFi.softAPIP(); Serial.print(AP IP address: ); Serial.println(myIP); // 3. 初始化ESPUI网页界面 // 先设置一些全局回调函数非必须用于调试 ESPUI.setVerbosity(Verbosity::Verbose); // 创建主页面标签 Label* statusLabel ESPUI.label(状态, ControlColor::Turquoise, 系统就绪); ESPUI.begin(万能红外遥控器); Serial.println(网页界面已启动请用浏览器访问上述IP地址。); }在setup()中我们依次启动了红外接收/发射、将ESP32设置为一个Wi-Fi热点、并启动了ESPUI网页服务器。此时用手机搜索Wi-Fi就能找到名为“IR-Smart-Controller”的热点连接后在浏览器输入ESP32的IP地址串口会打印出来通常是192.168.4.1就能看到控制界面了。第三步网页界面构建与回调函数这是项目的交互核心。我们需要动态创建按钮并为每个按钮绑定一个函数当按钮被点击时这个函数就发射对应的红外码。// 声明一个函数用于添加一个可学习的按钮 void addLearnedButton(const String name, int id) { // 在ESPUI的“控制”标签页下添加一个按钮 Button* btn ESPUI.addControl(ControlType::Button, name.c_str(), 学习, ControlColor::Peterriver, Control::noParent, [id](Control* sender, int type) { // 这是按钮的回调函数type表示事件类型如按下、释放 if (type B_DOWN) { // 当按钮被按下时发射存储的红外码 if (id codeIndex) { Serial.println(发射红外码: learnedIRCodes[id]); // 这里需要将字符串格式的红外码转换回原始数据并发射 // 为简化我们先打印出来。实际发射逻辑在后面的学习功能中完善。 } } }); } void setup() { // ... 之前的初始化代码 ... // 4. 构建网页界面 // 创建一个“学习模式”按钮 ESPUI.addControl(ControlType::Button, 进入学习模式, 学习, ControlColor::Alizarin, Control::noParent, [](Control* sender, int type) { if (type B_DOWN) { startLearningMode(); // 调用开始学习模式的函数 } }); // 创建一个标签用于显示学习到的码值 ESPUI.label(学习到的码值, ControlColor::Emerald, 等待学习...); // 开始ESPUI服务 ESPUI.begin(万能红外遥控器); }网页界面构建是在setup()中完成的。我们创建了一个“进入学习模式”的按钮点击它会触发startLearningMode()函数。同时预留了一个标签用来显示学习到的原始码值。第四步红外学习模式实现学习模式是项目的关键。我们需要让ESP32进入一个状态持续监听红外接收头当有信号来时将其原始数据记录下来。bool isLearningMode false; int learningTargetId -1; // 当前正在为哪个按钮ID学习 void startLearningMode() { isLearningMode true; Serial.println(进入学习模式请将遥控器对准接收头并按下一个键...); // 通过ESPUI更新网页状态提示 ESPUI.updateLabel(learnedCodeLabelId, 正在监听请按键...); } void loop() { // 必须调用此函数以处理网页请求和回调 ESPUI.update(); // 红外学习逻辑 if (isLearningMode irrecv.decode(results)) { // 成功接收到一个红外信号 Serial.println(红外信号已接收); // 将接收到的原始结果转换为一个字符串十六进制格式 String irCode resultToHexidecimal(results); Serial.print(原始码值: ); Serial.println(irCode); // 存储这个码值 if (codeIndex 10) { // 防止数组越界 learnedIRCodes[codeIndex] irCode; learningTargetId codeIndex; // 在网页上动态创建一个新的按钮并绑定发射功能 String btnName 设备按键 String(codeIndex 1); addLearnedButton(btnName, codeIndex); // 更新网页显示 ESPUI.updateLabel(learnedCodeLabelId, 已学习: irCode); codeIndex; } else { Serial.println(存储已满无法学习更多按键。); } // 接收完毕准备接收下一个信号 irrecv.resume(); // 退出学习模式或者可以设计成长按进入再按退出 isLearningMode false; Serial.println(学习模式结束。); } // 可以添加其他逻辑比如处理网络事件等 }在loop()函数中我们不断检查是否进入了学习模式以及是否收到了红外信号。irrecv.decode(results)是阻塞式的直到收到一个完整的红外信号才会返回true。收到后我们用resultToHexidecimal函数将复杂的信号结构转换为一个简单的十六进制字符串便于存储和显示。然后我们动态地在网页上创建一个新按钮并将这个字符串码值与其绑定。第五步红外发射功能完善上面我们只完成了码的存储和按钮创建发射功能还需要完善。我们需要将存储的十六进制字符串还原成IRsend对象可以识别的格式并发射。// 一个简化版的发射函数假设我们学习的是NEC协议 void sendLearnedIRCode(int id) { if (id 0 || id codeIndex) return; String hexCode learnedIRCodes[id]; // 将十六进制字符串转换为数值 uint64_t code strtoull(hexCode.c_str(), NULL, 16); // 假设是32位的NEC码 uint32_t necCode (uint32_t)code; Serial.print(发射NEC码: 0x); Serial.println(necCode, HEX); // 使用IRsend对象发射NEC协议编码 irsend.sendNEC(necCode, 32); // 32位数据 } // 修改addLearnedButton中的回调函数 void addLearnedButton(const String name, int id) { Button* btn ESPUI.addControl(ControlType::Button, name.c_str(), name, ControlColor::Peterriver, Control::noParent, [id](Control* sender, int type) { if (type B_DOWN) { sendLearnedIRCode(id); // 调用发射函数 } }); }这里我们假设学习的都是NEC协议最常见的协议之一。sendLearnedIRCode函数将之前存储的字符串转换回数值然后调用irsend.sendNEC()进行发射。但这里有一个巨大的隐患我们怎么知道学习到的是什么协议4.3 协议识别与通用发射方案现实世界中红外协议有几十种NEC, Sony, RC5, RC6, Samsung等它们的编码格式、载波频率、头信号都不同。IRrecv对象可以自动识别很多协议。我们需要存储的不仅仅是原始数据还有协议类型。修改学习部分的代码// 修改存储结构同时存储协议和码值 struct LearnedIR { uint8_t protocol; uint64_t code; uint16_t bits; }; LearnedIR learnedIR[10]; // 在学习模式下 if (isLearningMode irrecv.decode(results)) { Serial.print(识别到协议: ); Serial.println(typeToString(results.decode_type).c_str()); Serial.print(码值: 0x); Serial.println(results.value, HEX); Serial.print(数据位: ); Serial.println(results.bits); // 存储 if (codeIndex 10) { learnedIR[codeIndex].protocol results.decode_type; learnedIR[codeIndex].code results.value; learnedIR[codeIndex].bits results.bits; // ... 后续创建按钮等操作 ... } irrecv.resume(); } // 通用的发射函数 void sendLearnedIRCode(int id) { if (id 0 || id codeIndex) return; LearnedIR ir learnedIR[id]; Serial.printf(发射: 协议%s, 码值0x%llX, 位%d\n, typeToString(ir.protocol).c_str(), ir.code, ir.bits); // 根据不同的协议调用不同的发射函数 switch (ir.protocol) { case decode_type_t::NEC: irsend.sendNEC(ir.code, ir.bits); break; case decode_type_t::SONY: irsend.sendSony(ir.code, ir.bits); break; case decode_type_t::RC5: irsend.sendRC5(ir.code, ir.bits); break; case decode_type_t::RC6: irsend.sendRC6(ir.code, ir.bits); break; // ... 添加更多你需要的协议支持 ... default: Serial.println(不支持的协议尝试发送原始数据。); // 对于不明确或复杂的协议可以发送原始时间数据results.rawbuf // 这需要更复杂的存储和发送逻辑 break; } }通过results.decode_type我们可以获得自动识别的协议枚举。存储时将协议类型、码值和位数一起保存。发射时根据协议类型调用对应的irsend.sendXXX()函数。这是最稳健、最通用的做法。对于库无法自动识别的奇怪协议可以退而求其次存储原始的rawbuf时间数据并用sendRaw()发射但这需要更多内存和更复杂的处理。5. 功能优化与高级玩法基础功能实现后我们可以让这个项目变得更实用、更智能。5.1 美化网页界面与分组控制ESPUI支持基本的控件和样式。我们可以将不同设备的按钮分组并赋予不同的颜色。// 在setup中创建选项卡Tab将不同设备分开 uint16_t tab1 ESPUI.addControl(ControlType::Tab, 客厅, 客厅设备); uint16_t tab2 ESPUI.addControl(ControlType::Tab, 卧室, 卧室设备); // 在特定Tab下添加控件 ESPUI.addControl(ControlType::Button, 空调开, 开, ControlColor::Emerald, tab1, [](Control* sender, int type) { if (type B_DOWN) sendAirConditionerCmd(1); }); ESPUI.addControl(ControlType::Button, 空调关, 关, ControlColor::Alizarin, tab1, [](Control* sender, int type) { if (type B_DOWN) sendAirConditionerCmd(0); }); // 可以添加滑块控制空调温度 ESPUI.addControl(ControlType::Slider, 温度, 26, ControlColor::Sunflower, tab1, [](Control* sender, int type) { if (type SL_VALUE) { int temp sender-value.toInt(); setAirConditionerTemp(temp); } });通过Tab和不同的控件按钮、滑块、标签可以构建出一个直观易用的遥控面板远比物理遥控器清晰。5.2 接入家庭Wi-Fi与远程控制让ESP32连接你家现有的Wi-Fi而不是一直开热点这样更省电且家中所有设备都能访问它。// 在setup中替换掉 WiFi.softAP() const char* homeSSID 你的Wi-Fi名称; const char* homePassword 你的Wi-Fi密码; WiFi.begin(homeSSID, homePassword); Serial.print(正在连接到Wi-Fi); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(\n连接成功); Serial.print(IP地址: ); Serial.println(WiFi.localIP()); // 在路由器后台查看或通过串口打印连接家庭Wi-Fi后你需要知道ESP32从路由器获取到的IP地址串口会打印然后在手机浏览器输入这个IP即可访问。这样只要手机和ESP32在同一个局域网内就能控制。5.3 集成语音控制与自动化这是项目的“智能”升华。我们可以让ESP32接入开源智能家居平台如Home Assistant。通过MQTT接入在ESP32程序中集成MQTT客户端库如PubSubClient。当网页按钮被点击时除了发射红外信号也向一个特定的MQTT主题如ir/controller/ac/on发布一条消息。同时它也订阅另一个主题如ir/controller/command。Home Assistant配置在Home Assistant中安装MQTT集成。然后你可以创建一个开关实体当这个开关被打开时Home Assistant就向ir/controller/command主题发布一条“ac_on”的指令。ESP32收到后就执行发射空调开机红外码的操作。实现语音控制Home Assistant天然支持与Google Assistant、Amazon Alexa或苹果HomeKit集成。一旦你在Home Assistant里创建好了这个“虚拟空调开关”你就可以直接对智能音箱说“嘿Siri打开空调”音箱通知Home AssistantHome Assistant通过MQTT通知ESP32ESP32发射红外信号——空调就开了。这实现了一个完整的本地化智能家居闭环无需任何厂商云服务隐私和安全都掌握在自己手中。6. 常见问题与深度排错指南在实际制作过程中你几乎一定会遇到下面这些问题。我把我的踩坑经验总结在这里。6.1 红外信号学习失败或时灵时不灵现象进入学习模式后按下遥控器按键网页没反应或者偶尔能成功。排查步骤检查电路首先确认红外接收头的VCC是否接3.3VOUT是否接对了GPIO引脚。用手机摄像头对准接收头当你按下遥控器时摄像头里应该能看到接收头内部有微弱的紫色光闪烁手机摄像头能捕捉到红外光这说明接收头在工作且收到了信号。检查代码引脚定义确认kRecvPin常量与你实际连接的GPIO编号一致。ESP32有些引脚在启动时有特殊用途如GPIO0、GPIO2、GPIO15尽量避免使用优先使用像4、5、16、17这样的通用IO。供电不足如果使用USB线供电确保不是从电脑上一个老旧的USB口取电或者线材质量太差。尝试换一个USB充电头供电。红外接收头在接收信号时瞬时电流可能较大供电不稳会导致解码错误。环境光干扰强烈的日光灯、太阳光都含有红外成分会干扰接收。尝试在较暗的环境下学习或者给接收头套上一小段黑色热缩管以减少干扰。库版本与协议确保IRremoteESP8266库是最新版本。有些非常规的或自定义的协议可能无法自动识别。可以在串口监视器中打开详细调试信息在setup()里加上Serial.println(irrecv.toString());然后观察按下遥控器时串口输出的原始时间数据。如果数据看起来有规律但库没识别可能需要查阅该设备的红外协议文档使用sendRaw()功能。6.2 红外发射距离短或无法控制设备现象网页点击按钮ESP32似乎运行了但设备没反应或者必须把发射管贴到设备接收窗上才有用。排查与解决发射管电流这是最常见的原因。我们之前计算了100Ω的限流电阻但这是理论值。实测是王道。你可以尝试将电阻减小到47Ω甚至33Ω以增大电流提高发射功率。注意一定要确保ESP32的GPIO输出电流能力通常单个引脚最大40mA不要超限。并联多个发射管是更好的方案每个管配一个电阻总电流分担到多个GPIO引脚上。发射管方向与位置红外发射管有很强的方向性。确保发射管正面透镜凸起的一面对准设备的红外接收窗。如果设备接收窗位置刁钻可以考虑用一条光纤或透明的塑料棒作为“光导管”将红外光引导过去。协议或码值错误确保发射的协议和码值完全正确。有些设备如某些品牌的空调需要发送一长串复杂的编码或者需要连续发送两次。可以在学习时用串口监视器仔细对比成功控制时的码值和你存储发射的码值是否完全一致包括协议类型。载波频率偏差虽然ESP32的RMT硬件产生38kHz载波很准但有些设备可能对频率敏感。IRsend对象在初始化时可以调整载波频率irsend.begin(kIrLedPin, true); // 第二个参数为是否启用调试会微调频率但通常不需要。6.3 网页无法访问或连接不稳定现象手机搜不到ESP32的热点或者连接后打不开网页或者网页时好时坏。排查步骤热点名称密码检查代码中ssid和password是否含有特殊字符或过长。建议只用字母和数字且密码至少8位。IP地址冲突如果ESP32连接了家庭Wi-Fi确保它的IP地址没有被路由器分配给其他设备。最好在路由器后台为ESP32的MAC地址设置静态IP分配。ESP32内存不足ESPUI和红外库同时运行可能占用较多内存。如果网页复杂按钮过多可能导致ESP32重启。在Arduino IDE的工具-Partition Scheme中选择“Huge APP (3MB No OTA)”来获得更大的程序存储空间。同时优化代码避免使用过多的String类操作多用字符数组(char[])。网络干扰如果处于Wi-Fi信号复杂的环境如公寓楼尝试在代码中更改ESP32的热点信道WiFi.softAP(ssid, password, 1, 0, 4);其中第4个参数0表示不隐藏第5个参数4表示信道可以尝试1, 6, 11。6.4 设备重启或程序崩溃现象运行一段时间后ESP32自动重启或者网页无响应。可能原因与解决看门狗定时器WatchDog触发ESP32有硬件看门狗如果某个任务如复杂的红外解码长时间阻塞主循环(loop())看门狗会强制重启。确保loop()函数执行时间不能太长。在irrecv.decode()这类可能阻塞的函数前后可以调用yield()或delay(0)来喂看门狗。堆内存碎片化频繁的动态内存分配如String拼接会导致内存碎片最终分配失败而崩溃。对于需要频繁更新的字符串如网页状态显示可以定义为全局静态字符数组。电源问题发射红外信号时电流骤增如果电源线太长或太细可能导致电压瞬间跌落引发ESP32复位。尽量使用短的、质量好的USB线并靠近ESP32供电。这个项目从硬件焊接、代码编写到问题排查几乎涵盖了嵌入式物联网开发的完整流程。它不仅仅是一个万能遥控器更是一个理解信号处理、网络通信和嵌入式系统设计的绝佳实践。当你成功用手机控制老家电的那一刻那种创造的成就感是购买成品智能插座无法比拟的。最重要的是你拥有了一个完全受控于本地网络的智能核心隐私、速度和可靠性都掌握在自己手里这才是智能家居DIY的终极乐趣所在。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价