news 2026/6/2 15:48:13

基于ESP32与Blynk的8路继电器双控系统:网络/本地冗余智能开关方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于ESP32与Blynk的8路继电器双控系统:网络/本地冗余智能开关方案

1. 项目概述:打造一个不断网的智能开关

折腾智能家居的朋友,估计都遇到过这样的尴尬:兴致勃勃地用手机App关掉了客厅的灯,结果家里WiFi一抽风,或者路由器重启,灯就彻底“失联”了,想关关不掉,想开开不了,最后还得摸黑去找物理开关。这种“智能”变“智障”的体验,实在是让人头疼。

所以,我一直想做一个真正靠谱的、能应对网络波动的智能开关方案。核心需求很简单:有网时,用手机远程控制,享受便利;没网时,立刻能用手边的实体按键控制,保证基础功能绝不掉链子。这听起来像是两个独立系统,但用ESP32来实现,却能巧妙地合二为一。

ESP32这颗芯片真是物联网项目的“万金油”,双核处理器、丰富的GPIO、集成的WiFi和蓝牙,价格还非常亲民。而Blynk平台则大大降低了物联网App的开发门槛,拖拖拽拽就能创建一个功能完善的手机控制界面,特别适合我们这种更偏重硬件和嵌入式逻辑的开发者。

这次要分享的,就是基于ESP32和Blynk搭建的一套8路继电器控制系统。它不仅仅是一个简单的手机遥控器,更是一个具备本地冗余控制能力的自动化节点。无论网络状况如何,你都能掌控家里的灯光、风扇、插座等设备。下面,我就把从电路设计、代码编写到PCB制作、调试上线的完整过程,以及其中踩过的坑和总结的经验,毫无保留地分享出来。

2. 系统核心设计思路与方案选型

2.1 为什么选择“WiFi + 手动”双控架构?

智能家居的可靠性是用户体验的基石。纯云端控制的方案严重依赖网络质量和服务器稳定性,一旦出现波动,所有设备即刻“瘫痪”。而纯本地手动控制,又失去了智能化的便利性。因此,双控架构成为了平衡便利与可靠性的最优解。

在这个项目中,双控的逻辑优先级是:手动控制为最高优先级,且完全独立于网络状态。这意味着即使ESP32芯片本身程序跑飞了(虽然概率极低),你仍然可以通过物理按钮直接操控继电器背后的电路。网络控制则作为便捷的增强功能,在网络通畅时提供远程操作能力。这种设计哲学确保了系统在最坏情况下,依然能回归到一个传统的、可用的开关面板。

2.2 主控芯片:ESP32为何是理想选择?

在众多微控制器中,选择ESP32 DEVKIT V1模块,主要基于以下几点考量:

  1. 集成无线连接:内置WiFi和蓝牙,无需外接模块,简化了电路设计和成本。对于家庭局域网内的IoT设备,WiFi的普及性和带宽完全足够。
  2. 充足的IO资源:我们需要控制8路继电器,同时监测8个手动按钮的状态,这至少需要16个数字IO口。ESP32提供了丰富的GPIO,轻松满足需求,甚至还有富余。
  3. 强大的社区与生态:Arduino IDE对ESP32的支持已经非常成熟,有海量的库和教程。Blynk也提供了专门的ESP32库,集成起来非常方便。
  4. 成本与性能平衡:相比需要通过额外芯片实现网络功能的Arduino方案,ESP32提供了更高的集成度和更具竞争力的价格。

2.3 控制逻辑与状态同步的实现难点

双控方案最核心的技术难点在于状态同步。举个例子:你通过手机App打开了第1路继电器(灯亮),然后走到墙边,用手动按钮关闭了它(灯灭)。此时,手机App上的按钮状态应该从“ON”变为“OFF”,以反映真实的设备状态。反之亦然。

