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

如何将串口读取的二进制数据转换为有效ASCII字符串?

串口秤数据解码问题及解决方法

问题描述

通过USB-TTL将秤的UART连接至树莓派,秤以8位ASCII块形式发送数据。使用serial库读取串口时得到b'\xfb\x9b\xa3...'这类二进制数据,尝试ASCII解码触发UnicodeDecodeError,无法获取预期的'ST, GS 0.0 g'有效字符串。此前用USR-TCP232-T2转换器可正常获取类似'S 0.0 g\nST, GS 0.0 g...'的数据,用binascii.hexlify处理后解码结果仍不符合预期。

附操作代码及错误信息:

>>> ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=0.5)
>>> ser.isOpen()
True
>>> ser.inWaiting()
4095
>>> ser.read()
b'\xfb'
>>> ser.read(200)
b'\xfb\x9b\xa3\x8d\x9b\xbf1\xbf\xe5\xac\x00V\xd5Ze\xfd\xbf\xbf\xbfL\xa3\x8d\x9b\xbf1\xbf\xe5\xeb\x00V\xd5Ze\xfd\xbf\xbf\xbf\x93\xa3\x8d\x9b\xfc1\xbf\xe5\xeb\x00V\xd5Ze\xfd\xbf\xbf\xbf\x93\xa3\x8d\x9b\xbf1\xfc\xe5\xeb\x00V\x15Ze\xfd\xbf\xbf\xbf\x93\xa3\x8d\x9b\xbf\xc4\xbf\xe5\xeb\x00V\xd5Ze\xfd\xbf\xbf\xbf\x93\x8c\x8d\x9b\xbf1\xbf\xe5\xeb\x00V\xd5Ze\xfd\xbf\xbf\xbf\x93\xa3\x8d\x9b\xbf\xc4\xbf\xe5\xeb\x00V\xd5Ze\xfd\xfc\xbf\xbf\x93\xa3\x8d\x9b\xbf1\xbf\xe5\xeb\x00V\xd5\x1a\\V\xfb\xfb\xfb\x9b\xa3\x8d\x9b\xbf1\xfc\xe5\xeb\x00V\xd5Ze\xfd\xbf\xfc\xbf\x93\xa3\x8d\x9b\xbf1\xbf\xe5\xeb\x00V\xd5Z\xc9\xfd\xbf\xbf\xbf\x93\xa3\x8d\x9b\xbf1\xbf\x94\xeb\x00V\x15Ze\xfd\xbf\xbf\xbf\x93'
>>> ser.read(200).decode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa3 in position 0: ordinal not in range(128)

解决步骤

  • 匹配完整串口参数:USR-TCP232-T2能正常工作,说明秤的串口参数正确,但树莓派端可能遗漏了奇偶校验、停止位等配置。工业秤常用偶校验,调整serial初始化代码:

    import serial
    ser = serial.Serial(
        port='/dev/ttyUSB1',
        baudrate=9600,
        parity=serial.PARITY_EVEN,
        stopbits=serial.STOPBITS_1,
        bytesize=serial.EIGHTBITS,
        timeout=0.5
    )
    

    可根据秤的说明书微调奇偶校验和停止位参数。

  • 用Latin-1解码并过滤无效字符:秤发送的8位ASCII包含超出0-127范围的控制字符,ascii解码会失败。用latin-1解码(每个字节对应唯一Unicode字符,无报错)后过滤不可打印字符:

    raw_data = ser.read(200)
    decoded = raw_data.decode('latin-1')
    # 提取仅打印字符
    valid_str = ''.join([c for c in decoded if c.isprintable()])
    print(valid_str)
    

    此方法可直接提取出'ST, GS 0.0 g'这类有效内容。

  • 排查硬件兼容性:USB-TTL模块可能存在电平不匹配(秤为RS232电平,模块为TTL电平需转换)或接线错误。确认TX接RX、RX接TX、GND共地,或更换质量可靠的USB-TTL模块测试。

  • 解析数据帧结构:秤发送的是块数据,可能含帧头(如0xfb)、帧尾标识。先定位帧边界再提取有效数据:

    buffer = b''
    while True:
        chunk = ser.read(1024)
        if not chunk:
            break
        buffer += chunk
        # 假设帧尾为换行符,根据实际有效数据调整
        if b'\n' in buffer:
            frames = buffer.split(b'\n')
            for frame in frames[:-1]:
                # 跳过帧头控制字符,解码有效部分
                decoded_frame = frame.decode('latin-1').strip('\xfb\x9b\xa3')
                print(decoded_frame)
            buffer = frames[-1]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:25:25