💡 划重点
- 单套成本控制在 35 元以内,适合社区小车库批量部署。
- 采用 HC-SR04 超声波测距判断车位占用,ESP32 深度睡眠+定时唤醒,一节电池可撑数月。
- 通过 MQTT 将车位状态上报至本地服务器或云平台,手机/大屏实时查看。
- 车位上方安装,向下探测,LED 现场指示红/绿,降低寻找成本。
需求洞察
社区和小型车库的停车矛盾集中在“找位难”和“占位纠纷”。车主绕圈找空位,物业无法实时掌握车位使用率;固定车位被临时占用时,管理员只能人工巡逻。传统地磁或摄像头方案成本高、布线复杂,难以在每个车位复制。本方案针对单个车位设计,目标用户是物业、车位业主和临时访客。真实痛点是:缺乏低成本的占用状态感知手段,信息不透明导致时间浪费和资源错配。值得做的原因有三:一是 ESP32 与超声模块价格极低,35 元内可落地;二是低功耗定时唤醒让无线部署成为可能,免去穿墙打孔;三是 MQTT 协议轻量,容易集成到现有物联网平台。一个车位一个节点,积少成多,就能形成车库级车位引导系统。
方案设计
感知层:HC-SR04 超声波模块安装于车位正上方,向下发射声波,根据回波时间计算与车辆/地面的距离。设定阈值(如 1.2 米),小于阈值判定为“占用”,大于阈值判定为“空闲”。为避免地面杂物误判,可加入多次采样取中值。
控制层:ESP32 作为主控,负责触发超声、读取回波、逻辑判断、控制 LED,并管理 WiFi 与 MQTT 连接。利用 ESP32 的深度睡眠功能,RTC 定时器每 5 分钟唤醒一次,完成测量与上报后立即休眠,平均电流可降至微安级。
执行层:板载 LED(GPIO2)作为现场指示。空闲时绿灯闪烁,占用时红灯常亮,方便车主肉眼识别。若需更醒目,可外接 WS2812 灯珠,但成本略增。
日志/联网层:ESP32 连接社区 WiFi,通过 MQTT 发布主题 parking/spot1/status,载荷为 0(空闲)或 1(占用)。同时订阅 parking/spot1/cmd 用于远程校准阈值。本地可搭配 Mosquitto 服务器和 Node-RED 仪表盘,记录历史占用率,辅助车位调度。
物料清单
| 物料 | 数量 | 用途 | 估算单价 | 合计 |
|---|---|---|---|---|
| ESP32-C3 迷你开发板 | 1 | 主控、WiFi、深度睡眠 | 15.0 元 | 15.0 元 |
| HC-SR04 超声波模块 | 1 | 距离感知 | 4.0 元 | 4.0 元 |
| LED(红/绿双色) | 1 | 现场状态指示 | 0.3 元 | 0.3 元 |
| 电阻 220Ω | 1 | LED 限流 | 0.1 元 | 0.1 元 |
| 电阻 1kΩ、2kΩ | 各1 | Echo 分压(5V→3.3V) | 0.2 元 | 0.2 元 |
| 杜邦线/排针 | 若干 | 连接 | 1.5 元 | 1.5 元 |
| 防水外壳/扎带 | 1 | 保护与固定 | 3.0 元 | 3.0 元 |
| 合计 | 24.1 元 |
预留 10 元余量用于 PCB 或电池座,总成本仍低于 35 元。
接线与结构
| ESP32 引脚 | 连接至 | 说明 |
|---|---|---|
| GPIO5 | HC-SR04 Trig | 输出触发脉冲,3.3V 电平可被模块识别 |
| GPIO18 | HC-SR04 Echo 经分压 | Echo 输出 5V,经 1kΩ 与 2kΩ 分压至 3.3V 再接入 |
| GPIO2 | LED 阳极(串联 220Ω) | 高电平点亮,可 PWM 调光 |
| GND | HC-SR04 GND、LED 阴极 | 共地 |
| 5V | HC-SR04 VCC | 从开发板 5V 引脚取电 |
微调说明:原建议 Echo 直连 GPIO18,但 HC-SR04 的 Echo 为 5V 输出,长期直连可能损伤 ESP32。增加两个电阻分压是必要保护,成本仅 0.2 元。Trig 仍用 GPIO5,LED 用 GPIO2。结构上,将超声波模块朝下固定在车位上方 2.2~2.5 米处,避免车辆顶部最高点误触发;LED 装在车位前方立柱,便于观察。
核心代码
以下为 Arduino 框架骨架,使用 PubSubClient 与 WiFi,实现定时唤醒、测距、MQTT 上报。
#include <WiFi.h>
#include <PubSubClient.h>
#define TRIG_PIN 5
#define ECHO_PIN 18
#define LED_PIN 2
#define THRESHOLD_CM 120
#define SLEEP_SEC 300
const char* ssid = "社区WiFi";
const char* password = "12345678";
const char* mqtt_server = "192.168.1.100";
WiFiClient espClient;
float readDistance() {
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
return duration * 0.034 / 2;
}
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
// 多次采样取中值
float d1 = readDistance(); delay(50);
float d2 = readDistance(); delay(50);
float d3 = readDistance();
float dist = (d1 + d2 + d3) / 3.0;
bool occupied = (dist < THRESHOLD_CM);
digitalWrite(LED_PIN, occupied ? HIGH : LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
if (client.connect("parking_spot1")) {
client.publish("parking/spot1/status", occupied ? "1" : "0");
client.disconnect();
}
WiFi.disconnect(true);
esp_sleep_enable_timer_wakeup(SLEEP_SEC * 1000000ULL);
esp_deep_sleep_start();
}
void loop() {}
代码逻辑:唤醒后取三次距离中值,判断占用,点亮 LED,连接 WiFi 发布 MQTT,随后深度睡眠。注意实际部署需处理 WiFi 重连超时和 MQTT 遗嘱消息。
调试步骤
- 通电检查:用 USB 供电,串口监视器观察启动日志,确认无重启循环。
- 超声测距校准:手放在模块下方不同距离,串口打印距离值,调整
THRESHOLD_CM使空位/占用判断准确。 - LED 验证:遮挡超声模拟占用,LED 应亮;移开应灭。
- 网络测试:确保 WiFi 信号强度足够,用 MQTT 客户端订阅主题,查看上报数据。
- 功耗测量:用万用表串联测深度睡眠电流,正常应低于 1mA;若偏高,检查外设供电和上拉电阻。
- 现场安装:固定外壳,调整角度避免声波反射干扰,测试连续 24 小时稳定性。