实现这一点的关键在于:

  • 手动按钮动作的实时检测:ESP32需要不断扫描按钮状态。一旦检测到变化,立即驱动对应的继电器,同时将这个状态变化通过Blynk库的接口“同步”到云端,进而更新手机App上的虚拟按钮状态。
  • 网络控制指令的响应:当通过Blynk App操作时,指令经由Blynk云发送到ESP32。ESP32收到后驱动继电器,同时,因为手动按钮是物理输入,其状态并未改变,所以不需要反向操作。但代码里必须处理好,避免网络指令触发错误的本地按钮检测逻辑。

这就要求我们的代码不能是简单的“if-else”,而需要一个状态机来清晰管理每个通道的当前状态、控制来源以及需要执行的动作。在后面的代码详解部分,我们会看到如何优雅地实现这一点。

3. 硬件电路设计与核心元件解析

3.1 整体电路框架与供电设计

整个系统的硬件核心可以分为三大部分:ESP32主控模块、8路继电器驱动电路、8路手动输入检测电路。它们由一个统一的5V直流电源供电。

注意:强烈建议使用像旧手机充电器这样带有隔离保护的开关电源作为5V电源。绝对不要为了省事,直接从继电器控制的高压市电侧通过降压模块取电,这会将高压侧的干扰和危险引入低压控制电路,极易损坏ESP32,并带来严重的安全隐患。

供电路径如下:5V电源正极同时接入ESP32的VIN引脚(其内部有稳压电路)和继电器模块的VCC引脚。所有地线(GND)必须可靠连接在一起,形成共同的参考地。

3.2 继电器驱动电路详解:为什么需要三极管和光耦?

ESP32的GPIO引脚输出电流能力有限(通常约40mA),而5V继电器线圈的吸合电流往往在70mA以上,直接驱动会损坏ESP32。因此,必须使用三极管作为电流放大开关。

这里选用常见的NPN型三极管BC547。其驱动原理是:当ESP32的GPIO输出高电平(3.3V)时,通过一个基极限流电阻(如1kΩ)使三极管饱和导通,继电器线圈得电吸合;GPIO输出低电平时,三极管截止,线圈失电释放。继电器线圈是感性负载,断电时会产生很高的反向电动势,所以在线圈两端需要并联一个续流二极管(1N4007),为这个感应电流提供泄放回路,保护三极管不被击穿。

然而,仅有三极管隔离还不够。继电器在控制空调、水泵等大功率感性负载时,开合瞬间会产生强烈的电磁干扰和火花,这些干扰可能通过电源线或空间耦合窜入控制电路。为了进一步增强系统的抗干扰能力和安全性,我在三极管驱动级之前加入了光电耦合器PC817

光耦的作用是实现“电气隔离”:ESP32侧的信号通过发光二极管传递到光敏三极管侧,两者之间没有电气连接,只有光束传递。这样,继电器侧产生的任何电压尖峰和噪声都无法直接传导到敏感的ESP32芯片上,极大地提高了系统的稳定性和可靠性。虽然增加了少许成本和复杂度,但对于长期稳定运行的家居设备来说,这笔投资非常值得。

3.3 手动输入电路:巧用内部上拉电阻

手动按钮输入电路的设计目标是稳定、防抖、节省元件。我采用了INPUT_PULLUP模式,即利用ESP32芯片内部的上拉电阻。

电路连接非常简单:按钮一端接对应的GPIO引脚,另一端直接接地。未按下按钮时,由于内部上拉电阻的作用,GPIO引脚被拉至高电平(约3.3V),读取到的状态为HIGH1。当按钮按下时,引脚直接与地短路,电平被拉低至0V,状态变为LOW0

这种方式的优点:

  • 节省外部电阻:无需为每个按钮外接一个物理的上拉电阻。
  • 电路简洁:布线更简单,PCB布局更紧凑。
  • 降低功耗:在稳定状态下,内部上拉电阻的电流通路非常小。

需要注意的是,机械按钮在按下和弹起时会产生抖动,即电平会在短时间内多次快速变化。必须在软件中通过消抖逻辑来处理,例如检测到电平变化后,延时20-50毫秒再次读取,以确认稳定的状态。

3.4 PCB设计:从面包板到专业制造

