
1. 项目概述与核心价值家里有老人或者听力不太好的朋友最怕的就是听不到门铃响。我自己就深有体会每逢家里孩子开生日派对客厅里吵得跟集市一样普通的门铃声音完全被淹没好几次都错过了快递或者访客。传统的闪光门铃要么太贵要么安装复杂还得单独布线实在不够灵活。作为一个喜欢折腾Arduino、ESP8266和3D打印的玩家我就在想能不能用手里现成的智能家居组件花最少的钱把家里那个普通的交流门铃改造成一个智能通知中心这个想法催生了今天要分享的项目一个基于ESP-now和MQTT的智能门铃通知系统。这个系统的核心思路非常直接让物理世界的“按门铃”这个动作变成智能家居里一个可以被任意编排的数字事件。它不再仅仅依赖于声音而是可以通过灯光、手机通知、甚至联动其他智能设备比如自动打开摄像头等多种方式来提醒你。这对于听力障碍人士、在嘈杂环境中工作的人或者只是想给家里增添一点自动化便利的用户来说都非常实用。整个方案的成本可以控制在几十元以内核心是一块ESP-01S Wi-Fi模块和一些常见的电子元件技术栈则围绕低功耗、高可靠的ESP-now点对点通信和灵活的MQTT消息协议展开。下面我就把自己从电路设计、代码调试到集成到OpenHAB家庭自动化平台的全过程包括中间踩过的坑和总结的经验毫无保留地分享出来。2. 系统架构与方案选型解析在动手之前我们需要先理清整个系统的数据流和为什么选择这样的技术组合。一个典型的门铃改造项目无非是检测门铃按钮被按下的事件然后将这个事件通知给用户。但如何检测、如何通知、如何融入现有智能家居生态这里面的选择就大有讲究了。2.1 核心需求与设计思路我们的核心需求很明确可靠、低成本、非侵入式改造、易于集成。可靠门铃通知不能丢消息必须保证每次按下都能触发后续动作。低成本希望用最普及、最廉价的硬件实现。非侵入式改造最好不需要改动家中原有的门铃线路主体以并联或感应方式接入。易于集成生成的事件应该能被主流的智能家居平台如Home Assistant, OpenHAB 甚至国内的米家通过网关轻易捕获和处理。基于这些需求我设计了如下图所示的系统架构注此处为文字描述架构。整个系统分为三层传感与边缘层位于门铃旁边。由一个简单的电路板构成核心是ESP-01S模块。它的任务是检测门铃线上的电压变化即有人按铃然后将这个“按下”事件通过无线信号发送出去。网络与网关层负责接收边缘层发来的消息并将其转换、转发到家庭自动化网络中。这里我使用了ESP-now协议将数据从门铃传感器发送到一个常供电的ESP-now转MQTT网关上。这个网关再通过Wi-Fi连接家庭路由器使用MQTT协议将事件发布到指定的主题Topic。应用与通知层即家庭自动化服务器我使用的是OpenHAB。它订阅了MQTT的特定主题一旦收到“门铃按下”的消息就可以执行预设的自动化规则比如让客厅的智能彩灯闪烁红光、在手机APP上发送推送通知、在控制面板的界面上记录最后一次按铃的时间等。2.2 关键技术选型为什么是ESP-now MQTT市面上无线模块和协议那么多为什么偏偏选中了这对组合首先为什么用ESP-now而不是直接让ESP-01S连Wi-FiESP-01S本身支持Wi-Fi似乎可以直接连接路由器并发送MQTT消息。但这在实际应用中存在几个问题功耗与响应速度门铃传感器我们希望它平时深度休眠以省电如果用电池供电只在按铃时瞬间唤醒工作。让ESP-01S每次唤醒都去执行完整的Wi-Fi连接、获取IP、连接MQTT服务器这一套流程耗时可能长达数秒延迟太高而且功耗也大。ESP-now是一种低功耗的2.4GHz无线通信协议它允许ESP设备之间直接、快速地进行数据交换无需经过路由器。ESP-01S从睡眠中唤醒可以在几十毫秒内通过ESP-now将消息发出然后迅速回到睡眠状态极其省电且响应迅速。网络依赖性如果家里的Wi-Fi路由器重启或者网络不稳定直接连Wi-Fi的传感器可能会失联。而ESP-now是设备间直连只要网关和设备之间的距离在范围内通信就不受家庭主干网络状态的影响可靠性更高。简化配置对于仅需发送几个字节状态信息的传感器节点ESP-now的编程模型比管理Wi-Fi连接和MQTT客户端要简单直接得多。其次为什么还要用MQTTESP-now解决了“最后一米”的快速、可靠传感数据采集问题但它是一个封闭的点对点或点对多点网络消息无法直接被家庭自动化服务器理解。这时就需要一个网关来桥接两个世界。这个网关通常是一个常供电的ESP32或ESP8266设备它一方面通过ESP-now接收所有传感器节点的数据另一方面通过Wi-Fi连接家庭网络并作为一个MQTT客户端。MQTT协议是一个轻量级的“发布/订阅”消息协议几乎是物联网和智能家居的事实标准。它的优势在于解耦传感器发布者和自动化应用订阅者不需要知道彼此的存在它们只和MQTT代理服务器Broker通信。灵活你可以轻松地增加新的通知方式比如再增加一个手机订阅而无需修改传感器或网关的代码。跨平台几乎所有智能家居平台都原生支持MQTT这使得本项目可以无缝接入OpenHAB、Home Assistant、Node-RED等。所以ESP-now MQTT的组合实际上是用ESP-now优化了边缘传感层的功耗和实时性用MQTT保证了系统核心的灵活性和可集成性两者相辅相成构成了一个非常经典的物联网分层架构。2.3 硬件选型清单与替代方案我的核心硬件清单如下所有元件都非常常见且廉价ESP-01S项目核心负责检测与无线发送。选择它是因为价格极低约10元、体积小巧。注意ESP-01S的工作电压是3.3V且GPIO口很少仅有两个可用的用户GPIOGPIO0和GPIO2在设计电路时需要特别注意。1N4001二极管4个用于搭建全桥整流电路将门铃的交流电AC转换为直流电DC。AMS1117-3.3电压稳压器将整流滤波后的较高直流电压约7-10V DC稳定地降至3.3V为ESP-01S供电。这是整个电路的“心脏”选择不当会烧毁模块。电容10uF和1000uF各一用于电源滤波。10uF通常放在AMS1117的输入输出端用于高频滤波1000uF的大电容放在整流桥之后用于平滑整流后的脉动直流电尤其在门铃按下这种瞬时供电场景下能为后续电路提供稳定的能量。电阻7.5k或10k作为上拉或下拉电阻用于确保ESP-01S的GPIO引脚在不确定状态时有确定的电平防止误触发。万用板洞洞板、连接线、接插件等。注意关于电源方案的深度思考原项目中使用门铃变压器的8V AC作为电源经整流稳压后给ESP-01S供电。这是一个“取电”思路好处是一劳永逸无需电池。但前提是必须确认你家门铃变压器有足够的功率余量。老式门铃变压器通常功率很小3-5VA在驱动原有门铃线圈的同时可能无法再为ESP模块提供稳定的100-200mA的启动电流。强烈建议在改造前用万用表测量门铃在按下和未按下时线路两端的电压。如果按下后电压跌落严重说明变压器容量不足可能需要单独为传感器配备一个5V/1A的USB电源适配器从附近插座取电。安全永远是第一位的。3. 电路设计与核心原理详解这是整个项目中最需要耐心和细心的部分尤其是处理交流电部分务必谨慎。我的设计过程并非一帆风顺经历了“计划A”的失败才转向“计划B”。3.1 初版方案计划A的失败与原因分析我最开始的想法很简单门铃变压器输出8V交流电当按钮按下时这个8V电压会加载到门铃两端。我直接用电阻分压然后用一个光耦或者直接连接到ESP-01S的GPIO上通过检测高电平来判断门铃是否被按下。为此我设计了一个简单的分压电路用AMS1117将8V稳到3.3V给ESP供电然后用两个电阻把门铃线的电压分压到3.3V以下送入GPIO。结果失败了。当门铃按下时ESP-01S的蓝色运行指示灯根本没有亮程序也没启动。用万用表直流电压档去测量门铃两端的电压几乎读不到什么数值。问题根源我忽略了“交流电”这个关键特性。我用的是直流电压档去测量一个交流信号而且这个交流信号在未构成完整回路比如没有接门铃线圈这样的负载时表现可能很怪异。当我将万用表切换到交流电压档AC~V再去测量时清晰的8V AC读数出现了。ESP-01S的GPIO是直流输入引脚无法直接处理交流信号。更关键的是我最初的电路可能无法在交流正负半周都为后续电路提供正确的直流工作路径导致AMS1117无法正常启动。这个教训让我明白在处理任何来自市电或变压器的信号时第一件事就是用万用表的交流档和直流档分别测量明确信号性质。不能想当然。3.2 成功方案计划B整流、滤波与稳压既然信号是交流电那么要把它变成微控制器能识别的直流信号标准流程就是整流 - 滤波 - 稳压 - 检测。第一步桥式整流我用4个1N4001二极管搭建了一个经典的全桥整流电路。它的作用是将交流电的双向流动转变为单向的脉动直流电。无论门铃线A、B哪端是正经过整流桥后输出端Cathode端始终是正电压另一端Anode端是地GND。1N4001是常用的整流二极管耐压1000V电流1A完全满足这个小功率场景。第二步电容滤波整流后的电压是脉动的像一连串的山峰。直接给后面的稳压芯片和ESP模块供电会导致电压剧烈波动芯片无法工作。我在整流桥的输出端并联了一个1000uF的电解电容。这个电容就像一个“小水库”在电压峰值时储存电能在电压谷底时释放电能从而将脉动直流电平滑成一个电压值较高但仍有微小纹波的直流电。电容容量越大滤波效果越好电压越平滑。这里选择1000uF是基于门铃按下的瞬时性和ESP-01S的启动电流需求估算的。第三步电压稳压经过滤波后的直流电压峰值接近交流电压的峰值8V AC的峰值大约是8 * 1.414 ≈ 11.3V这个电压对于3.3V的ESP-01S来说太高了。我使用了AMS1117-3.3线性稳压器将电压降至稳定、干净的3.3V。AMS1117的输入电压最高可达15V完全满足要求。在其输入和输出引脚附近我分别并联了10uF的陶瓷电容或电解电容用于滤除高频噪声确保输出电压稳定。第四步信号检测与微控制器供电至此我们已经得到了一个稳定的3.3V直流电源VCC。这个VCC直接连接到ESP-01S的VCC和CH_PD使能引脚。同时我将整流滤波后、但未经稳压的“高压直流”约10V通过一个10kΩ的大电阻进行限流然后连接到ESP-01S的一个GPIO口例如GPIO2。这样当门铃按下整流桥有输出时这个GPIO会检测到一个高电平由于电阻分压和ESP内部保护二极管的作用实际进入引脚的电流和电压会被钳位在安全范围当门铃松开整流桥无输出该GPIO通过ESP内部或外部的一个下拉电阻如10kΩ到GND被拉低。ESP程序只需要检测这个GPIO的上升沿或高电平状态即可得知门铃被按下。实操心得AMS1117的散热与布局AMS1117是线性稳压效率不是100%。当输入输出电压差较大如10V到3.3V且输出电流较大ESP启动时约200mA时其功耗P (Vin - Vout) * Iout ≈ (10-3.3)*0.2 ≈ 1.34W。这个功耗会导致芯片发热。虽然门铃按下是瞬时行为通常1-2秒发热不持续但为了长期稳定建议给AMS1117芯片涂抹一点散热硅脂或者如果空间允许贴一个小散热片。在PCB布局上尽量让AMS1117的GND引脚通过较大的铜箔面积连接到主地线有助于散热。如果门铃被长时间卡住虽然罕见持续发热可能成为问题。可以在软件中加入保护逻辑或者考虑使用效率更高的DC-DC降压模块如MP1584但成本和电路复杂度会略有增加。4. 软件实现与配置全流程硬件电路搭建好后就需要让ESP-01S“活”起来实现检测和通信功能。软件部分主要包括三块ESP-01S传感器端的程序、ESP-now转MQTT网关的程序以及家庭自动化平台以OpenHAB为例的配置。4.1 ESP-01S传感器端编程Arduino IDE传感器端的代码核心逻辑是初始化 - 深度睡眠 - 被门铃信号唤醒 - 读取GPIO状态 - 通过ESP-now发送消息 - 重新进入深度睡眠。关键步骤与代码解析环境准备在Arduino IDE中安装ESP8266开发板支持。选择开发板为“Generic ESP8266 Module”并根据你的ESP-01S具体型号设置正确的Flash Size通常为1MB。引入库与定义#include ESP8266WiFi.h #include espnow.h // 接收端的MAC地址即ESP-now网关的MAC地址 uint8_t gatewayMac[] {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // 请替换为实际地址 // 定义门铃检测引脚 #define DOORBELL_PIN 2 // GPIO2 根据你的实际接线修改 #define DEBOUNCE_DELAY 50 // 防抖延时单位毫秒 // 定义数据结构用于发送消息 typedef struct message { char type[10]; // 例如 doorbell int state; // 例如 1 表示按下 } message; message myData;你需要将gatewayMac替换成你ESP-now网关的实际MAC地址。可以在网关的串口打印信息中找到。初始化与主循环逻辑void setup() { Serial.begin(115200); pinMode(DOORBELL_PIN, INPUT_PULLDOWN_16R); // 使用内部下拉电阻 // 初始化ESP-NOW WiFi.mode(WIFI_STA); if (esp_now_init() ! 0) { Serial.println(ESP-NOW初始化失败); return; } esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); esp_now_add_peer(gatewayMac, ESP_NOW_ROLE_SLAVE, 1, NULL, 0); // 检测门铃状态 bool doorbellPressed false; unsigned long pressTime millis(); // 简单的防抖逻辑 while ((millis() - pressTime) DEBOUNCE_DELAY) { if (digitalRead(DOORBELL_PIN) HIGH) { doorbellPressed true; pressTime millis(); // 重新计时确保稳定高电平 } } if (doorbellPressed) { strcpy(myData.type, doorbell); myData.state 1; esp_now_send(gatewayMac, (uint8_t *) myData, sizeof(myData)); Serial.println(门铃按下事件已发送); } else { Serial.println(未检测到有效门铃信号); } // 发送完成后进入深度睡眠 // 注意ESP-01S的GPIO16需要连接到RST引脚才能用深度睡眠唤醒 // 本例中我们依靠外部断电门铃松开来复位所以用延时后软件重启模拟 delay(1000); // 等待发送完成 ESP.restart(); // 重启模块等待下一次门铃按下供电 } void loop() { // setup()执行完会重启所以loop()永远跑不到 }关键点说明防抖机械按钮按下时会产生抖动导致短时间内多次触发。代码中通过延时检测来消除抖动确保只识别一次稳定的按下动作。供电与睡眠策略本例中ESP-01S的电源由门铃线路提供。门铃按下时通电程序运行、发送消息门铃松开时断电模块完全关闭。这是一种最极致的“省电”方式。如果你采用电池供电或其他常电方案则需要使用ESP.deepSleep()函数并配合定时器或外部中断如GPIO电平变化来唤醒。发送可靠性esp_now_send函数是异步的实际发送成功与否可以通过注册发送状态回调函数来确认。对于门铃这种关键事件建议添加上报确认机制如果发送失败可以尝试重发几次如果电源允许。4.2 ESP-now转MQTT网关实现网关通常使用功能更强的ESP32或NodeMCUESP8266开发板实现它需要同时运行ESP-now和MQTT客户端。核心逻辑网关启动后初始化Wi-Fi连接MQTT代理同时初始化ESP-now。当通过ESP-now收到传感器发来的消息后将其转换为对应的MQTT消息并发布出去。代码要点基于Arduino IDE使用PubSubClient MQTT库#include WiFi.h // ESP32用WiFi.h, ESP8266用ESP8266WiFi.h #include esp_now.h #include PubSubClient.h // Wi-Fi和MQTT配置 const char* ssid 你的Wi-Fi名称; const char* password 你的Wi-Fi密码; const char* mqtt_server 你的MQTT代理IP; // 例如 192.168.1.100 const int mqtt_port 1883; const char* mqtt_topic sensor/doorbell; // MQTT主题 WiFiClient espClient; PubSubClient client(espClient); // 定义与传感器端一致的数据结构 typedef struct message { char type[10]; int state; } message; message incomingData; // ESP-NOW接收回调函数 void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { memcpy(incomingData, incomingData, sizeof(incomingData)); Serial.print(收到来自传感器的数据: ); Serial.println(incomingData.type); if (strcmp(incomingData.type, doorbell) 0) { // 发布MQTT消息 String payload {\state\:\RING\}; // 构造JSON格式负载 if (client.publish(mqtt_topic, payload.c_str())) { Serial.println(MQTT消息发布成功); } else { Serial.println(MQTT消息发布失败); } } } void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(Wi-Fi连接成功); client.setServer(mqtt_server, mqtt_port); while (!client.connected()) { if (client.connect(ESPNowGateway)) { Serial.println(MQTT连接成功); } else { delay(2000); } } // 初始化ESP-NOW WiFi.mode(WIFI_STA); if (esp_now_init() ! ESP_OK) { Serial.println(ESP-NOW初始化失败); return; } esp_now_register_recv_cb(OnDataRecv); // 注册接收回调 Serial.println(ESP-NOW网关就绪); } void loop() { client.loop(); // 维持MQTT连接 // 主循环可以处理其他任务 }注意MAC地址管理在实际部署中你可能有多个ESP-now传感器。上述网关代码接收所有ESP-now消息。为了更严谨可以在回调函数OnDataRecv中判断发送者的MAC地址只处理特定设备的消息或者在消息结构体中加入设备ID字段进行过滤。4.3 家庭自动化平台集成以OpenHAB为例当MQTT消息成功发布后最后一步就是在家庭自动化平台中消费这个消息并触发自动化。这里以OpenHAB 3为例。安装MQTT绑定在OpenHAB的“设置”-“扩展”中搜索并安装“MQTT Binding 2.0”和“MQTT Action”扩展。配置MQTT桥接在“设置”-“系统设置”-“桥接”中添加一个MQTT桥接填写你的MQTT代理地址、端口、用户名密码如有。创建物品Item在“设置”-“模型”-“物品”中创建一个代表门铃的开关或字符串物品。// 在.items文件中添加 String Doorbell_State 门铃状态 { channelmqtt:topic:mybroker:doorbell } // 或者在UI界面创建选择MQTT通道主题填写sensor/doorbell值转换选择“JSONPATH”路径填写$.state创建规则Rule在“设置”-“自动化”-“规则”中创建一条新规则。触发条件选择“当物品状态更新”选择Doorbell_State物品状态变为“RING”。执行动作这里可以添加多个动作例如发送通知使用“通知”动作推送到手机APP。控制灯光调用你已有的灯光场景物品例如让客厅灯闪烁红色。这可能需要你预先在灯光绑定中定义好闪烁场景。记录时间将当前时间保存到另一个物品中例如Doorbell_LastRing。// 示例规则代码OpenHAB Rule DSL rule Doorbell Ringing when Item Doorbell_State received update RING then // 1. 发送通知 sendNotification(myphoneexample.com, 有人按门铃) // 2. 触发灯光场景假设你有一个可以执行场景的Switch Item FlashingRedScene.sendCommand(ON) // 3. 记录最后一次按铃时间 Doorbell_LastRing.postUpdate(new DateTimeType().toString) // 4. 可选5秒后重置门铃状态 createTimer(now.plusSeconds(5), [ | Doorbell_State.postUpdate(IDLE) ]) end创建界面UI在OpenHAB主界面或你自定义的仪表板上添加一个文本或图标部件绑定到Doorbell_State和Doorbell_LastRing物品这样就能实时看到门铃状态和最后一次响铃时间。5. 部署、调试与故障排查实录将代码烧录好电路焊接完毕就可以进入部署和调试阶段了。这个过程是问题的高发区下面是我总结的常见问题及解决方法。5.1 硬件组装与安全注意事项安全第一虽然门铃变压器通常是安全电压8-24V AC但在操作前务必关闭对应的空气开关或拔掉门铃变压器的电源。用电工胶带妥善包裹所有裸露的焊点和导线。先测试再集成不要急于把电路板塞进门铃盒。先用杜邦线连接好所有元件使用一个可调电源或电池模拟门铃电压如提供8-12V AC或整流后的DC进行测试。用万用表测量AMS1117的输出是否为稳定的3.3V用逻辑分析仪或另一个ESP的串口监听看门铃按下时GPIO信号和ESP-now发送是否正常。ESP-01S的GPIO用法ESP-01S的GPIO0和GPIO2在启动时需要特定的电平状态。GPIO0拉低会进入下载模式GPIO2内部有弱上拉。通常我们将检测信号接在GPIO2上并在程序内配置为INPUT_PULLDOWN_16R启用内部下拉电阻。确保你的电路不会在启动时意外拉低GPIO0。电源稳定性测试在门铃持续按下可以临时短接门铃按钮的10-15秒内用万用表监测3.3V电源线的电压。它应该保持稳定波动不超过±0.1V。如果电压跌落说明滤波电容容量不足或AMS1117带载能力不够可能是输入电压太低或散热问题。5.2 软件与通信调试技巧ESP-now配对失败症状传感器端发送成功但网关端收不到数据。排查确认MAC地址确保传感器代码中填写的网关MAC地址绝对正确。最好在网关的setup()里用Serial.println(WiFi.macAddress());打印出来然后硬编码到传感器端。检查Wi-Fi模式通信双方发送和接收的Wi-Fi模式必须设置为WIFI_STA站点模式不能是WIFI_AP或WIFI_AP_STA除非经过特殊配置。信道一致性ESP-now通信依赖于Wi-Fi信道。如果网关连接了家里的Wi-Fi它的信道就固定了。传感器在初始化ESP-now时最好能通过esp_now_set_peer_channel设置到与网关相同的信道或者将网关的Wi-Fi信道固定在某个值如信道1。距离与干扰ESP-now在空旷环境下传输距离可达百米但穿墙能力会衰减。确保设备之间没有过多的钢筋混凝土墙阻隔。2.4GHz频段干扰多可以尝试更换Wi-Fi信道。MQTT连接或发布失败症状网关串口打印Wi-Fi已连接但MQTT连接失败或连接成功但发布失败。排查网络可达性在网关代码中尝试ping一下MQTT服务器的IP地址确保网络层是通的。MQTT服务器配置检查Mosquitto等MQTT代理是否允许匿名连接对于内网测试可以开启或者用户名密码是否正确。检查防火墙是否开放了1883端口。客户端ID冲突确保你的网关client.connect时使用的客户端ID是唯一的如果和网络上已有的MQTT客户端ID重复会导致连接被拒绝。Payload格式使用MQTT客户端工具如MQTT.fx订阅sensor/doorbell主题查看网关发出的消息格式是否正确。OpenHAB等平台对JSON格式要求严格确保没有多余的逗号或格式错误。OpenHAB收不到消息或规则不触发症状MQTT工具能收到消息但OpenHAB中物品状态没更新。排查桥接状态在OpenHAB的“设置”-“系统设置”-“桥接”中查看MQTT桥接是否显示为“在线”。主题匹配检查物品配置的MQTT主题是否与网关发布的主题完全一致包括大小写。值转换如果网关发布的是JSON字符串{state:RING}那么OpenHAB物品的“值转换”需要选择“JSONPATH”并在“值转换模式”中填写正确的路径如$.state。如果网关发布的是纯字符串RING则不需要值转换。规则触发条件检查规则触发条件是“状态更新”还是“命令接收”。应该使用“当物品Doorbell_State收到更新RING时”。可以在规则中先添加一个简单的日志动作logInfo(Doorbell, Rule triggered!)来测试规则是否被执行。5.3 稳定性与优化建议增加看门狗与重连机制在网关代码的loop()函数中定期检查Wi-Fi和MQTT连接状态如果断开则尝试重连。可以使用client.connected()和WiFi.status()进行检查。消息确认与重发在传感器端实现ESP-now的发送状态回调。如果发送失败在电源允许的情况下比如电容还有余电延迟几毫秒后重发一次。电源优化如果使用电池供电需要彻底改造电源方案。使用大容量锂电池如18650配合高效的DC-DC降压模块并让ESP-01S绝大部分时间处于深度睡眠模式仅由门铃信号通过外部中断唤醒。这会复杂很多需要仔细计算功耗。状态防抖与误触发除了软件防抖可以在硬件上并联一个小电容如0.1uF在检测GPIO和地之间进行硬件滤波。在软件上可以增加“必须持续高电平超过一定时间如100ms才认定为有效按下”的逻辑。这个项目从构思到稳定运行我前后迭代了三个版本从最初简单的想法到被交流电“教育”再到成功集成到家庭自动化中每一步都充满了动手的乐趣和解决问题的成就感。看到家人不再因为听不到门铃而烦恼甚至可以在派对中通过炫酷的灯光变化得知有客来访这种感觉非常棒。物联网技术并非遥不可及它正是由这样一个个解决实际小问题的项目构成的。希望我的这份详细记录能帮助你成功打造属于自己的智能门铃通知系统。