← 返回传感器图鉴

HC-SR04 超声波测距传感器

最后更新 2026-06-20
⏱ 约 8 分钟 🟡 涉接线/强电
🛒 器材清单
器材数量参考
HC-SR04 模块1
杜邦线4

价格随渠道波动,以购买页实时为准。

想让一辆小车知道"前面有没有墙、还有多远",最便宜的办法不是激光,也不是摄像头,而是这块巴掌一半大、价格三五块钱的蓝板子——HC-SR04。它的工作方式和蝙蝠一模一样:朝前喊一嗓子(人耳听不见的超声波),听回声什么时候弹回来,时间差一算,距离就出来了。

它不是"看"到距离,而是"算"出距离。理解这一点,后面的坑就好躲了。

工作原理

把它板子上那两个银色的金属圆筒看成一只嘴、一只耳朵,整个测距过程就是四步:

  1. 触发:你给 Trig 脚一个至少 10 微秒的高电平脉冲,告诉模块"开始测"。
  2. 发声:模块收到触发后,从发射头打出 8 个 40kHz 的超声脉冲串。这个频率远超人耳上限(约 20kHz),所以全程悄无声息。
  3. 听回声:声波撞到物体反弹回来,接收头收到回声的瞬间,模块把 Echo 脚拉低。从发声开始到收到回声,Echo 脚一直是高电平。
  4. 算距离:Echo 高电平持续的这段时间,就是声波"去 + 回"的总往返时间。

核心就一条公式。声波在常温空气里约 340 米/秒,换算成方便的单位是 0.034 cm/μs(每微秒走 0.034 厘米)。声波是往返跑了两趟,所以要除以 2:

距离(cm) = Echo高电平时间(μs) × 0.034 ÷ 2

把 0.034 ÷ 2 算出来约等于 0.017,倒过来就是大家常用的"除以 58"那个魔法数字——距离(cm) ≈ Echo时间(μs) / 58,两种写法等价,记哪个都行。

想搞清楚 GPIO 怎么发脉冲、怎么读高电平,先看 /principle/gpio/ 打底。

接线

HC-SR04 ESP32 说明
VCC 5V 注意不是 3.3V,供 3.3V 会测不准或不工作
Trig 任意 GPIO(如 GPIO5) 单片机发触发脉冲给它
Echo 任意 GPIO(如 GPIO18) 它回送回声信号,5V 电平需分压
GND GND 共地
⚠️ 安全

HC-SR04 的 Echo 脚回给单片机的是 5V 高电平。 ESP32 的 GPIO 只认 3.3V,长期直接接 5V 的 Echo 有打坏引脚的风险。规范做法是在 Echo 和 ESP32 之间加一个分压:1kΩ 串联 2kΩ 对地,从中间取信号,就能把 5V 压到约 3.3V。或者用专门的电平转换模块。短期面包板实验很多人直连也没烧,但要做产品请务必加分压。原理见 /principle/level-shift/

完整代码

下面是阻塞式的标准写法,逻辑和上面四步严格对应:

const int trigPin = 5;
const int echoPin = 18;

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

void loop() {
  // 1. 触发:先拉低确保干净,再给 10μs 高电平
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // 2. 测 Echo 高电平持续时间(微秒),第三参数是超时 30ms
  long duration = pulseIn(echoPin, HIGH, 30000);

  // 3. 换算成厘米:往返要除以 2,声速 0.034 cm/μs
  float distance = duration * 0.034 / 2;

  // 4. 超时返回 0 表示没收到回声(太远 / 没对准 / 接线问题)
  if (duration == 0) {
    Serial.println("超出量程或无回声");
  } else {
    Serial.print("距离: ");
    Serial.print(distance);
    Serial.println(" cm");
  }

  delay(200); // 两次测量间隔,别打太密,否则上一次的回声会干扰
}

pulseIn 会一直等到 Echo 变高再计时到它变低,所以它是阻塞的——在它返回前 CPU 干不了别的。对避障小车这种场景一般够用。如果你的程序还要同时跑别的任务,可以改用中断 + micros() 记录时间的非阻塞写法,让 AI 按这个思路帮你改即可。

你应该看到什么