在面包板上验证所有功能无误后,为了系统的长期稳定性和美观,设计一块定制PCB是必要的步骤。使用立创EDA这类免费工具,可以相对轻松地完成。

PCB布局要点:

  1. 强弱电分区:将高压市电走线(继电器输出端子附近)和低压控制电路(ESP32、光耦左侧)严格分开,保持足够的爬电距离(建议大于3mm)。可以用丝印层画一条线作为视觉区分。
  2. 电源走线加粗:为5V和GND网络使用更宽的走线(如30-40mil),以减少阻抗,确保为所有芯片和继电器提供稳定电压。
  3. 信号线避免平行长走线:特别是按钮输入线,尽量短且避免与继电器驱动线长距离平行,减少干扰。
  4. 添加测试点与指示灯:在关键电源节点(5V, 3.3V)和每个继电器控制信号线上放置测试焊盘。为每一路继电器和网络状态(如WiFi连接)设计LED指示灯,便于调试。
  5. 散热考虑:如果继电器需要频繁切换大电流负载,可以考虑在PCB上为继电器线圈驱动三极管增加小的散热铜皮。

将设计好的PCB文件(Gerber格式)发给像嘉立创这样的PCB打样厂商,通常只需很低的成本就能获得品质优秀的成品板,这比用洞洞板手工焊接要可靠和美观得多。

4. 软件代码实现与Blynk平台配置

4.1 开发环境搭建与库安装

首先,需要在Arduino IDE中安装ESP32开发板支持。

  1. 打开Arduino IDE,进入“文件” -> “首选项”,在“附加开发板管理器网址”中添加:https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  2. 打开“工具” -> “开发板” -> “开发板管理器”,搜索“esp32”,找到并安装“Espressif Systems”提供的ESP32平台。
  3. 安装完成后,在“工具” -> “开发板”中选择“ESP32 Dev Module”或“DOIT ESP32 DEVKIT V1”。

接下来安装Blynk库。

  1. 在Arduino IDE中,点击“项目” -> “加载库” -> “管理库...”。
  2. 在库管理器中搜索“Blynk”,选择由“Volodymyr Shymanskyy”发布的版本进行安装。

4.2 Blynk项目创建与设备虚拟引脚映射

Blynk的操作逻辑是:手机App上的控件(如按钮、滑块)被绑定到一个“虚拟引脚”(V0, V1, V2...)上。在ESP32的代码中,我们通过读写这些虚拟引脚的值,来实现与App的交互。

创建Blynk项目的步骤:

  1. 手机下载并安装Blynk App(新版本为Blynk IoT)。
  2. 注册账号并登录。
  3. 点击“New Project”,输入项目名称(如“Home Control”)。
  4. 在“Choose Device”中选择“ESP32”。
  5. “Connection Type”选择“Wi-Fi”。
  6. 点击“Create”,Blynk会自动生成一个Auth Token(认证令牌),并通过邮件发送给你。这个Token是设备连接Blynk云的唯一凭证,至关重要,需要填入后续的代码中。

配置控件:

  1. 在项目编辑界面,从组件库中拖入8个“Button”控件。
  2. 分别点击每个按钮进行设置。关键是将“PIN”设置为虚拟引脚,例如第一个按钮设为V1,第二个V2,以此类推直到V8
  3. 将“MODE”设置为“SWITCH”,这样按钮会保持开/关状态,而不是点按一次就复位。
  4. 你还可以设置按钮的标签、颜色等,让界面更直观。

4.3 核心代码逻辑深度剖析

代码的核心是处理三个事件源:Blynk虚拟引脚值变化物理按钮状态变化网络连接状态变化。下面是一个高度精简和注释后的逻辑框架:

