杰瑞科技汇

python pyserial 清空

清空串口缓冲区(发送/接收区)

这是最常见的需求,通常发生在以下情况:

python pyserial 清空-图1
(图片来源网络,侵删)
  • 在发送新命令之前,确保没有残留的旧数据干扰。
  • 在开始读取新数据之前,丢弃掉之前已经处理完或无用的数据。

pyserialSerial 对象提供了两个专门的方法来实现这一点:

  1. serial.Serial.reset_input_buffer(): 清空输入缓冲区(即从设备读取到但尚未被 Python 读取的数据)。
  2. serial.Serial.reset_output_buffer(): 清空输出缓冲区(即已通过 Python 写入串口,但尚未被发送设备完全处理的数据)。

一个更彻底的、同时清空两个缓冲区的方法是:

  1. serial.Serial.reset_output_buffer(): 重置串口,它会将所有内部缓冲区(输入和输出)清空,并将串口线(DTR - Data Terminal Ready)的状态重置为开启,这是最常用、最推荐的“清空”操作。

示例代码

import serial
import time
# --- 1. 配置串口 ---
# 请根据你的实际情况修改 'COM3' 和 9600
# 在 Linux/Mac 上可能是 '/dev/ttyUSB0' 或 '/dev/ttyACM0'
PORT = 'COM3'
BAUDRATE = 9600
try:
    # 打开串口
    ser = serial.Serial(PORT, BAUDRATE, timeout=1)
    print(f"串口 {ser.name} 已成功打开。")
    # --- 2. 清空串口(推荐方法) ---
    # 在发送或接收数据之前,先重置串口,确保一个干净的通信环境
    print("\n正在重置串口(清空所有缓冲区)...")
    ser.reset_input_buffer()  # 清空输入缓冲区
    ser.reset_output_buffer() # 清空输出缓冲区
    # 或者直接使用 ser.reset(),它等同于上面两行操作
    # ser.reset() 
    print("串口已重置。")
    # --- 3. 发送数据 ---
    command_to_send = b'GET_DATA\n'  # 发送一个命令,以 b 开头表示字节串
    print(f"\n正在发送数据: {command_to_send}")
    ser.write(command_to_send)
    time.sleep(0.5) # 给设备一些处理时间
    # --- 4. 接收数据 ---
    # 在读取之前,再次清空输入缓冲区是个好习惯,以防有意外数据
    ser.reset_input_buffer() 
    print("正在等待接收数据...")
    # 读取一行数据,直到遇到换行符 '\n' 或超时
    received_data = ser.readline()
    if received_data:
        print(f"成功接收数据: {received_data}")
    else:
        print("未接收到任何数据(可能已超时)。")
except serial.SerialException as e:
    print(f"无法打开串口 {PORT}: {e}")
except Exception as e:
    print(f"发生错误: {e}")
finally:
    # --- 5. 关闭串口 ---
    if 'ser' in locals() and ser.is_open:
        print("\n正在关闭串口...")
        ser.close()
        print("串口已关闭。")

清空软件缓冲区(Python 端)

你读取的数据可能包含很多无用的前导字符(比如设备启动时的信息、调试信息等),你可能想只关心最后的有效数据。

这时,你可以在 Python 代码层面循环读取并丢弃数据,直到你找到你想要的起始标记。

python pyserial 清空-图2
(图片来源网络,侵删)

示例代码:丢弃所有数据直到找到特定标记

import serial
import time
PORT = 'COM3'
BAUDRATE = 9600
START_MARKER = b'START_DATA' # 定义我们期望的数据起始标记
ser = serial.Serial(PORT, BAUDRATE, timeout=0.1) # 设置一个较短的timeout以便快速循环
try:
    print("正在等待数据起始标记...")
    while True:
        # 读取一个字节
        byte = ser.read(1)
        if not byte: # 如果超时,返回空字节
            continue
        # 检查这个字节是否是我们标记的第一个字节
        if byte == START_MARKER[0]:
            # 如果是,尝试读取剩余的标记部分
            marker = byte
            for i in range(1, len(START_MARKER)):
                next_byte = ser.read(1)
                if not next_byte:
                    break # 超时,放弃本次匹配
                marker += next_byte
                if next_byte != START_MARKER[i]:
                    break # 不匹配,放弃
            # 如果我们成功匹配了整个标记
            if marker == START_MARKER:
                print("找到起始标记!")
                # 我们可以开始读取我们真正想要的数据了
                # 读取一行
                actual_data = ser.readline()
                print(f"接收到有效数据: {actual_data}")
                break # 退出循环
except serial.SerialException as e:
    print(f"串口错误: {e}")
finally:
    if ser.is_open:
        ser.close()
        print("串口已关闭。")

清空终端/控制台输出

有时候你可能想说的“清空”是指清空你在 Python IDE(如 PyCharm, VS Code)或命令行终端上打印的输出。

这和 pyserial 无关,是 Python 的标准操作。

示例代码

import os
import time
# 方法1:使用 os.system() 调用系统命令
# 在 Windows 上
os.system('cls')
# 在 Linux 或 macOS 上
# os.system('clear')
# 方法2:打印多行空行(跨平台,但不够“干净”)
print("\n" * 50)
# 方法3:使用 ANSI 转义码(更现代、跨平台)
# \033[2J 清屏,\033[H 光标移到左上角
print('\033[2J\033[H', end='')
print("屏幕已清空。")

总结与最佳实践

需求 推荐方法 说明
清空硬件缓冲区(发送/接收区) ser.reset_input_buffer()
ser.reset_output_buffer()
ser.reset()
最常用,在每次通信开始前或中间需要重新同步时调用,确保数据干净。ser.reset() 是最彻底的选择。
丢弃无用数据 ser.read(数据长度)ser.readline() 并不保存结果 在读取有效数据前,循环读取并丢弃数据,直到找到特定标记(如 b'START')。
清空软件控制台 os.system('cls' or 'clear') 或 ANSI 转义码 pyserial 无关,用于管理你的程序输出界面。

核心建议:

在进行串口通信时,养成一个良好的习惯:在发送关键指令之前,先调用 ser.reset() 或至少 ser.reset_input_buffer(),这可以极大地避免因数据错位、残留数据等导致的各种奇怪问题。

python pyserial 清空-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