💡 划重点

  • 今日目标:在 25 元预算内,制作一块可贴在车库内墙上的「车库门远程状态卡片」,通过 MQTT 将门状态推送到手机。
  • 主控选型:ESP8266(NodeMCU / D1 Mini 皆可),成本低、自带 Wi-Fi,适合家庭局域网场景。
  • 传感原理:磁簧开关固定在门框,磁铁贴在活动门板,门开/合对应开关通断。
  • 低耗核心:GPIO2 中断唤醒 + 深度睡眠(Deep Sleep),常态工作电流可降至 uA 级,两节 5 号电池可续航数月。
  • 网络协议:MQTT QoS 0 即可(家庭局域网状态提示,丢包影响极小),Broker 可用部署在树莓派或旧路由器上的 Mosquitto。
  • 成本控制重点:ESP8266 探针板用裸片模组(ESP-12F)而非完整开发板,可将核心物料压在 25 元内。若选用现成 D1 Mini 开发板(约 10 元),总价也仍在 25 元内。

需求洞察

目标用户:家里有独立车库、经常出门后不确定「到底锁了没」的粗心健忘人群,以及有老人小孩的家庭(担心门没关进猫狗或小孩跑出去)。

真实痛点:

为什么值得做:

方案设计

整体逻辑为「磁簧感知开合 → 主控中断唤醒 → LED 本地反馈 → MQTT 上报 → 休眠等待下事件」。

感知层(信息采集)

控制层(状态解析与去抖)

执行层(本地反馈)

日志/联网层

物料清单

物料 数量 用途 估算单价(元)
ESP-12F 模组 / D1 Mini 开发板 1 主控与 Wi-Fi 8.0(模组)或 10.0(开发板)
磁簧开关(常开型,玻璃管或塑封) 1 门状态感知 1.5
小号钕磁铁(直径10mm) 1 与磁簧配合触发 1.0
5mm 红色 LED 1 状态指示 0.1
1kΩ 电阻 2 LED 限流与保护 0.1
4.7kΩ 上拉电阻 1 GPIO2 中断输入稳定 0.05
1N5819 肖特基二极管 1 电池防反接 0.2
3.7V 锂电池(或 2xAA 电池盒) 1 供电 5.0(锂电池)或 1.0(电池盒)
PCB 洞洞板 / 免焊面包板 1 固定元件 2.0
杜邦线或细导线 若干 接线 1.5
塑料外壳/热缩管 1 封装绝缘 2.0
3D 打印门夹支架(可选) 1 固定磁簧与磁铁(可不做,用胶固定) 0(或 3.0)
合计 — — 约 21.45 元(不含 3D 打印),满足 ≤25 元

接线与结构

GPIO 分配如下(基于 ESP8266 D1 Mini 引脚定义):

结构建议:

说明:原任务建议 GPIO0 连接 LED、GPIO2 连接磁簧,未改动。仅在供电上增加了锂电池方案,替代直连 USB,以配合休眠低功耗目标。

核心代码

使用 Arduino 框架,平台选择 esp8266 by ESP8266 Community,可编译运行。


#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>

// 停库门状态卡片 v1.0 —— Low-power MQTT Sensor
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const char* mqtt_server = "192.168.x.x";
const int mqtt_port = 1883;

const int REED_PIN = 2;   // GPIO2 -> D4
const int LED_PIN  = 0;   // GPIO0 -> D3

bool last_state;
bool current_state;

WiFiClient espClient;

// 简单防抖读取
bool readReedDebounced() {
  int counter = 0;
  for (int i=0; i<5; i++) {
    if (digitalRead(REED_PIN) == LOW) counter++;
    delay(2);
  }
  return (counter >= 3);  // true表示门关(磁簧闭合=接地=LOW)
}

