You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:10:23