超声波传感器

原理简介

超声波传感器发射超声波并接收回波,用「发出到收回的时间差」算距离。

  • 工作原理:Trig 脚发一个 10µs 脉冲触发测距,Echo 脚输出高电平,高电平宽度 = 声波往返时间
  • 常见型号:HC-SR04
  • 重要电平:Trig 是 3.3V 输入可直连;Echo 输出是 5V,必须经电阻分压再进 Pico GPIO
  • 接口:Trig = GPIO 输出,Echo = GPIO 输入(分压后)

典型应用

  • 测距
  • 小车避障
  • 液位 / 水位检测
  • 物体探测
  • 机器人导航

接线图

[接线图占位,后续添加]

文字说明(具体接法见下方代码注释):

  • HC-SR04 VCC → Pico 5V(VBUS,模块要 5V 才正常工作)
  • HC-SR04 GND → Pico GND
  • HC-SR04 Trig → Pico GP16(3.3V 输入,可直连)
  • HC-SR04 Echo → 1kΩ 电阻 → Pico GP17,同时 GP17 → 2kΩ 电阻 → GND (分压:5V × 2k/(1k+2k) ≈ 3.3V,把 Echo 的 5V 降到 GPIO 安全范围)

示例代码

基础示例:测距

# ============ 接线 ============
# HC-SR04 VCC → Pico 5V(VBUS)
# HC-SR04 GND → Pico GND
# HC-SR04 Trig → Pico GP16(3.3V 直连)
# HC-SR04 Echo → 1kΩ → GP17,GP17 → 2kΩ → GND(分压,Echo 是 5V 必须降)
# =============================
from machine import Pin
import time

trigger = Pin(16, Pin.OUT)
echo = Pin(17, Pin.IN)

def measure_distance():
    # 发 10µs 触发脉冲
    trigger.value(0)
    time.sleep_us(2)
    trigger.value(1)
    time.sleep_us(10)
    trigger.value(0)

    # 等 Echo 变高,再计时高电平宽度
    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         # 声速 340m/s,除以 2(往返)
    return distance

print('超声波测距')

while True:
    try:
        dist = measure_distance()
        print(f'距离: {dist:.1f} cm')
    except Exception as e:
        print('测量失败:', e)
    time.sleep(1)

进阶示例:避障系统(继电器模块控电机)

# ============ 接线 ============
# 超声波:VCC → 5V,GND → GND,Trig → GP16,Echo → 1kΩ → GP17 → 2kΩ → GND
# 继电器模块(已带驱动,GPIO 只给信号,电机强电由模块隔离):
#   继电器模块 IN  → Pico GP15
#   继电器模块 VCC → Pico 3V3
#   继电器模块 GND → Pico GND
#   继电器模块 COM/NO 接电机和电源(电机别直接接 GPIO)
# =============================
from machine import Pin
import time

trigger = Pin(16, Pin.OUT)
echo = Pin(17, Pin.IN)
relay = Pin(15, Pin.OUT)     # 继电器模块信号脚

SAFE_DISTANCE = 30           # 安全距离(厘米)

def measure_distance():
    trigger.value(0)
    time.sleep_us(2)
    trigger.value(1)
    time.sleep_us(10)
    trigger.value(0)
    while echo.value() == 0:
        pass
    start = time.ticks_us()
    while echo.value() == 1:
        pass
    end = time.ticks_us()
    return time.ticks_diff(end, start) * 0.0343 / 2

print('避障系统')
print(f'距离小于 {SAFE_DISTANCE} 厘米时停止')

while True:
    try:
        dist = measure_distance()
        print(f'距离: {dist:.1f} cm')
        if dist < SAFE_DISTANCE:
            relay.off()       # 停止电机
            print('距离过近,停止')
        else:
            relay.on()        # 启动电机
            print('距离安全,继续')
    except Exception as e:
        print('测量失败:', e)
    time.sleep(0.5)

应用示例:液位检测

# ============ 接线 ============
# 超声波:VCC → 5V,GND → GND,Trig → GP16,Echo → 1kΩ → GP17 → 2kΩ → GND
# (只测距离,不接其它外设)
# =============================
from machine import Pin
import time

trigger = Pin(16, Pin.OUT)
echo = Pin(17, Pin.IN)

CONTAINER_HEIGHT = 100        # 容器高度(厘米)

def measure_distance():
    trigger.value(0)
    time.sleep_us(2)
    trigger.value(1)
    time.sleep_us(10)
    trigger.value(0)
    while echo.value() == 0:
        pass
    start = time.ticks_us()
    while echo.value() == 1:
        pass
    end = time.ticks_us()
    return time.ticks_diff(end, start) * 0.0343 / 2

print('液位检测')

while True:
    try:
        dist = measure_distance()
        liquid_level = max(0, CONTAINER_HEIGHT - dist)   # 距底液面高度
        level_percent = liquid_level / CONTAINER_HEIGHT * 100
        print(f'距离: {dist:.1f} cm, 液位: {liquid_level:.1f} cm, 百分比: {level_percent:.1f}%')
    except Exception as e:
        print('测量失败:', e)
    time.sleep(2)

注意事项

  • Echo 必须分压:HC-SR04 的 Echo 是 5V 输出,直连 Pico GPIO 会烧引脚!一定要 1kΩ + 2kΩ 分压
  • Trig 可直连:Trig 是 3.3V 输入,直接接 GPIO 即可,别分压
  • 供电用 5V:HC-SR04 模块标称 5V,接 VBUS(5V);只用 3.3V 可能测不准或不工作
  • 测量间隔:两次触发至少隔 60ms,示例里 time.sleep(0.5~1) 已满足
  • 测量范围:有效约 2–400 厘米;太近(<2cm)或没障碍物会读到异常值,用 try/except 兜底
  • 电机/负载走继电器:驱动电机会用继电器模块,电机强电绝不直连 GPIO

常见问题

Q: 距离一直读到 0 或特别大? A: 先查 Echo 分压电阻有没有接(Echo 直连 5V 会伤脚);再查 Trig/Echo 脚号是否和你 Pin() 里一致。

Q: 数值跳动很大? A: 多次测量取平均,或避开棉布/斜面等吸音/斜反射物体;也确认 60ms 间隔够。

Q: 接了 5V 供电,GPIO 会坏吗? A: 只要 Echo 走了 1k+2k 分压、Trig 用 3.3V 直连,GPIO 只接触约 3.3V,是安全的。