使用PyFirmata驱动Arduino HC-SR04超声波传感器遇读数异常求助
问题分析
PyFirmata通过串口与Arduino通信,默认依赖迭代器轮询读取引脚状态,这种方式实时性不足,无法精准捕捉HC-SR04的短脉冲(Echo引脚的高电平脉冲宽度从几十微秒到几十毫秒不等,轮询间隔可能跟不上)。另外代码里的死循环等待逻辑,会因为读取延迟直接错过脉冲,导致始终读不到高电平信号。
解决方案
1. 启用引脚实时报告
默认情况下PyFirmata的数字输入引脚可能未开启主动状态报告,需要手动启用,让Arduino主动发送引脚状态变化,而非Python端被动轮询。
2. 优化等待逻辑,增加超时机制
避免用while死循环等待,添加超时判断,防止程序无限阻塞。
修复后的代码
import pyfirmata import time board = pyfirmata.Arduino('COM16') # 初始化引脚 echo = board.get_pin('d:11:i') trig = board.get_pin('d:12:o') LED = board.get_pin('d:13:o') # 关键:启用Echo引脚的状态报告 echo.enable_reporting() it = pyfirmata.util.Iterator(board) it.start() trig.write(0) time.sleep(2) # 传感器初始化 while True: time.sleep(0.5) # 发送触发脉冲 trig.write(1) time.sleep(0.00001) # 维持10微秒高电平 trig.write(0) start_time = time.time() timeout = start_time + 0.1 # 设置0.1秒超时,避免无限等待 # 等待Echo变为高电平 while echo.read() is False and time.time() < timeout: start_time = time.time() # 超时处理:未检测到反射信号 if time.time() >= timeout: print("未检测到信号,距离过远或传感器异常") continue # 等待Echo变回低电平 end_time = time.time() while echo.read() is True and time.time() < (start_time + 0.1): end_time = time.time() time_elapsed = end_time - start_time distance = (time_elapsed * 34300) / 2 # 声速取34300cm/s print(f"测量距离 = {distance:.2f} cm")
额外排查点
- 确认接线:Trig接D12、Echo接D11,GND和5V供电引脚连接牢固
- 检查Arduino已烧录Standard Firmata固件(烧录路径:Arduino IDE → 文件 → 示例 → Firmata → StandardFirmata)
- 关闭其他占用串口的程序(比如Arduino IDE的串口监视器)
内容的提问来源于stack exchange,提问作者Phinsen Renaldo
相关产品推荐
相关产品推荐

