PySerial读取十六进制数据异常:仅获取部分响应的问题排查
串口读取数据丢失问题排查与解决
问题场景
使用Python 3.12 + PySerial 3.5读取设备十六进制响应时,仅获取到b'\x1f\n'(十六进制1F0A),但用RealTerm等串口工具能正常得到预期响应b'\x1F\xA0\x26'。相关代码及运行结果如下:
原代码
import binascii import serial ser = serial.Serial(port='COM4',baudrate=9600,bytesize=8,parity="N",stopbits=1,timeout=1) print(ser.name) packet = b"\x1F" ser.write(packet) response = ser.read_until(size=3) print(response) print(response.hex()) print(binascii.hexlify(response))
运行结果
COM4 b'\x1f\n' 1f0a b'1f0a'
核心原因分析
read_until方法的行为误解:read_until(size=3)并非读取固定3字节,而是遇到默认终止符b'\n'就提前返回,最多读取3字节。设备返回的第二个字节恰好是0x0A(即\n),导致读取提前终止,未获取到第三个字节。- 串口配置不匹配:RealTerm可能启用了流控制(硬件/软件)或其他隐藏配置,而Python代码中未同步设置,导致设备发送数据时被阻塞。
- 响应延迟:设备处理命令需要时间,原代码的1秒超时可能不足以等待设备发送完所有3字节数据。
解决方法
1. 替换read_until为固定长度读取
如果明确知道响应是固定3字节,直接使用ser.read(3)替代read_until,该方法会等待直到读取到指定字节数(或超时):
修改后的代码片段:
# 替换原response行 response = ser.read(3)
2. 同步RealTerm的串口配置
打开RealTerm的串口设置面板,检查以下参数并同步到Python代码中:
- 流控制:如果RealTerm启用了RTS/CTS硬件流控制,在
serial.Serial中添加rtscts=True;如果是XON/XOFF软件流控制,添加xonxoff=True。 - 其他参数:确认波特率、数据位、奇偶校验、停止位完全一致(原代码已设置8N1,需和RealTerm匹配)。
示例配置(假设启用RTS/CTS):
ser = serial.Serial( port='COM4', baudrate=9600, bytesize=8, parity="N", stopbits=1, timeout=2, # 适当延长超时 rtscts=True )
3. 增加响应延迟与缓冲区清空
在发送命令后,给设备预留处理时间,并清空输入缓冲区避免残留数据干扰:
import time # ... 串口初始化代码 ... ser.flushInput() # 清空输入缓冲区 ser.write(packet) time.sleep(0.1) # 等待设备处理命令并发送响应 response = ser.read(3)
4. 验证修改结果
修改后运行代码,若配置正确,应能输出预期的b'\x1f\xa0\x26',对应的十六进制为1fa026。
内容的提问来源于stack exchange,提问作者daveya17
相关产品推荐
相关产品推荐

