最近用 ESP32 接了一个 HC-SR04 超声波测距模块,再加一个有源蜂鸣器,做了一个”距离小于 10 cm 就报警”的小实验。记录下接线、代码和踩过的坑。
实验目标
用 ESP32 读取 HC-SR04 超声波模块测得的距离。
当距离小于 10 cm 时,蜂鸣器每 3 秒响一次,每次响 200 ms。
距离大于等于 10 cm 时,蜂鸣器保持安静。
所需材料
器件
数量
说明
ESP32 开发板
1
普通 DevKit 即可
HC-SR04 超声波模块
1
测距范围 2 cm ~ 400 cm
有源蜂鸣器模块
1
常见低电平触发
杜邦线
若干
母对母或公对母
接线 HC-SR04 与 ESP32
HC-SR04
ESP32
VCC
3.3V 或 5V
GND
GND
Trig
GPIO18(D18)
Echo
GPIO19(D19)
HC-SR04 的 Echo 输出 5V 高电平,ESP32 GPIO 耐压 3.3V。实际测试直接接也能工作,但严格来说建议在 Echo 和 ESP32 之间串一个 1kΩ 电阻分压,更安全。
蜂鸣器与 ESP32
蜂鸣器
ESP32
VCC
3.3V
GND
GND
IO / SIG
GPIO23(D23)
有源蜂鸣器分两种触发方式:
低电平触发 :GPIO 输出低电平时响,高电平时不响(本次使用的类型)。
高电平触发 :GPIO 输出高电平时响,低电平时不响。
如果接好后蜂鸣器一直响,大概率是触发方式设反了,改一下代码里的 active_high 即可。
实际接线图:
代码 项目里有两个文件:hcsr04.py 是测距库,main.py 是主程序。
hcsr04.py from machine import Pinimport time TRIG_PIN = 5 ECHO_PIN = 4 MAX_ECHO_US = 30000 SOUND_SPEED_CM_PER_US = 0.0343 def measure_single (trig_pin=TRIG_PIN, echo_pin=ECHO_PIN ): trig = Pin(trig_pin, Pin.OUT) echo = Pin(echo_pin, Pin.IN) trig.value(0 ) time.sleep_us(2 ) trig.value(1 ) time.sleep_us(10 ) trig.value(0 ) start_wait = time.ticks_us() while echo.value() == 0 : if time.ticks_diff(time.ticks_us(), start_wait) > MAX_ECHO_US: return -1 start = time.ticks_us() while echo.value() == 1 : if time.ticks_diff(time.ticks_us(), start) > MAX_ECHO_US: return -1 duration = time.ticks_diff(time.ticks_us(), start) distance = duration * SOUND_SPEED_CM_PER_US / 2 return distancedef measure (samples=5 , trig_pin=TRIG_PIN, echo_pin=ECHO_PIN ): values = [] for _ in range (samples): d = measure_single(trig_pin, echo_pin) if d >= 0 : values.append(d) time.sleep_ms(10 ) if not values: return -1 values.sort() n = len (values) if n % 2 == 1 : return values[n // 2 ] return (values[n // 2 - 1 ] + values[n // 2 ]) / 2
measure() 默认采样 5 次取中值,能过滤一些毛刺。
main.py import timefrom machine import Pinfrom hcsr04 import measure TRIG_PIN = 18 ECHO_PIN = 19 BUZZER_PIN = 23 active_high = False buzzer = Pin(BUZZER_PIN, Pin.OUT) buzzer.value(0 if active_high else 1 ) THRESHOLD_CM = 10 INTERVAL_MS = 3000 BEEP_MS = 200 while True : distance = measure(samples=5 , trig_pin=TRIG_PIN, echo_pin=ECHO_PIN) print ('distance: %.1f cm' % distance) if 0 <= distance < THRESHOLD_CM: print ('ALARM: distance < %d cm' % THRESHOLD_CM) buzzer.value(1 if active_high else 0 ) time.sleep_ms(BEEP_MS) buzzer.value(0 if active_high else 1 ) time.sleep_ms(INTERVAL_MS)
核心逻辑:
TRIG_PIN = 18 和 ECHO_PIN = 19 对应 D18、D19。
每 3 秒测一次距离。
距离小于 10 cm 时,蜂鸣器响 200 ms。
active_high 控制蜂鸣器触发极性。
烧录与上传 本次使用 MicroPython,所以需要先把 MicroPython 固件刷进 ESP32,再上传 Python 文件。
1. 刷 MicroPython 固件 esptool --port /dev/ttyUSB0 erase_flash esptool --port /dev/ttyUSB0 --baud 460800 write_flash 0x1000 ESP32_GENERIC-xxxxxx-vx.xx.x.bin
2. 上传 Python 文件 mpremote connect /dev/ttyUSB0 cp main.py :main.py mpremote connect /dev/ttyUSB0 cp hcsr04.py :hcsr04.py mpremote connect /dev/ttyUSB0 reset
3. 查看串口输出 mpremote connect /dev/ttyUSB0 repl
正常会看到如下输出:
distance : 59 .1 cmdistance : 59 .0 cmALARM : distance < 10 cmdistance : 8 .5 cm
按 Ctrl+] 退出 REPL。
实测效果
无障碍物时,串口每隔 3 秒打印一次距离,蜂鸣器安静。
用手靠近超声波模块,距离降到 10 cm 以下时,蜂鸣器开始”嘀——嘀——“响,每 3 秒一次。
移开手后,蜂鸣器停止。
实测视频:
你的浏览器不支持视频播放,可以点击这里下载 。
踩坑记录
蜂鸣器一直响
原因:active_high 与蜂鸣器实际触发方式不一致。
解决:低电平触发设 False,高电平触发设 True。
mpremote 进不了 Raw REPL
原因:旧固件/程序状态异常,或主板在循环中没响应。
解决:重新擦除 Flash 并刷入 MicroPython 固件。
距离偶尔跳变
原因:超声波回波受环境干扰。
解决:用 measure() 多次采样取中值,已经写在代码里。
总结 这个实验整体比较简单,主要是熟悉 ESP32 + MicroPython + HC-SR04 的套路。蜂鸣器作为报警输出,配合阈值判断就能做出一个实用的近距提醒装置。后续可以扩展成倒车雷达、液位报警、人体靠近提醒等场景。
评论
0 条评论