// 定义引脚和变量 #define BLYNK_PRINT Serial // 启用调试信息输出 #include <WiFi.h> #include <WiFiClient.h> #include <BlynkSimpleEsp32.h> char auth[] = "YourAuthToken"; // 替换为你的Blynk Auth Token char ssid[] = "YourWiFiSSID"; char pass[] = "YourWiFiPassword"; // 继电器控制引脚 (输出) int relayPins[] = {23, 22, 21, 19, 18, 5, 25, 26}; // 手动按钮引脚 (输入,使用内部上拉) int buttonPins[] = {13, 12, 14, 27, 33, 32, 15, 4}; // 记录继电器当前状态 bool relayState[8] = {false}; // 记录按钮上一次的状态,用于检测变化 bool lastButtonState[8] = {HIGH}; // 初始为上拉状态(HIGH) BlynkTimer timer; // 创建一个定时器对象 // BLYNK_WRITE函数:当App改变虚拟引脚Vx的值时,此函数被自动调用 BLYNK_WRITE(V1) { int pinValue = param.asInt(); // 获取从App发来的值,0或1 controlRelay(0, pinValue); // 控制第1路继电器(索引0) // 注意:这里不需要同步到按钮,因为按钮是物理输入,状态独立。 } // 为V2到V8编写类似的BLYNK_WRITE函数... // 控制继电器的统一函数 void controlRelay(int channel, bool state) { digitalWrite(relayPins[channel], state ? HIGH : LOW); // 驱动继电器 relayState[channel] = state; // 更新状态记录 // 如果网络连通,将状态同步回Blynk App(确保App显示一致) if(Blynk.connected()){ Blynk.virtualWrite(channel + 1, state); // V1对应channel 0, 故+1 } } // 检查按钮状态的函数,由定时器定期调用 void checkButtonStatus() { for(int i=0; i<8; i++) { bool currentButtonState = digitalRead(buttonPins[i]); // 检测按钮状态是否发生变化(从高到低,即按下) if (lastButtonState[i] == HIGH && currentButtonState == LOW) { delay(50); // 简单消抖延时 if(digitalRead(buttonPins[i]) == LOW) { // 再次确认按下 // 按钮按下,切换对应继电器的状态 bool newState = !relayState[i]; controlRelay(i, newState); } } lastButtonState[i] = currentButtonState; // 更新上一次的状态 } } // 网络连接状态检查函数 void checkWiFiConnection() { static bool lastConnected = false; if (WiFi.status() != WL_CONNECTED) { Serial.println("WiFi连接断开,尝试重连..."); // 此时Blynk会自动尝试重连,但手动控制依然有效 if (lastConnected) { lastConnected = false; } } else { if (!lastConnected) { Serial.println("WiFi已连接"); lastConnected = true; } } } void setup() { Serial.begin(115200); // 初始化继电器引脚为输出,并初始化为关闭状态 for(int i=0; i<8; i++) { pinMode(relayPins[i], OUTPUT); digitalWrite(relayPins[i], HIGH); // 假设继电器是低电平触发,初始给高电平关闭 } // 初始化按钮引脚为输入,并启用内部上拉电阻 for(int i=0; i<8; i++) { pinMode(buttonPins[i], INPUT_PULLUP); } // 连接Blynk Blynk.begin(auth, ssid, pass); // 也可以指定服务器: Blynk.begin(auth, ssid, pass, "blynk.cloud", 8080); // 设置一个定时器,每200毫秒执行一次checkButtonStatus函数 timer.setInterval(200L, checkButtonStatus); // 设置另一个定时器,每3秒检查一次WiFi连接状态 timer.setInterval(3000L, checkWiFiConnection); } void loop() { Blynk.run(); // 必须持续运行,以处理Blynk通信 timer.run(); // 运行定时器,执行定时任务 }

代码关键点解析:

  • 状态同步controlRelay函数是核心。无论是来自Blynk的调用还是按钮检测的调用,最终都通过这个函数来实际控制继电器。在控制之后,如果Blynk连接正常,会通过Blynk.virtualWrite将最新状态发回App,确保手机界面显示与实际设备状态一致。
  • 消抖处理:在checkButtonStatus函数中,检测到按钮按下(电平从高变低)后,延时50毫秒再次读取,如果仍然是低电平,才确认为有效按下动作。这是处理机械开关抖动的经典方法。
  • 非阻塞设计:使用BlynkTimer来定期执行按钮扫描和网络检查,而不是在loop()中使用delay()。这保证了Blynk的网络通信(Blynk.run())能够及时得到处理,系统响应更灵敏。

