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

树莓派Python环境下如何确认串口写入完成以解决丢包问题

树莓派Python环境下如何确认串口写入完成以解决丢包问题

嗨,我完全懂你的困扰——直接写串口会丢字符,加延迟能凑合用但总觉得不优雅,想要精准判断串口写入完成对吧?这其实是因为pyserial的write()方法默认只是把数据放到输出缓冲区就返回了,并不会等待硬件真正把数据发送完毕,所以如果后续操作衔接太急,就容易出现数据丢包的情况。

给你两个靠谱的解决办法,不用依赖固定延迟:

方法一:用flush()阻塞等待写入完成

pyserial提供了ser.flush()方法,它会一直阻塞到输出缓冲区里的所有数据都被串口硬件发送完毕,相当于帮你自动“等”到写入真的完成。你只需要在每次ser.write(data)之后加上这一行就行:

ser.write(data)
ser.flush()  # 等待串口把数据发完再继续

方法二:轮询out_waiting状态(非阻塞可选)

如果你不想用阻塞方式,可以循环检查ser.out_waiting属性——这个属性代表当前输出缓冲区中还未发送的字节数,直到它变成0,就说明所有数据都发送完成了:

ser.write(data)
while ser.out_waiting > 0:
    pass  # 循环等待缓冲区清空

另外还要提醒你,你的代码里有缩进错误,except和finally块下面的代码没有正确缩进,这会导致语法错误,得修正才能正常运行。下面是修正缩进并加入flush()后的完整代码:

import socket
import serial
from threading import Thread
from datetime import datetime

def on_new_client(client_socket, addr):
    try:
        while True:
            client_socket.settimeout(60)
            data = client_socket.recv(1)
            ser.write(data)
            ser.flush()  # 新增:等待串口写入完成
            client_socket.settimeout(None)
            if not data:
                print(f'Client {addr} disconnected')
                break
            Ctime = datetime.now().strftime("%H:%M:%S")
            print(f"Address: {addr},Time:{Ctime}, Data: {data}")
    except socket.timeout:
        print(f"Connection timed out for {addr}")
    except Exception as e:
        print(f"Error with client {addr}: {e}")
    finally:
        client_socket.close()
        print(f"Connection closed for {addr}")

def main():
    global ser
    ser = serial.Serial(
        port='/dev/ttyS0',
        baudrate=9600,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.EIGHTBITS
    )

    host1 = '192.168.176.248'
    port1 = 4002
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host1, port1))
    s.listen(5)
    print(f"Server started on {host1}:{port1}")
    while True:
        client_socket,addr = s.accept()
        print(f"New connection from: {addr}")
        thread = Thread(target=on_new_client, args=(client_socket, addr), daemon=True)  # Mark thread as daemon
        thread.start()  # Start the thread

if __name__ == '__main__':
    main()

这样修改后,你就不用再加额外的延迟,串口写入完成后才会继续执行后续代码,应该就能解决丢字符的问题了。

备注:内容来源于stack exchange,提问作者Sathish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:30:28