Skip to content

第 10 章:看懂超声波测距代码

本章任务

看懂 HC-SR04 超声波测距的代码——对应第一册第 10 章的实验。这是六个实验里代码最"绕"的一个,但拆开看每一步都很直白。

接线回顾

HC-SR04Pico说明
VCC3V3 (Pin 36)3.3V 供电
TrigGP16 (Pin 21)触发信号(输出)
EchoGP17 (Pin 22)回波信号(输入,需分压
GNDGND (Pin 23)共地

Echo 输出 5V 电平,Pico 只耐受 3.3V,所以接线里有分压电阻(Echo → 1kΩ → GP17,GP17 → 2kΩ → GND)。

Mind+ 生成的典型代码

python
from machine import Pin        # 引脚控制工具
import time                    # 时间工具

trig = Pin(16, Pin.OUT)        # GP16:触发引脚,输出模式
echo = Pin(17, Pin.IN)         # GP17:回波引脚,输入模式

def measure():                 # 定义一个叫 measure(测量)的函数
    # 第一步:发一个 10 微秒的高电平,通知模块"开始测距"
    trig.value(0)              # 先确保触发脚是低电平
    time.sleep_us(2)
    trig.value(1)              # 拉高(发信号)
    time.sleep_us(10)          # 保持 10 微秒
    trig.value(0)              # 拉低,触发完成

    # 第二步:等回波开始,记下开始时刻
    while echo.value() == 0:   # 只要回波还没来(低电平)……
        pass                   # ……就原地等着
    start = time.ticks_us()    # 回波开始了!记下这一刻的时间

    # 第三步:等回波结束,记下结束时刻
    while echo.value() == 1:   # 只要回波还在持续(高电平)……
        pass                   # ……继续等
    end = time.ticks_us()      # 回波结束了!记下这一刻

    # 第四步:用"持续时间"算距离
    duration = time.ticks_diff(end, start)     # 高电平持续了多久(微秒)
    distance = duration * 0.0343 / 2           # 换算成厘米
    return distance            # 把结果交出去

while True:                    # 主循环:每秒测一次
    d = measure()              # 调用上面的函数,拿到距离
    print(f"距离:{d:.1f} cm")  # 打印出来,保留 1 位小数
    time.sleep(1)              # 等 1 秒再测下一次

代码讲解

测距的原理(第一册 10.1):Trig 发信号 → 模块发出超声波 → 波撞到障碍物弹回来 → Echo 脚高电平的持续时间 = 波的往返时间。

代码就是这四步的忠实翻译:

  1. 触发trig 拉高 10 微秒——等于对模块喊"开始!"
  2. 等回波开始:第一个 while 循环里只有一个 pass(什么都不做),就是干等
  3. 等回波结束:第二个 while 同样干等,结束瞬间记下时间
  4. 算距离:距离 = 时间 × 声速 ÷ 2。除以 2 是因为声波走了"去 + 回"两趟

ticks_us() 是"微秒级秒表",ticks_diff(end, start) 算两个时刻的差。def measure(): 把这一大段打包成一个函数,主循环里一句 measure() 就能测一次——这就是第 6 章说的函数的好处。

运行效果

程序运行后,每秒打印一次当前距离。把手放在传感器前由远及近移动,数值会跟着变小。

常见坑

  • 读数始终是 0 或固定值:检查代码里 Trig 和 Echo 的编号有没有写反(Trig=16 是发、Echo=17 是收)
  • 程序像"卡住"不打印:两个 while 都在等回波,如果接线松了或 Echo 分压没接,就会一直等下去
  • 读数忽大忽小:让模块对准平整的墙面测,斜面、海绵、布料会让回波不稳定

想一想

  1. distance = duration * 0.0343 / 2 里的 / 2 如果去掉,显示的距离会偏大还是偏小?

    💡 查看答案

    偏大,而且是整整一倍。因为声音从传感器出发、撞到物体、再弹回来,走的是"来回"两段路,除以 2 才是单程距离。去掉 / 2,20cm 会显示成 40cm。

  2. 找到代码里的 time.sleep(1),改成 0.2 会怎样?

    💡 查看答案

    每秒从测 1 次变成测 5 次,屏幕上的距离刷新更快、跟手更灵敏;但数字也会跳得更快,看起来没那么稳。

不积跬步,无以至千里;万里之行,始于当下。