4.4 代码上传与ESP32启动模式

将上述代码中的authssidpass替换为你自己的信息后,在Arduino IDE中选择正确的开发板型号和端口,点击上传。

一个常见的坑:很多ESP32开发板在上传程序时需要手动进入下载模式。如果看到串口监视器输出“Connecting….”后卡住,通常需要按住开发板上的“BOOT”按钮不放,然后短暂按一下“EN/RST”按钮,再松开“BOOT”按钮,即可让芯片进入下载模式,程序上传会自动继续。

5. 系统组装、调试与实战部署

5.1 焊接与组装注意事项

收到PCB后,焊接顺序建议遵循“先低后高,先内后外”的原则:

  1. 焊接贴片电阻、二极管、光耦:这些元件高度低,先焊接避免遮挡。
  2. 焊接晶体管、LED:注意晶体管和LED的极性,PCB上通常有标记。
  3. 焊接排针、接线端子:用于连接ESP32和外部电源/负载的端子。
  4. 焊接电解电容(如有)和继电器:继电器是最终的大件,注意将其插紧并与PCB焊盘对齐后再焊接。
  5. 最后安装ESP32:建议使用排母焊接在PCB上,然后将ESP32开发板像插卡一样插入。这样既方便固定,也利于日后更换或升级ESP32模块。

焊接完成后,务必进行目视检查通断测试

  • 检查是否有虚焊、连锡、元件焊反。
  • 用万用表蜂鸣档,检查电源正负极之间是否短路。
  • 检查每个按钮引脚对地是否能在按下时导通。

5.2 上电测试与功能验证

安全第一!在连接任何家用电器(220V)之前,务必在低压(5V)环境下完成所有控制逻辑测试。

  1. 供电测试:仅连接5V电源,用万用表测量PCB上的5V和3.3V电压是否正常。观察电源指示灯和ESP32是否上电。
  2. 程序加载测试:通过USB线给ESP32供电并上传程序。打开串口监视器(波特率115200),观察输出。成功连接WiFi和Blynk后,会看到相应的提示信息。
  3. 继电器动作测试:不接高压负载,用手机Blynk App操作各个按钮,同时用耳朵听或万用表测量继电器输出端,确认对应继电器能正常吸合/释放。同样,手动按下PCB上的物理按钮,测试其控制功能。
  4. 状态同步测试:这是关键。用手机App打开一路继电器,然后立刻用手动按钮关闭它,观察手机App上该路按钮的状态是否很快(1-2秒内)从“ON”变成了“OFF”。反复测试,确保双向同步迅速准确。
  5. 断网测试:关闭路由器或让手机断开WiFi(使用移动数据),测试手动按钮是否依然能正常控制继电器。然后恢复网络,观察ESP32是否能自动重连,并且App上的状态是否更新为当前实际状态。

5.3 连接家用电器与安全规范

在低压测试全部通过后,方可连接家用电器。

警告:操作高压电有生命危险!如果你不是专业电工,请务必在有经验的人员指导下进行,或仅将此系统用于控制低压直流设备(如LED灯带、12V风扇)。

  1. 断电操作:确保所有要连接的电路(如灯线、插座线)处于完全断电状态。用验电笔再次确认。
  2. 负载选择:确认你的继电器模块的触点容量(如10A 250VAC)。绝对不要用它去控制超过其额定功率的负载,尤其是空调、热水器等大功率电器。建议先从台灯、风扇等小功率电器开始。
  3. 接线规范
    • 火线(L)接入继电器的公共端(COM)。
    • 将继电器的常开端(NO)接到负载(如灯)的一端。
    • 负载的另一端接零线(N)
    • 地线(PE)必须可靠连接到负载的外壳(如果负载是金属外壳)。
    • 所有高压接线点必须用绝缘胶带或热缩管包裹严实,并确保线头紧固,无铜丝外露。
  4. 绝缘与固定:将整个控制板装入一个绝缘、阻燃的塑料或金属电箱内。所有高压部分必须与低压部分(ESP32、USB口等)有物理隔离或保持足够距离。

