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

使用PySerial.write()发送数据时丢失字节的问题求助

PySerial向STM单片机发送命令时出现字节丢失问题

问题描述

使用Python的PySerial库向STM单片机发送命令时,频繁出现字节丢失/错乱的情况,约半数回显异常,但用Putty发送相同命令完全正常。已排查硬件故障,更换操作系统、编译为可执行文件均无效。

示例代码

import serial

stm_serial_port = '/dev/ttyUSB0'
stm_baud_rate = 460800
ser_stm = serial.Serial(stm_serial_port, stm_baud_rate, timeout=1)

cmd = "initc 1 0.6 50 1000 1000 1000 1000 100 100"
encoded_cmd = str.encode(cmd+"\r\n")

def flush_buffers():
    # 原代码未定义此函数,需补充缓冲区清空逻辑
    ser_stm.reset_input_buffer()
    ser_stm.reset_output_buffer()

for i in range(100):
    flush_buffers()
    print('Cmd  : '+cmd)
    ser_stm.write(encoded_cmd)
    feedback = ser_stm.readline().decode('utf-8')
    print('Echo : '+feedback)
    while(True):
        data = ser_stm.readline().decode('utf-8')
        if 'sh>' in data:
            break

异常回显示例

Cmd : initc 1 0.6 50 1000 1000 1000 1000 100
Echo : intc 0.6 50 1000 1000 1000 1000 100

Cmd : initc 1 0.6 50 1000 1000 1000 1000 100
Echo : initc 1 0.650 1000 1000 1000 1000 100

Cmd : initc 1 0.6 50 1000 1000 1000 1000 100
Echo : initc 1 0.6 50 1000 1000 00 1000 100

Cmd : initc 1 0.6 50 1000 1000 1000 1000 100
Echo : initc 1 0.6 50 10001000 1000 1000 100


问题原因及解决方法

1. 缓冲区刷新逻辑缺失

原代码中flush_buffers()未实现实际的缓冲区清空操作,残留的历史数据会干扰当前通信。必须显式清空串口的输入输出缓冲区:

def flush_buffers():
    ser_stm.reset_input_buffer()  # 清空接收缓冲区
    ser_stm.reset_output_buffer() # 清空发送缓冲区

2. 高波特率下发送时序不匹配

460800属于高波特率,PySerial默认发送后不会等待数据完全发送完毕就开始读取,导致单片机端接收不完整。需在write后等待发送缓冲区为空:

ser_stm.write(encoded_cmd)
ser_stm.flush()  # 阻塞直到所有数据发送完成

3. 串口流控参数不匹配

Putty可能默认启用了硬件流控(RTS/CTS),而PySerial默认关闭。需显式配置流控参数:

ser_stm = serial.Serial(
    port=stm_serial_port,
    baudrate=stm_baud_rate,
    timeout=1,
    rtscts=True  # 启用硬件流控,匹配Putty设置
)

若单片机未配置硬件流控,可尝试启用软件流控:

ser_stm = serial.Serial(
    port=stm_serial_port,
    baudrate=stm_baud_rate,
    timeout=1,
    xonxoff=True
)

4. 读取时序过快

发送命令后立即调用readline(),可能单片机还未完成回显发送。可增加短暂延迟或循环读取确保获取完整数据:

import time

ser_stm.write(encoded_cmd)
ser_stm.flush()
time.sleep(0.01)  # 根据实际通信延迟调整,如10ms
feedback = ser_stm.readline().decode('utf-8').strip()

5. 换行符格式不匹配

部分设备仅识别\n而非\r\n,可尝试修改发送的换行符:

encoded_cmd = str.encode(cmd+"\n")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:28:22