void publishState(bool doorClosed) {
  if (!client.connected()) {
    // 尝试快速连接,若失败则直接休眠,不反复重试
    WiFi.begin(ssid, password);
    int attempts = 0;
    while (WiFi.status() != WL_CONNECTED && attempts < 20) {
      delay(100);
      attempts++;
    }
    if (WiFi.status() != WL_CONNECTED) {
      ESP.deepSleep(0); // 无法联网则不打扰,等下个事件唤醒再试
      delay(100);
    }
    client.connect("garage_card");
  }
  if (client.connected()) {
    if (doorClosed) {
      client.publish("home/garage/door/state", "{\"state\":\"closed\"}");
    } else {
      client.publish("home/garage/door/state", "{\"state\":\"open\"}");
    }
    client.disconnect();
  }
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  // 初次上电记录初始状态(首次建议不要直接休眠,稍亮LED提示)
  last_state = readReedDebounced();
  digitalWrite(LED_PIN, !last_state); // 门开亮灯,门关灭灯
  delay(100);
  publishState(last_state);

  // 第一次刚上电,也同步进休眠等待外部事件
  // 设置GPIO2为下降沿和上升沿都唤醒
  // Deep sleep等待外部中断唤醒:时间为0表示由外部事件唤醒
  ESP.deepSleep(0);
}

void loop() {
  // 在中断唤醒后loop会执行,但这里不会再走到,因为setup末尾直接sleep
  // 为保证极端情况的兼容性,也加入处理
  current_state = readReedDebounced();
  if (current_state != last_state) {
    last_state = current_state;
    digitalWrite(LED_PIN, !last_state);
    publishState(last_state);
  }
  // 处理完成立刻再睡
  ESP.deepSleep(0);
}

编译时需在 Board 选项中选择 LOLIN(WEMOS) D1 mini Lite 并禁用 VTABLES_IN_FLASH(无必要,保持默认即可)。

调试步骤

  1. 静态输入测试:先不焊磁簧,用杜邦线直接短接 GPIO2 到 GND,观察 LED 是否变化(GPIO0输出高亮 / 低灭)。若不能触发,检查上拉是否失效或引脚短路。
  2. 串口调试(此方案为了省电不加串口台打印,可临时加):可在 setup 中加 2 行 Serial.begin(74880) 和 Serial.println 观察状态解析是否准确。
  3. MQTT 连通性测试:电脑上用 mosquitto_sub -h 192.168.x.x -t 'home/garage/door/state' 订阅,再用磁铁靠近或移开磁簧,几秒内应能看到 {"state":"..."} 消息,且两次消息之间不会出现重复发送。
  4. 防抖验证:快速来回摆动磁簧(每秒两三次),看 Topic 是否出现撕裂不清的乱序消息。若出现多次抖动上报,可将防抖循环中的延时调大至 5ms×5 次或改用软件去抖算法。
  5. 功耗实测:万用表电流档串入电池正极,休眠时电流应低于 20uA(排除 LED 电流);触发后瞬时峰值约 150~300mA(Wi-Fi 发射),持续时间不超过 1s。若休眠电流过大,说明 GPIO 上拉漏电或 LDO 空载耗材。
  6. 安装距离测试:装到车库后(磁铁离磁簧约 10mm),反复开关门 10 次,确认每次状态变化均能远程收到,中间不能有超过 2 次漏报(低概率可容忍,可通过保证对齐调整)。
  7. 长时间稳定性:连续跑 48 小时,抽查 Broker 日志看异常掉线或重复连接情况,若有频繁 reconnect,需检查 Wi-Fi 信号强度(ESP 天线朝向和金属门框干扰)。

设计图

车库门远程状态卡片结构flow
1
感知输入
→
2
控制处理
→
3
执行反馈
→
4
数据上报

图中数据流方向为:感知输入(磁簧开合)→ 控制处理(ESP8266 中断唤醒 → 去抖 → 状态变判定)→ 执行反馈(LED 点亮/熄灭) + 数据上报(MQTT Topic 推送至手机/Home Assistant)。休眠模式从控制处理节点回流指向上电启动与低功耗调度,形成事件驱动的节能循环。