HC-SR04 超声波测距实战

📅 2026-05-13 · 📂 硬件编程 · ⏱ 阅读约 6 分钟

📺 B站推荐视频:ESP32 入门教程

概述

HC-SR04 是最经典的单片机测距模块,价格不到 5 元。利用超声波发射-反射原理,可实现 2cm-4m 的非接触式距离测量。

学习目标:理解超声波测距原理(脉冲-回波法),掌握微秒级定时,学会滤波和精度优化。

物料清单

测距原理

HC-SR04 有两个"眼睛":Trig(发射换能器)和 Echo(接收换能器)。工作流程:

  1. Trig 引脚给 ≥10μs 的高电平脉冲 → 模块自动发送 8 个 40kHz 超声波
  2. 超声波遇到障碍物反射回来
  3. Echo 引脚输出高电平,持续时间 = 超声波往返时间
  4. 距离 = 高电平时间 × 声速 / 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)。