💡 划重点

  • 硬件灵魂:ESP32 做主控,一片低成本超声波 HC‑SR04 完成测距,不用摄像头、不依赖地感线圈。
  • 联网方式:内置 Wi‑Fi 直连路由器,通过 MQTT 协议把车位状态送到手机或物业平台。
  • 低功耗策略:利用 ESP32 的定时深度休眠唤醒,每隔若干秒醒一次测距上报,电池供电也能撑过半年。
  • 成本红线:全部物料控制在 35 元以内,社区车库批量部署不心疼。
  • 部署简单:一个探头装在车位正上方或后墙,LED 就地显示红/绿状态,手机端同步查看。

需求洞察

目标用户:老旧小区物业、私人小车库业主、公司内部停车场管理员。

真实痛点

为什么值得做

用 35 元物料打造一个“能上网的独立车位检测器”,每个车位装一个,无需布线(Wi‑Fi),用 MQTT 直接上报空闲/占用,物业或车主看一眼手机就知道哪儿有车位。对比市面上几百元的单点雷达检测器,成本下降一个数量级,小规模车库也能轻松智能化。

方案设计

感知层

采用一个 HC‑SR04 超声波测距模块,出 Trig 脉冲、等 Echo 拉高时间,计算距离。模块朝正下方或车位后墙安装,将实时距离与预设阈值对比:小于阈值 → 有车,大于阈值 → 空闲。

控制层

ESP32 负责:

执行层

板载 LED 用 GPIO2 驱动,两种颜色指示灯可用红绿双色共阴 LED 或两个 LED 模拟,这里只用单色 LED 做占用指示(高亮代表有车),未来可扩展为红绿双色,但保持成本约束下先单色演示。

日志/联网层

物料清单

物料名称 数量 用途 估算单价(元) 小计(元)
ESP32 开发板(NodeMCU-32S) 1 主控与 Wi‑Fi 13.0 13.0
HC‑SR04 超声波模块 1 测距感知 5.0 5.0
红色 LED(5mm) 1 占用指示 0.1 0.1
220Ω 电阻 1 LED 限流 0.1 0.1
面包板 400 孔 + 连接线 1 套 原型搭建 5.0 5.0
杜邦线(公母、母母) 10 根 传感器与板子连接 2.0 2.0
micro USB 数据线(供电) 1 5V 电源输入 3.0 3.0
合计 28.3

若后期升级为电池供电,可另加 18650 电池及 TP4056 充电模块(约 10 元),总成本仍可控制在 35 元以内。当前方案采用 USB 常供电,以满足物业车库总有插座的条件。

接线与结构

按照给定建议接线,做以下微调说明:

接线顺序:

  1. ESP32 的 5V 和 GND 接面包板电源轨。
  2. HC‑SR04 的 VCC 接 5V,GND 接 GND,Trig 接 GPIO5,Echo 接 GPIO18。
  3. 外接 LED:阳极串 220Ω 电阻后接 GPIO2,阴极接 GND;若直接用板载 LED,则忽略此外接。
  4. 供电:micro USB 线插入电脑 USB 口或手机充电头。

核心代码

以下为 Arduino IDE 下的可编译骨架,使用了 WiFi.hPubSubClient.h 库。代码中深度睡眠定时唤醒,每 8 秒测距一次,连接 MQTT 上报并控制 LED。


#include <WiFi.h>
#include <PubSubClient.h>
#include "esp_sleep.h"

// Wi-Fi 配置
const char* ssid = "Your_SSID";
const char* password = "Your_PASSWORD";

// MQTT 配置
const char* mqtt_server = "192.168.1.100"; // 替换为 Broker IP
const int mqtt_port = 1883;
const char* topic = "parking/spot1";
const char* clientID = "ESP32_Parking_01";

// 引脚定义
const int trigPin = 5;
const int echoPin = 18;
const int ledPin = 2;

// 测距阈值(厘米),小于该值认为有车
const int distance_threshold = 40;

WiFiClient espClient;

void connectWiFi() {
  WiFi.begin(ssid, password);
  int retries = 0;
  while (WiFi.status() != WL_CONNECTED && retries < 30) {
    delay(500);
    retries++;
  }
}

void reconnectMQTT() {
  while (!client.connected()) {
    if (client.connect(clientID)) {
      // 连接成功
    } else {
      delay(1000);
    }
  }
}

float readDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH, 30000); // 超时 30ms
  if (duration == 0) return 999.0; // 超时无效
  float distance = duration * 0.034 / 2;
  return distance;
}

void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // 连接网络
  connectWiFi();

  if (WiFi.status() == WL_CONNECTED) {
    reconnectMQTT();
  }

  float dist = readDistance();
  bool occupied = (dist < distance_threshold);
  String payload = occupied ? "occupied" : "free";

  // 上报
  if (client.connected()) {
    client.loop();
    delay(100);
    client.disconnect();
  }

  // LED 指示
  digitalWrite(ledPin, occupied ? HIGH : LOW);

  // 延时显示一会儿再休眠
  delay(200);

  // 设置定时器唤醒,8 秒后醒来
  esp_sleep_enable_timer_wakeup(8 * 1000000);
  esp_deep_sleep_start();
}

void loop() {
  // 实际不会运行到这里
}

说明

  • 代码在 setup() 中执行一次测距、上报、指示后进入深度睡眠,下一次唤醒再执行,实现低功耗循环。
  • 唤醒后 ESP32 会重新运行 setup(),因此每次都会重新联网,适合间隔较长的场景。
  • MQTT Broker 须提前搭建好,或使用公共测试 Broker,注意更换地址。

调试步骤

  1. 烧录固件并查看串口:将代码中 SSID、密码和 MQTT 服务器地址修改好,编译上传到 ESP32,打开串口监视器(115200 波特率),观察是否打印连接成功信息。
  2. 模拟遮挡测试:用纸板或手掌靠近超声波探头前方 30cm 以内,观察板载 LED 是否点亮;移开后 LED 熄灭。
  3. MQTT 消息验证:在电脑端使用 MQTT 客户端(如 MQTTX)订阅 parking/spot1 主题,上电并让探头识别有车/无车,应能收到 “occupied” 或 “free” 消息。
  4. 低功耗验证:断开串口监视器,用万用表测量睡眠期间开发板的功耗(需去掉 USB‑TTL 芯片耗电部分,或直接用电池供电),预估休眠电流小于 10mA。
  5. 调整阈值:在代码中修改 distance_threshold 变量,以适应实际安装高度。测试时将车停入、驶出,观察 LED 和 MQTT 消息是否正确变化。

设计图

停车位占用监测结构flow
1
感知输入 (HC-SR04 超声测距)
2
控制处理 (ESP32 唤醒计算、判断)
3
执行反馈 (板载 LED 占用指示)
4
数据上报 (MQTT 发布车位状态)