💡 划重点
- 用 HC-SR04 超声测距判断车位有无车辆,成本低、安装简单。
- ESP32 负责定时唤醒、阈值判断、Wi-Fi 联网与 MQTT 上报。
- LED 就地指示占用状态,方便现场巡检。
- 深度睡眠定时唤醒,兼顾实时性与功耗,适合社区小车库长期运行。
- 整机物料控制在 35 元内,可复制性强。
需求洞察
目标用户是社区物业、小车库管理员和私家车位业主。真实痛点有三:一是人工巡查效率低,车位被占、空置状态无法实时掌握;二是地磁、摄像头方案成本高,布线复杂,老旧车库难以改造;三是车主找车位绕行,物业统计车位利用率缺少数据。为什么值得做?因为一个车位监测节点不到 35 元,用电池或 USB 供电即可部署,通过 MQTT 把状态汇总到本地服务器或 Home Assistant,就能实现空位引导、占用告警和利用率统计。相比动辄上百元的地磁方案,超声方案在室内小车库中精度足够,且不涉及隐私图像,更容易落地。
方案设计
感知层使用 HC-SR04 超声波模块,安装在车位正上方或侧方,向下发射声波,根据回波时间计算到车顶或地面的距离。控制层由 ESP32 承担,定时从深度睡眠中唤醒,读取距离并和阈值比较。执行层用一颗 LED 指示:红灯表示占用,绿灯表示空闲,也可用闪烁表示传感器异常。日志/联网层通过 ESP32 内置 Wi-Fi 连接 MQTT 代理,把 occupied 或 free 发布到指定主题,同时可附带距离、电量、时间戳。为了降低功耗,节点大部分时间处于深度睡眠,每 60 秒唤醒一次,测量并上报后立即休眠。若车库有常电,可改为 10 秒上报;若用电池,可延长到 5 分钟。
物料清单
| 物料 | 数量 | 用途 | 估算单价 | 合计 |
|---|---|---|---|---|
| ESP32 开发板 | 1 | 主控、Wi-Fi、深度睡眠 | 18 元 | 18 元 |
| HC-SR04 超声模块 | 1 | 车位距离感知 | 4 元 | 4 元 |
| LED 红绿双色 | 1 | 占用/空闲指示 | 0.2 元 | 0.2 元 |
| 220Ω 电阻 | 1 | LED 限流 | 0.1 元 | 0.1 元 |
| 1kΩ 电阻 | 1 | Echo 分压上臂 | 0.1 元 | 0.1 元 |
| 2kΩ 电阻 | 1 | Echo 分压下臂 | 0.1 元 | 0.1 元 |
| 杜邦线/面包板 | 1 套 | 连接与固定 | 3 元 | 3 元 |
| 5V 电源适配器 | 1 | 供电 | 5 元 | 5 元 |
| 合计 | 30.5 元 |
若已有 USB 电源和线材,成本可降至 25 元左右,满足 35 元内目标。
接线与结构
HC-SR04 的 VCC 接 5V,GND 接 ESP32 的 GND。Trig 接 GPIO5,Echo 接 GPIO18。注意 Echo 输出为 5V 电平,ESP32 输入不耐 5V,因此用 1kΩ 和 2kΩ 电阻分压:Echo 接 1kΩ 到 GPIO18,GPIO18 再接 2kΩ 到 GND,得到约 3.3V。LED 正极经 220Ω 接 GPIO2,负极接 GND。结构上,超声模块朝下,避开金属遮挡,LED 装在车位入口可见处。若现场需要更远探测,可把阈值调到 80 厘米;若车顶较高,可把模块装在车位后上方,减少地面反射干扰。
核心代码
以下为 Arduino 骨架,可编译后烧录到 ESP32。
#include <WiFi.h>
#include <PubSubClient.h>
#define TRIG 5
#define ECHO 18
#define LED 2
#define THRESHOLD 50
#define SLEEP_SEC 60
const char* ssid = "your_ssid";
const char* password = "your_password";
const char* mqttServer = "broker.emqx.io";
const int mqttPort = 1883;
const char* topic = "parking/spot1";
WiFiClient espClient;
float readDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH, 30000);
if (duration == 0) return -1;
return duration * 0.034 / 2;
}
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(LED, OUTPUT);
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
while (!client.connected()) {
delay(500);
}
float dist = readDistance();
bool occupied = (dist > 0 && dist < THRESHOLD);
digitalWrite(LED, occupied ? HIGH : LOW);
client.publish(topic, occupied ? "occupied" : "free");
Serial.printf("dist=%.1f occupied=%d\n", dist, occupied);
client.disconnect();
WiFi.disconnect(true);
esp_sleep_enable_timer_wakeup((uint64_t)SLEEP_SEC * 1000000ULL);
esp_deep_sleep_start();
}
void loop() {}
调试步骤
- 先只烧录串口测距程序,打开串口监视器,观察静止地面和放置纸箱后的距离值。
- 根据实测调整
THRESHOLD,建议取“地面距离”和“车顶距离”的中间值,并留 10 厘米余量。 - 接入 Wi-Fi 和 MQTT,用 MQTT 客户端订阅
parking/spot1,确认能收到occupied和free。 - 测低功耗:用万用表或 USB 电流表观察深度睡眠电流,正常应在微安级;若偏高,检查 LED 和超声模块是否常供电。
- 现场安装:固定超声模块角度,避免震动,LED 朝向通道,连续观察 24 小时误报情况。