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

Linux下pyserial打开/dev/ttyUSB0串口报BrokenPipeError问题咨询

问题根因

pyserial 打开串口设备时,默认会执行完整的标准RS232串口初始化流程,包含RTS、DTR等硬件流控引脚的状态置位操作,会通过fcntl.ioctl向设备发送对应控制指令。
你使用的USB条码扫描枪属于模拟串口(CDC ACM)类设备,多数这类低成本扫描枪仅实现了串口的数据收发通道逻辑,完全没有实现硬件流控相关的指令响应逻辑。你用cat < /dev/ttyUSB0读取时,仅会对设备做普通字符流读取操作,不会触发流控相关的ioctl调用,因此可以正常回显条码;但pyserial初始化阶段发送RTS状态更新的控制指令时,设备无法响应甚至直接断开通信管道,就会抛出BrokenPipeError: [Errno 32] Broken pipe报错。
这个问题和Python版本无关,Python2.7、Python3.5下的pyserial默认初始化逻辑一致,因此会出现相同报错。

解决方案

按优先级尝试以下方案即可:

  • 方案1:修改pyserial初始化参数,禁用硬件流控,跳过不必要的引脚置位
    初始化串口时显式关闭RTS/CTS、DSR/DTR硬件流控,避免触发不支持的ioctl调用,参考代码:
    import serial
    
    ser = serial.Serial(
        port='/dev/ttyUSB0',
        baudrate=9600, # 替换为你的扫描枪实际波特率,绝大多数设备默认值为9600
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_1,
        bytesize=serial.EIGHTBITS,
        timeout=2,
        rtscts=False, # 关闭RTS/CTS硬件流控
        dsrdtr=False  # 关闭DSR/DTR硬件流控
    )
    # 若上述参数配置后仍触发报错,可追加两行手动拉低对应引脚状态
    ser.rts = False
    ser.dtr = False
    
    # 测试读取
    while True:
        data = ser.readline()
        if data:
            print("扫描得到条码:", data.decode().strip())
    
  • 方案2:直接以普通字符文件方式读取设备
    既然通过cat命令可以直接读取设备输出,说明设备本身就是标准的可读取字符流文件,不需要依赖pyserial的串口控制逻辑,可以直接用Python内置的文件操作接口读取,完全绕开pyserial的初始化流程:
    # 以原始无缓冲只读模式打开设备
    with open('/dev/ttyUSB0', 'rb', buffering=0) as dev:
        while True:
            line = dev.readline()
            if line:
                barcode = line.decode(errors='ignore').strip()
                print("扫描得到条码:", barcode)
    
  • 前置权限检查
    执行脚本前先确认当前用户对/dev/ttyUSB0有读写权限,若权限不足可执行以下命令将当前用户加入串口设备对应的用户组,重启终端后生效:
    sudo usermod -aG dialout $USER
    

内容的提问来源于stack exchange,提问作者Ferdinando Ceci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:24:38