5.4 系统优化与扩展思路

这个基础框架有很大的扩展潜力:

  1. 增加状态反馈:除了控制,还可以将负载的实际电流、电压(通过传感器)或门的开关状态(通过干簧管)反馈到Blynk App上,实现真正的监控。
  2. 场景联动:利用Blynk App内的“Widget Bridge”或编写更复杂的代码,实现多设备联动。例如,“离家模式”一个按钮关闭所有继电器;“影院模式”关闭主灯、打开氛围灯。
  3. 本地Web服务器:除了Blynk,还可以让ESP32同时作为一个Web服务器。这样即使在家庭局域网内,也可以通过浏览器输入ESP32的IP地址来访问一个控制页面,作为Blynk的备用控制方式。
  4. OTA升级:配置ESP32的OTA(空中下载)功能,以后更新程序无需再插拔USB线,直接在Blynk App或Web页面上传新固件即可。
  5. 低功耗优化:如果用于电池供电的场景(如无线开关),可以优化代码,让ESP32大部分时间处于深度睡眠模式,仅在按钮按下时唤醒连接网络发送指令,从而极大延长续航。

6. 常见问题与故障排查实录

在实际制作和调试过程中,你几乎一定会遇到下面这些问题。这里我把它们和解决方案整理出来,希望能帮你节省大量时间。

6.1 编译与上传问题

问题现象可能原因解决方案
编译错误:fatal error: BlynkSimpleEsp32.h: No such file or directoryBlynk库未正确安装。在Arduino IDE中,通过“管理库”重新搜索安装Blynk库,确保安装的是适用于ESP32的版本。
上传失败,提示“Timed out waiting for packet header”或一直“Connecting…”ESP32未进入下载模式;驱动未安装;端口被占用。1. 按前文所述操作BOOT和EN按钮。
2. 检查设备管理器中是否有未识别的设备(需安装CP210x或CH340驱动)。
3. 关闭所有可能占用串口的软件(如串口监视器、其他IDE)。
上传成功,但ESP32不断重启(看串口日志)代码存在逻辑错误导致崩溃;电源供电不足。1. 检查代码中数组越界、空指针等常见错误。
2. 确保使用足额电流(建议1A以上)的5V电源单独为ESP32和继电器模块供电。继电器同时吸合时瞬间电流很大。

6.2 网络连接与Blynk通信问题

问题现象可能原因解决方案
串口显示连接WiFi失败WiFi密码错误;信号太弱;路由器设置了MAC过滤或仅允许特定设备连接。1. 仔细检查代码中的SSID和密码(区分大小写)。
2. 将ESP32靠近路由器测试。
3. 检查路由器后台设置。
连接Blynk服务器失败Auth Token错误;网络防火墙或DNS问题;Blynk服务器区域问题。1. 核对并重新从Blynk App复制Auth Token。
2. 尝试在代码中指定Blynk服务器和端口:Blynk.begin(auth, ssid, pass, "blynk.cloud", 8080);
3. 某些网络环境可能需要配置DNS。
手机App能控制,但状态不同步或延迟高网络延迟;代码中状态同步逻辑有误;虚拟引脚映射错误。1. 检查家庭WiFi信号强度。
2. 在controlRelay函数中,确保每次继电器动作后都执行了Blynk.virtualWrite
3. 核对App中按钮控件绑定的虚拟引脚号(V1-V8)与代码中BLYNK_WRITE(Vx)Blynk.virtualWrite使用的引脚号是否一致。

6.3 硬件与功能异常问题

