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

树莓派4通过UART读取GM875二维码扫描器数据异常求助

问题

使用GM875二维码/条形码阅读器通过UART连接树莓派4 Model B时,出现以下异常:

  • 初始读取到大量乱码字节(如b'\x00\x00...')
  • 多次扫描后偶尔能获取正确数据,但随后脚本抛出OSError: [Errno 5] Input/output error并终止
  • 该阅读器在ESP32上可正常工作,已开启树莓派UART功能,改用C++代码也会出现乱码问题

所用Python代码

import serial

# Configure the serial connection (adjust parameters as needed)
ser = serial.Serial(
    port='/dev/serial0',  # Use /dev/serial0 for the Raspberry Pi UART
    baudrate=9600,        # Adjust baudrate to match your barcode reader's settings
    timeout=1             # Timeout in seconds for read operations
)

def read_from_scanner():
    try:
        while True:
            if ser.in_waiting > 0:
                # Read data from the barcode scanner
                data = ser.readline()
                if data:
                    print(f"Barcode Data: {data}")
    except KeyboardInterrupt:
        print("Program interrupted. Closing..")
    finally:
        ser.close()

if __name__ == "__main__":
    read_from_scanner()

报错信息

Traceback (most recent call last):
  File "/home/pi/qrcode_project/qrcode_rpi/t1.py", line 24, in <module>
    read_from_scanner()
  File "/home/pi/qrcode_project/qrcode_rpi/t1.py", line 13, in read_from_scanner
    if ser.in_waiting > 0:
       ^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 549, in in_waiting
    s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 5] Input/output error

解决方案

1. 修复树莓派UART的映射冲突

树莓派4的serial0默认可能和蓝牙共享硬件UART,导致串口不稳定:

  • 执行sudo raspi-config,进入Interface Options → Serial Port,选择「否」关闭串口控制台,选择「是」开启串口硬件支持
  • 编辑/boot/config.txt,添加以下内容:
    dtoverlay=disable-bt
    enable_uart=1
    
  • 重启树莓派:sudo reboot

2. 确保串口参数完全匹配GM875默认配置

GM875默认参数为9600波特率、8位数据位、1停止位、无校验(8N1),需在代码中明确指定,避免参数不匹配导致乱码:
修改后的串口初始化代码:

ser = serial.Serial(
    port='/dev/serial0',
    baudrate=9600,
    bytesize=serial.EIGHTBITS,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    timeout=1
)

3. 检查硬件连接与电平

  • 确认交叉连接:GM875的TX引脚接树莓派的RX(GPIO15),GM875的RX引脚接树莓派的TX(GPIO14),必须共地(GND引脚相连)
  • GM875支持3.3V/5V电平,树莓派UART是3.3V,建议使用3.3V供电,避免电平不匹配损坏硬件或干扰信号

4. 代码优化:捕获IO错误并重连

in_waiting调用可能触发IO错误,可添加异常捕获逻辑,实现自动重连:

import serial
import time

def init_serial():
    try:
        ser = serial.Serial(
            port='/dev/serial0',
            baudrate=9600,
            bytesize=serial.EIGHTBITS,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            timeout=1
        )
        return ser
    except Exception as e:
        print(f"Failed to open serial port: {e}")
        return None

def read_from_scanner():
    ser = init_serial()
    if not ser:
        return
    try:
        while True:
            try:
                # 直接读取,避免in_waiting的IO错误
                data = ser.read_until(b'\n')  # 假设扫描器返回以换行结尾的数据
                if data:
                    # 过滤无效的空字节
                    cleaned_data = data.strip(b'\x00').decode('utf-8').strip()
                    if cleaned_data:
                        print(f"Barcode Data: {cleaned_data}")
            except OSError as e:
                print(f"IO Error occurred: {e}, reconnecting...")
                ser.close()
                time.sleep(2)
                ser = init_serial()
                if not ser:
                    break
    except KeyboardInterrupt:
        print("Program interrupted. Closing..")
    finally:
        if ser and ser.is_open:
            ser.close()

if __name__ == "__main__":
    read_from_scanner()

5. 排查硬件干扰

  • 更换质量较好的杜邦线,避免信号衰减或干扰
  • 若条件允许,用逻辑分析仪或示波器检测UART信号波形,确认数据传输是否稳定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 13:00:12