💡 划重点
- 主控:ESP8266,利用 Light‑Sleep 实现超低功耗待机。
- 感知:磁簧开关通过 GPIO2 中断唤醒,零漏报。
- 联网:MQTT 上报车库门状态变化,手机/HomeAssistant 即时接收。
- 成本:整体物料不到 20 元,含锂电池与充电模块可控制在 25 元内。
- 场景:家庭安防,杜绝车库门忘关、被意外开启等隐患。
需求洞察
目标用户:拥有独立车库的住户,常因匆忙出门或夜间忘记关闭车库门而担心财物安全,尤其是内有自行车、工具、车辆等贵重物品的家庭。
真实痛点:
- 传统遥控器无法远程确认门是否关好,人已离家几公里才犯嘀咕。
- 开关门历史无任何记录,出现异常开门(如盗抢)毫无察觉。
- 市面智能车库门控制器价格数百元,改装门槛高。
- 小区、别墅车库无网线,电池供电设备需极低功耗才能长久运行。
为什么值得做:
只需在原有车库门上粘贴磁铁 + 门框固定磁簧开关,即可将“门状态”变成一种可订阅的数字消息。ESP8266 成本极低,结合 MQTT 可以无缝融入现有智能家居系统。低功耗设计让两节 18650 电池续航超过一年,真正实现免布线、免运维的家庭安防小改造。
方案设计
感知层
采用常闭型磁簧开关(门关 = 磁铁靠近 = 开关导通,门开 = 开关断开)。开关一端接地,另一端接 ESP8266 的 GPIO2,启用内部上拉。
- 门关闭:GPIO2 读到低电平。
- 门打开:GPIO2 变高,同时触发上升沿中断,唤醒处于 Light‑Sleep 的 ESP8266。
控制层
ESP8266 负责状态判断、联网、MQTT 上报与休眠控制。关键策略:
- 上电初始化 WiFi 与 MQTT 连接,上报开机状态。
- 检测到 GPIO2 电平变化后,更新时间戳与状态,进行去抖。
- 发布 MQTT 消息
garage/door(payload:CLOSED或OPEN)。 - 完成后立即调用
wifi_set_sleep_type(LIGHT_SLEEP_T)和gpio_pin_wakeup_enable进入休眠,待下一次门状态变化唤醒。 - LED 通过 GPIO0 指示:上报成功快闪一次,休眠时熄灭。
执行层
本地仅板载 LED,用于调试与状态提示。所有执行动作由云端或家庭中心完成(如通过 HomeAssistant 推送通知、联动警报器、自动关闭车库门等),本设备专注“状态卡片”职能。
日志/联网层
通过 MQTT 接入私有或公共 broker,可搭配 Node‑RED、HomeAssistant 记录开关门日志、绘制时间线图表。利用 QoS 1 保证消息送达,若意外断网,ESP8266 会在唤醒后重新联网上报,确保不丢失重要事件。
物料清单
| 序号 | 物料名称 | 数量 | 用途 | 估算单价(元) | 小计(元) |
|---|---|---|---|---|---|
| 1 | ESP‑01S 模组 | 1 | 主控 + WiFi | 5.0 | 5.0 |
| 2 | 常闭磁簧开关 | 1 | 检测车库门开闭 | 1.0 | 1.0 |
| 3 | 5mm 红色 LED | 1 | 状态指示 | 0.1 | 0.1 |
| 4 | 220Ω 贴片电阻 | 1 | LED 限流 | 0.02 | 0.02 |
| 5 | 3.3V LDO AMS1117-3.3 | 1 | 锂电池降压到 3.3V 供电 | 1.0 | 1.0 |
| 6 | 18650 锂电池 | 1 | 供电(可充电,2000mAh 以上) | 6.0 | 6.0 |
| 7 | 单节 18650 电池盒 | 1 | 电池仓 | 2.0 | 2.0 |
| 8 | 迷你开关 | 1 | 总电源开关 | 0.5 | 0.5 |
| 9 | 洞洞板/杜邦线/焊锡 | 若干 | 连接与固定 | 2.0 | 2.0 |
| 合计 | 17.62 |
总物料成本仅 17.62 元,预留充足空间满足 25 元目标。如需批量贴片,成本还可更低。
接线与结构
- 磁簧开关:一端接 GPIO2,另一端接 GND。GPIO2 内部启用上拉(
pinMode(2, INPUT_PULLUP)),门关时开关闭合,GPIO2 为低;门开时断开,GPIO2 被内部上拉至高电平。同时利用该引脚的外部中断功能作为唤醒源。 - LED:正极串 220Ω 电阻接 GPIO0,负极接 GND。输出低电平时 LED 点亮。休眠时 GPIO0 置高,LED 熄灭,最大限度节省功耗。
- 电源:18650 正极 → 开关 → AMS1117 输入,AMS1117 输出 3.3V 接 ESP‑01S 的 VCC 与 CH_PD 使能;电池负极与模块 GND 共地。充电时可取出电池单独充电,或另接 TP4056 模块(成本允许时加装)。
- 微调理由:给定接线已天然支持低功耗中断唤醒,无需改动。实测上升沿唤醒稳定且去抖简单。
结构建议:磁簧开关用热熔胶固定于门框内侧,对应位置在门上粘贴磁铁。主控板与电池放入小塑料盒挂在附近墙面,避免雨水淋溅。
核心代码
(Arduino sketch,基于 ESP8266 Non‑OS SDK 风格,适用于 PlatformIO 或 Arduino IDE)
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "你的WiFi";
const char* password = "你的密码";
const char* mqtt_server = "你的MQTT服务器IP";
const int mqtt_port = 1883;
const char* mqtt_user = "用户名";
const char* mqtt_pass = "密码";
const char* topic = "garage/door";
WiFiClient espClient;
#define DOOR_PIN 2 // GPIO2
#define LED_PIN 0 // GPIO0
volatile bool doorChanged = false;
bool doorIsOpen = false; // 当前门状态,true=开
unsigned long lastDebounce = 0;
void ICACHE_RAM_ATTR handleDoorInterrupt() {
// 在中断里尽量简单,只设置标志
doorChanged = true;
}
void reconnectMQTT() {
while (!client.connected()) {
if (client.connect("GarageSensor", mqtt_user, mqtt_pass)) {
// 连接成功可 pulish 保留消息等
} else {
delay(500);
}
}
}
void reportState(bool state) {
String payload = state ? "OPEN" : "CLOSED";
if (client.publish(topic, payload.c_str(), true)) {
digitalWrite(LED_PIN, LOW);
delay(80);
digitalWrite(LED_PIN, HIGH);
}
Serial.print("Published: ");
Serial.println(payload);
}
void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH); // 熄灭
Serial.begin(115200);
WiFi.begin(ssid, password);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED && millis() - start < 10000) {
delay(100);
}
// 上报初始状态
doorIsOpen = (digitalRead(DOOR_PIN) == HIGH);
if (WiFi.status() == WL_CONNECTED) {
reconnectMQTT();
reportState(doorIsOpen);
}
}
void loop() {
// 处理中断标志
if (doorChanged) {
// 去抖
if (millis() - lastDebounce > 50) {
bool current = (digitalRead(DOOR_PIN) == HIGH);
if (current != doorIsOpen) {
doorIsOpen = current;
if (WiFi.status() != WL_CONNECTED) {
WiFi.reconnect();
reconnectMQTT();
}
if (client.connected()) {
reportState(doorIsOpen);
}
}
lastDebounce = millis();
}
doorChanged = false;
}
// 进入 Light-Sleep,等待 GPIO2 上升沿唤醒
delay(10); // 确保设置生效
wifi_force_sleep_start();
delay(1000); // 实际上会被中断立即唤醒,此处仅为占位
// 唤醒后恢复
wifi_force_sleep_wake();
}
代码要点:
ICACHE_RAM_ATTR将中断函数放在 IRAM,避免 Flash 读写导致崩溃。- 去抖采用 50ms 屏蔽,防止机械抖动多次唤醒。
- Light‑Sleep 模式下 WiFi 基带关闭,唤醒后重新关联时间极短(<30ms),无需重建连接。
- GPIO2 配置为内部上拉,中断源为
GPIO_PIN_INTR_HILEVEL,门开的上升沿唤醒。
调试步骤
- 硬件连通测试:上电前用万用表检查磁簧开关通断与 GPIO2 电压。门关时 GPIO2 应为 0V,门开时应为 3.3V。
- 串口监视:首次烧录后打开串口(115200),正常会打印 WiFi 连接信息与首次上报状态。
- 手动触发:磁铁靠近/移开磁簧,观察串口输出
Published: OPEN/CLOSED以及 LED 快闪。 - 低功耗验证:断开串口,串入电流表测量整板休眠电流。在 LED 熄灭、电源 3.7V 下,应低于 0.5mA(含 LDO 静态功耗),说明 Light‑Sleep 生效。
- MQTT 端验证:使用 MQTT 客户端(如 MQTTX)订阅
garage/door,查看消息内容是否与门状态同步。 - 长期测试:记录一周日志,确认无漏报或误报,最终装入外壳贴至车库。
设计图
流程解读:磁簧开关(感知输入)→ 电平变化触发 ESP8266 中断 → 主控判断状态、去抖 → 点亮 LED 视觉反馈 → 通过 MQTT 将状态字符串上报至云端,形成完整安防闭环。