问题现象可能原因解决方案
某一路继电器不受控制,常开或常闭对应的驱动三极管、光耦损坏或焊接不良;继电器本身损坏。1. 用万用表测量该路控制信号(光耦输出端)在操作时是否有高低电平变化。若无,向前级检查。
2. 直接给继电器线圈施加5V电压,看其能否正常动作,以判断继电器好坏。
手动按钮控制不灵敏或误触发软件消抖时间不合适;按钮接触不良;内部上拉电阻未启用。1. 调整checkButtonStatus函数中的消抖延时(如从50ms改为30ms或70ms)。
2. 更换按钮或检查焊接。
3. 确认pinMode设置为了INPUT_PULLUP
所有继电器同时乱跳或ESP32复位电源功率不足,继电器集体动作时引起电压骤降。这是最常见的问题!务必使用输出电流大于2A的5V电源适配器。继电器吸合瞬间电流是保持电流的3-5倍。可以在电源输入端并联一个较大容量的电解电容(如1000uF)作为储能缓冲。
控制高压负载时,ESP32偶尔死机继电器开合产生的电磁干扰通过电源或空间耦合进控制电路。1.确保使用了光耦进行隔离,这是抗干扰的关键。
2. 在继电器线圈两端和触点两端并联RC吸收电路(如0.1uF电容串联100Ω电阻)。
3. 为ESP32的电源增加π型滤波电路(如10uF电解电容并联0.1uF陶瓷电容)。

6.4 一个关于“初始状态”的隐藏坑

在项目初次上电时,继电器应该处于什么状态?是全部关闭,还是恢复断电前的状态?这需要根据实际应用来决定。我们的代码中,setup()函数里将继电器引脚初始化为HIGH(假设低电平触发),这意味着上电后所有继电器是关闭的。

但有时我们希望系统能记忆断电前的状态,这需要用到ESP32的非易失性存储(NVS)。可以在每次继电器状态改变时,将其保存到NVS;在setup()中,先从NVS读取保存的状态,然后据此初始化继电器。这样即使意外断电再上电,设备也能恢复到之前的状态。虽然增加了代码复杂度,但对于某些场景(如鱼缸灯、通风扇)非常实用。

折腾这个项目的过程中,最大的体会就是“细节决定成败”。一个不起眼的电源问题、一个没处理好的按钮抖动、一条走得不好的信号线,都可能导致整个系统工作不稳定。从面包板上的原型,到精心布局的PCB,再到严谨的代码逻辑和彻底的测试,每一步的耐心和细致,最终换来的就是一个你完全可以信赖的、安静可靠地为你服务智能家居节点。当你可以自信地在外用手机打开家里的热水器,回到家发现网络断了却依然能用墙上的开关打开灯时,那种一切尽在掌控的感觉,就是DIY智能家居最大的乐趣所在。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 15:46:48

STM32C542开发(3)----配置串口打印

STM32C542开发.3--配置串口打印概述视频教学样品申请源码下载硬件准备参考程序生成STM32CUBEMX2时钟树配置DEBUG配置串口配置生成项目导入STM32CubeIDE设置工程编码添加头文件printf 重定向串口打印测试演示概述 在传统 STM32 开发中&#xff0c;我们通常会通过 STM32CubeMX 配…

作者头像 李华
网站建设 2026/6/2 15:45:35

从零构建聊天机器人记忆系统:基于LLM与向量检索的工程实践

1. 项目概述&#xff1a;从零构建聊天机器人记忆系统 最近几年&#xff0c;大语言模型驱动的聊天机器人遍地开花&#xff0c;但很多开发者都踩过同一个坑&#xff1a;聊着聊着&#xff0c;机器人就“失忆”了。你刚告诉它你养了一只叫“奥利奥”的猫&#xff0c;三句话之后它可…

作者头像 李华
网站建设 2026/6/2 15:44:55

2026石家庄APP开发费用深度解析:行业报价真相、成本构成与避坑全攻略

收藏不亏&#xff1a;本文基于2026年石家庄本地软件开发真实市场行情&#xff0c;深度拆解APP开发定价底层逻辑&#xff0c;破除低价套路、隐形消费、模板冒充定制等行业乱象&#xff0c;为本地中小企业、实体商家、初创创业者提供可落地的预算参考与项目风控方案。在数字化转型…

作者头像 李华