HC-SR04 超声波测距实战
📅 2026-05-13 · 📂 硬件编程 · ⏱ 阅读约 6 分钟
概述
HC-SR04 是最经典的单片机测距模块,价格不到 5 元。利用超声波发射-反射原理,可实现 2cm-4m 的非接触式距离测量。
学习目标:理解超声波测距原理(脉冲-回波法),掌握微秒级定时,学会滤波和精度优化。
物料清单
- ESP32 ×1
- HC-SR04 超声波模块 ×1
- 杜邦线 ×4
测距原理
HC-SR04 有两个"眼睛":Trig(发射换能器)和 Echo(接收换能器)。工作流程:
- Trig 引脚给 ≥10μs 的高电平脉冲 → 模块自动发送 8 个 40kHz 超声波
- 超声波遇到障碍物反射回来
- Echo 引脚输出高电平,持续时间 = 超声波往返时间
- 距离 = 高电平时间 × 声速 / 2(往返除以2)
声速 ≈ 340m/s(0.034 cm/μs),所以:距离(cm) = 高电平时长(μs) × 0.034 / 2 ≈ 高电平时长 / 58
接线图
🔌 接线
ESP32 HC-SR04
┌─────────┐ ┌─────────┐
│ 5V(VIN) ┼──────┼ VCC │
│ GND ┼──────┼ GND │
│ GPIO5 ┼──────┼ Trig │
│ GPIO18 ┼──────┼ Echo │
└─────────┘ └─────────┘
⚠️ HC-SR04 工作电压 5V,但 Echo 输出为 5V!
需加分压电阻 (1kΩ+2kΩ) 降到 3.3V
或直接接(仅限测试,可能烧引脚)
完整代码
// Ultrasonic_HCSR04.ino — 超声波测距
#define TRIG 5
#define ECHO 18
float getDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH, 30000); // 30ms超时 ≈ 5m
if (duration == 0) return -1; // 超时/无回波
return duration * 0.034 / 2;
}
void setup() {
Serial.begin(115200);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
void loop() {
float dist = getDistance();
if (dist < 0) Serial.println("⚠ 超出范围");
else Serial.printf("距离: %.1f cm
", dist);
delay(500);
}
精度优化:滑动平均滤波
// 多次测量取中位数 — 滤除偶发错误
float getDistanceFiltered(int samples = 5) {
float readings[samples];
for (int i = 0; i < samples; i++) {
readings[i] = getDistance();
delay(20); // 间隔20ms避免干扰
}
// 冒泡排序后取中位数
for (int i = 0; i < samples-1; i++)
for (int j = 0; j < samples-i-1; j++)
if (readings[j] > readings[j+1]) { float t = readings[j]; readings[j] = readings[j+1]; readings[j+1] = t; }
return readings[samples/2];
}
常见问题
⚠️ 5V Echo 兼容:HC-SR04 的 Echo 输出是 5V 电平,直接接入 ESP32 会烧毁 GPIO!解决方案:用两个电阻分压(1kΩ+2kΩ),或买 HC-SR04P(3.3V兼容款)。
⚠️ 最小盲区:HC-SR04 最小测量距离约 2cm。小于 2cm 时 Echo 脉冲和 Trig 脉冲混叠,读数不准。
💡 替代方案:需要更高精度或更小体积?用 VL53L0X 激光测距模块(I²C接口,精度 ±1mm,尺寸 4×2mm)。