——基于 ESP32 和超声波传感器的低成本社区车库方案
💡 划重点
- 利用 HC-SR04 超声波模块实时判断车位是否有车。
- ESP32 通过 MQTT 上报占用状态,支持 Home Assistant、社区大屏等集成。
- 深度睡眠 + 定时唤醒,降低功耗,适合 USB 供电或电池场景。
- 硬件总成本控制在 35 元以内,单节点部署简单。
- 提供完整 Arduino 骨架代码、接线指导和调测流程。
需求洞察
目标用户:社区物业、小型车队车库、共享办公停车场管理员,以及希望 DIY 智能车库的爱好者。
真实痛点:
- 老旧社区或小车库没有车位引导系统,车主绕圈找位,浪费时间和燃油。
- 物业缺乏实时数据,无法统计车位使用率、合理分配资源。
- 市售地磁或视觉方案安装贵、施工复杂,不符合小预算改造需求。
为什么值得做:
用一个 30 元出头的节点就能完成一个车位的数字化,数据可直接进云平台。该方案门槛极低,可快速复制到多个车位,形成低成本物联网停车网络,兼具实用性与教学价值。
方案设计
感知层
- HC-SR04 超声波模块发射 40kHz 脉冲,测量模块到车底或地面的距离。
- 安装高度固定(如车库顶或侧面支架),设定阈值区分“有车”与“无车”。
控制层
- ESP32 作为主控,负责触发测距、处理回波信号、判断占用状态。
- 根据距离数据执行消抖和滤波,避免飞鸟或行人误判。
- 利用 ESP32 的 Deep‑sleep 和 RTC 定时器唤醒,每 30 秒唤醒一次进行测量,其余时间芯片处于睡眠状态,显著降低功耗。
执行层
- GPIO2 驱动一颗 LED,有车时常亮或闪烁,无车时熄灭,便于现场巡检。
- 可扩展继电器或警示灯,但本方案以成本优先仅用 LED 指示。
日志/联网层
- ESP32 连接 2.4GHz Wi‑Fi,通过 MQTT 协议上报 JSON 格式数据到本地或云 Broker。
- 上报内容:车位 ID、占用状态、距离值、信号强度、电池电压(若有)。
- 支持 TLS 加密(可选),保证传输安全。
- 服务端可结合 Node‑RED 或 Home Assistant 可视化,也可推送到微信/钉钉通知。
物料清单
| 物料名称 | 数量 | 用途 | 估算单价(元) |
|---|---|---|---|
| ESP32 DEVKIT V1 开发板 | 1 | 主控及 Wi‑Fi 通信 | 15.0 |
| HC‑SR04 超声波测距模块 | 1 | 距离采集 | 3.5 |
| 红色 LED 5mm | 1 | 车位状态指示 | 0.05 |
| 220Ω 限流电阻 | 1 | LED 保护 | 0.02 |
| 面包板 170孔 mini | 1 | 电路搭建 | 3.5 |
| 母母、公公杜邦线若干 | 1 套 | 模块与开发板连接 | 2.0 |
| Micro‑USB 供电线 | 1 | 供电及下载 | 2.0 |
| 合计 | 26.07 |
物料总成本约 26 元,满足 35 元预算要求。如需更稳定安装可增加扎带和亚克力支架,仍在预算内。
接线与结构
按照项目给定的 GPIO 进行接线(同时结合超声波模块典型工作模式):
- HC-SR04 VCC → ESP32 5V 或 3V3(部分模块支持 3.3V,此处使用 5V 供电以获得更稳定回波,ESP32 5V 引脚由 USB 供电)
- HC-SR04 GND → ESP32 GND
- HC-SR04 Trig → ESP32 GPIO5(输出触发脉冲)
- HC-SR04 Echo → ESP32 GPIO18(输入回波脉宽)
- LED 正极(长脚) 串联 220Ω 电阻 → ESP32 GPIO2
- LED 负极 → ESP32 GND
微调说明:原接线指定 Trig=5, Echo=18, LED=2。此安排完全符合 ESP32 的 GPIO 功能,且 5 与 18 均非启动引脚,不会影响下载模式。GPIO2 内部有弱上拉,但此处输出高电平点亮 LED,亦无冲突。超声波模块的 Echo 引脚必须接输入捕获脚,GPIO18 为输入模式。若需要增加硬件中断可选用其他引脚,但 Echo 仅通过 pulseIn() 测量已足够,不强制使用中断编号,因此保持原方案不变。
结构思路:将超声波模块倒装于车位正上方或侧面高处,探测波束垂直向下或斜向照射。探测区域避开墙角等固定障碍物,保证无车时返回地面距离,有车时返回车顶或车底距离。开发板和面包板可封装在防水接线盒内固定于横梁。
核心代码
#include <WiFi.h>
#include <PubSubClient.h>
#include "esp_sleep.h"
// WiFi & MQTT 配置
const char* ssid = "Your_SSID";
const char* password = "Your_PASS";
const char* mqtt_server = "192.168.1.100";
const int mqtt_port = 1883;
const char* topic = "parking/spot1";
const char* clientId = "ESP32_Parking1";
// 引脚定义
#define TRIG_PIN 5
#define ECHO_PIN 18
#define LED_PIN 2
// 距离阈值(厘米),小于此值认为有车
#define THRESHOLD_DIST 30.0
// 唤醒间隔(秒)
#define SLEEP_DURATION_SEC 30
WiFiClient espClient;
float readDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
float dist = duration * 0.034 / 2; // 声速换算为 cm
return dist;
}
void setup_wifi() {
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
attempts++;
}
}
void reconnect_mqtt() {
while (!client.connected()) {
if (client.connect(clientId)) {
// 连接成功
} else {
delay(2000);
}
}
}
void go_to_sleep() {
esp_sleep_enable_timer_wakeup(SLEEP_DURATION_SEC * 1000000ULL);
esp_deep_sleep_start();
}
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// 首次上电执行一次测量与上报,之后进入睡眠
float distance = readDistance();
bool occupied = (distance < THRESHOLD_DIST);
// LED 指示
digitalWrite(LED_PIN, occupied ? HIGH : LOW);
setup_wifi();
if (WiFi.status() == WL_CONNECTED) {
reconnect_mqtt();
// 构建 JSON 字符串
String payload = "{\"occupied\":" + String(occupied) + ",\"distance\":" + String(distance) + "}";
delay(100); // 保证数据发完
}
client.disconnect();
WiFi.disconnect(true);
go_to_sleep();
}
void loop() {
// 永远不会执行到这里,因为 deep sleep 后复位进入 setup()
}
代码说明:
- 上电后先测距、判断是否有车,然后连接 Wi‑Fi 并通过 MQTT 上报 JSON 数据。
- 使用深度睡眠,30 秒后 RTC 唤醒,ESP32 重新执行 setup()。如此循环,大幅降低平均功耗。
- pulseIn 超时设为 30ms,防止传感器故障卡死。
- 可根据需要调整 THRESHOLD_DIST,一般轿车底盘离地间隙约 15‑20cm,车顶距离若安装高度 2.5m,可设为 50cm 以下为有车。
调试步骤
- 硬件通电检查:通过 USB 给 ESP32 供电,测量 VCC 和 GND 是否正确。用万用表检查 HC‑SR04 的 VCC 电压是否为 5V。
- 串口监视:使用 Arduino IDE 串口监视器(115200 波特率)观察距离读数。可以用手遮挡模拟有车,看距离值是否突变。
- 阈值标定:在真实车位安装高度下,记录无车时的地面距离(例如 200cm)和有车时的底盘距离(例如 15cm)。将阈值设为两者中间值,如 30cm,同时预留 5‑10cm 的冗余避免误判。
- MQTT 连通性测试:在本机或服务器搭建 Mosquitto Broker,修改代码中的 IP 地址。通过 MQTT 客户端订阅
parking/spot1,观察上报内容是否与 LED 状态一致。 - 睡眠功耗验证:用 USB 电流表测量睡眠时电流,正常应在 100μA‑5mA 之间(取决于开发板)。若电流偏高,检查外围电路是否有漏电。
- 长时间运行:连续运行 24 小时,查看 MQTT 历史记录有无掉线和误报。可根据需要调整上报间隔(SLEEP_DURATION_SEC)。
设计图
停车位占用监测结构flow
1
感知输入(HC-SR04测距)
→
2
控制处理(ESP32判断有车/无车)
→
3
执行反馈(LED状态指示)
→
4
数据上报(MQTT发送JSON)
→
5
低功耗休眠(定时唤醒循环)