烧录后打开串口监视器(波特率 115200),把手掌伸到模块正前方:

  • 手在 20cm 处,串口大约打印 距离: 20.xx cm
  • 手慢慢往前推到 10cm、5cm,数字跟着平滑减小;
  • 把手完全移开、前方 4 米内无障碍,会看到 超出量程或无回声

数字能随手的距离连续变化,就说明发声、回声、计时这条链路全通了。

读数解读

  • 量程:约 2cm 到 400cm。超过 4 米回声太弱,常返回 0。
  • 精度:理想条件下约 ±3mm,但这是对硬质平面正对的成绩,实际玩法里到厘米级就不错了。
  • 波束角:约 15°,是一个锥形探测区,而不是一条激光线。这意味着它"看"的是前方一个扇面里最近的那个东西,分辨不出具体方位。

选型 / 避坑

便宜、量程大、5V 就能跑,是它的全部优点。缺点也很集中,下面几条几乎人人踩过:

🚧 避坑

① 盲区:小于约 2cm 测不准。发声和收声共用模块的时间窗口,物体贴太近时回声还没来得及被正确捕捉。 ② 软物 / 斜面漏检:海绵、布料、窗帘吸声,回声太弱收不到;斜面会把声波反射到别处而不是弹回来,于是"看不见"明明在眼前的东西。对硬质、正对的平面最准。 ③ 波束太宽:15° 锥角容易把旁边的桌腿、墙角也算进来,误报"前方有障碍"。窄空间里尤其明显。 ④ Echo 是 5V:接 ESP32 不分压有烧引脚风险(见上方安全提示)。 ⑤ 温度影响声速:声速随温度变化,0°C 约 331m/s、30°C 约 349m/s。对厘米级精度影响不大,要做高精度可按温度修正声速。

什么时候不该用它、该换别的:

  • 要精度高、要小体积、要抗声音干扰、不想折腾分压 → 上激光 ToF 的 VL53L0X(I2C 接口,原生 3.3V,无需分压),见 /sensor/vl53l0x/
  • 要便宜、要测得远(几米)、对精度和体积无所谓 → 就用 HC-SR04,它依然是这个价位的标杆。

故障排查

现象 可能原因 排查
一直读 0 或超大值 Echo / Trig 接反,或 Echo 没接好 核对接线,Trig 是输出、Echo 是输入
一直读 0 前方 >4m 无障碍,或目标吸声 / 斜面 拿硬质平面对正面试,距离放在 5–100cm
读数乱跳不稳 供电不足 5V 掉压;测量太密回声串扰 用稳定 5V,两次测量间隔 ≥60ms
数值整体偏大 Echo 5V 直连导致电平异常 加 1k+2k 分压再试
完全无反应 VCC 接了 3.3V 必须给 5V

进阶 / 变体

  • 舵机云台扫描:把 HC-SR04 装在一个舵机上,让舵机从 0° 转到 180°,每隔几度测一次距离,就能画出前方的"扇形地图"——这是很多避障小车和雷达可视化项目的做法,能部分弥补单点测距分辨不出方位的短板。
  • 多次取中值滤波:单次读数偶尔会跳。连测 5 次取中位数(不是平均值,中位数更抗突变),读数会稳很多,代价是采样慢一点。
  • 多模块协同:小车前方左中右各装一个,分时触发(避免互相收到对方的回声),就能粗略判断障碍偏哪边。

典型应用

  • 避障小车:检测前方障碍并提前刹车 / 转向;
  • 停车入库提醒:车尾装一个,离墙越近蜂鸣越急(停车雷达原理);
  • 智能垃圾桶:手靠近自动开盖;
  • 水位 / 液位检测:装在水箱顶部隔空向下测,算出剩余高度。

小结 · 相关

HC-SR04 用最低的成本解决了"前面有没有东西、有多远"这个最常见的需求。记住三件事:它测的是时间不是距离、Echo 是 5V 接 3.3V 单片机要分压、对软物斜面会瞎。把这三条躲过去,它就是个稳定耐用的好帮手。

参数以上方 datasheet 为准;本页为公开资料整理,接线与代码请结合实物验证。

📄 来源 / 自校链接

本文为公开资料整理,非亲测。关键参数与代码请结合实物与下列官方来源验证。

内容有错、看不懂、或想看下一期?告诉我们 →

本文为公开资料的学习整理,非亲测。涉接线/花钱/合规的步骤请结合实物与官方最新资料验证,风险自负。见免责声明