💡 划重点

  • 主控芯片:ESP32,支持 Wi-Fi 与深度睡眠,是低成本低功耗联网方案的理想选择。
  • 核心传感:HC-SR04 超声波模块,通过回波时间计算车位占用状态,精度高、价格低。
  • 联网协议:MQTT 轻量级发布/订阅,适合窄带宽、不稳定网络环境下的状态上报。
  • 功耗策略:定时唤醒 + 单次测量 + 立即休眠,平均功耗可控制在毫瓦级。
  • 目标成本:整机物料不超过 35 元,适合社区小车库批量部署。
  • GPIO 分配:Trig=5、Echo=18、LED=2,仅需三根信号线,接线简单可靠。

需求洞察

目标用户是社区小车库的管理员、物业运维人员以及拥有固定车位的业主。真实痛点在于:车库车位数量少但车辆进出频繁,经常出现外来车辆占用私人车位、车主找不到空位而堵塞通道的情况。人工巡查效率低,安装地磁或摄像头方案成本高、布线麻烦。因此,一个成本极低、安装简单、能实时上报车位状态的设备,能有效减少纠纷、提升车位周转率。本项目核心价值在于用 35 元以内成本,实现可与现有智能家居或物业系统联动的车位占用感知节点,并且电池供电可长期运行,不需要频繁维护。

方案设计

感知层:HC-SR04 超声波传感器每隔 N 秒被唤醒一次,发射超声脉冲并测量回波时间,转换为距离值。当距离小于设定阈值(如 50cm)时,判定为有车占用;否则为空闲。

控制层:ESP32 作为主控,负责定时从深度睡眠中唤醒,驱动超声波测距、处理数据、控制 LED 指示、建立 Wi-Fi 连接并发布 MQTT 消息,完成后立即重新进入睡眠。

执行层:板载 LED 作为本地状态指示(亮起=占用,熄灭=空闲),同时可通过 MQTT 消息触发远程告警或联动道闸、指示灯牌。

日志/联网层:通过 MQTT 将车位状态发布到本地 Broker(如 Mosquitto),或云端 Broker(如 EMQX、阿里云 IoT)。消息主题可设置为 parking/spot/status,消息内容为 JSON 格式,包含车位 ID、状态、时间戳。Broker 端可订阅该主题进行数据存储、可视化或推送通知。

物料清单

物料名称 数量 用途 估算单价(元) 小计(元)
ESP32 DevKit 开发板 1 主控与联网 15.00 15.00
HC-SR04 超声波模块 1 距离检测 3.00 3.00
5mm LED(红色) 1 状态指示 0.10 0.10
220Ω 电阻 1 LED 限流 0.05 0.05
3.7V 18650 锂电池 1 供电(可充电) 8.00 8.00
18650 电池座 1 电池固定 0.50 0.50
AMS1117 3.3V 稳压模块 1 电压稳定 0.80 0.80
面包板 + 杜邦线 1套 电路连接 2.50 2.50
亚克力或塑料外壳(自制) 1 保护结构 3.00 3.00
合计 32.95

物料总成本约 33 元,控制在 35 元以内,如需进一步降低成本可去掉外壳或使用更小的 ESP32 模组。

接线与结构

结构上建议将超声波模块朝向车位正上方或斜前方,距离地面高度约 1.2 至 1.5 米,避免误测到地面或其他障碍物。LED 可外露在外壳表面,便于远距离观察状态。整体采用垂直壁挂或天花吊装方式,减少人为触碰。接线说明:选用 GPIO 5 和 GPIO 18 是因为它们均为 ESP32 常规 IO,且不与 Flash 通信引脚冲突,方便程序烧录与调试。GPIO 2 板载 LED 也在同一引脚,但板载 LED 焊接在开发板上,若外接 LED 需要拔掉板载跳线或直接使用其他空闲 GPIO 以避免冲突,本方案中 GPIO 2 默认外接 LED 使用。

核心代码


#include <WiFi.h>
#include <PubSubClient.h>
#include <driver/rtc_io.h>

#define TRIG_PIN 5
#define ECHO_PIN 18
#define LED_PIN 2
#define DEEP_SLEEP_SEC 15

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const char* mqttServer = "192.168.1.100";
const int mqttPort = 1883;
const char* mqttTopic = "parking/spot/status";

WiFiClient espClient;

float getDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  long duration = pulseIn(ECHO_PIN, HIGH);
  return duration * 0.034 / 2;
}

void connectWiFi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
}

void connectMQTT() {
  while (!client.connected()) {
    if (client.connect("ESP32_Parking")) {
    }
    delay(50);
  }
}

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

  float dist = getDistance();
  bool occupied = (dist < 50);

  digitalWrite(LED_PIN, occupied ? HIGH : LOW);

  rtc_gpio_hold_enable(GPIO_NUM_2);  // 保持 LED 状态在睡眠中不丢失

  connectWiFi();
  connectMQTT();

  String payload = String("{\"occupied\":") + (occupied ? "true" : "false") + ",\"dist_cm\":" + String((int)dist) + "}";
  delay(50);
  client.disconnect();
  WiFi.disconnect();

  esp_sleep_enable_timer_wakeup(DEEP_SLEEP_SEC * 1000000ULL);
  esp_deep_sleep_start();
}

void loop() {
  // 程序不会运行到这里
}

代码说明:程序启动后立即进行超声波测距,根据距离设置 LED 状态,然后连接 Wi-Fi 和 MQTT 发布消息,最后进入深度睡眠。每次唤醒周期 15 秒,调整 DEEP_SLEEP_SEC 可改变功耗与实时性平衡。

调试步骤

  1. 基础通信验证:先用 Arduino 串口监视器打印距离值,确认 HC-SR04 正常,避免接线错误。用手遮挡传感器,距离应明显减小。
  2. LED 逻辑验证:设置临时阈值,遮挡时 LED 亮起,移除后熄灭。确认 GPIO 2 输出正常,若板载 LED 与外部 LED 同时亮,则说明状态逻辑正确。
  3. MQTT 连接测试:使用 MQTT.fx 或 mosquitto_sub 订阅主题 parking/spot/status,观察是否收到 JSON 消息。若连接失败,检查 SSID、密码、服务器 IP 是否可达。
  4. 功耗测量:在电池回路串联万用表,测量工作状态(约 80-120mA)和睡眠状态(约 10-20uA),确认深度睡眠生效。若电流偏高,检查是否有外设未断电。
  5. 部署实测:将设备安装在车位上方,模拟车辆进出,连续运行 24 小时记录 MQTT 消息准确率,调整阈值或测量角度。
  6. 稳定性优化:如果 Wi-Fi 连接时间过长导致单次唤醒功耗增大,可减少上报频率或将 DEEP_SLEEP_SEC 增加到 30 秒。

设计图

停车位占用监测结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报