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

树莓派UART串口数据分文件存储时文件大小归零问题求解

串口批量数据独立存储解决方案

原代码问题根因

  • 文件名仅在脚本启动时生成一次,所有批次数据都会写入同一个文件,不符合每次传输存独立文件的需求
  • 每次检测到串口有数据时,都使用w(覆盖写入)模式打开文件,新写入的内容会直接清空之前已写入的所有数据,这是文件大小先增长后归零的核心原因
  • 900KB的串口数据会分多批到达缓冲区,原代码每次仅读取当前缓冲区的片段,反复覆盖写入导致最终仅保留最后一段数据甚至空内容
  • text_file.close()放在数据检测分支外,首次循环如果没有串口数据,变量未定义会直接抛出异常
  • 没有传输批次判断逻辑,无法区分两次独立的传输,无法自动为新批次创建新文件

修复后实现代码

方案1:时间戳命名 + 空闲超时判断传输边界

该方案通过设置串口空闲超时判定一次传输是否结束,连续指定时间无数据到来则认为当前批次传输完成,下一次数据到来自动创建新的时间戳命名文件。

import serial
import time 
import datetime
import os

# 串口配置,根据实际参数调整
ser = serial.Serial(
    port='/dev/serial0', 
    baudrate=115200, 
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS, 
    rtscts=1
)

# 配置项
IDLE_TIMEOUT = 2  # 空闲超时时间(秒),大于传输中数据包间隔、小于两次传输的最小间隔即可
SAVE_DIR = os.path.dirname(__file__)  # 文件存储目录

# 运行时变量
current_file = None
last_receive_time = 0

while True:
    if ser.inWaiting() > 0:
        # 新批次传输开始,创建新文件
        if current_file is None:
            file_name = datetime.datetime.now().strftime("%Y-%m-%dT%H.%M.%S") + ".txt"
            output_path = os.path.join(SAVE_DIR, file_name)
            current_file = open(output_path, 'wb')  # 直接写二进制避免解码出错,不需要转ASCII可自行调整
        
        # 读取缓冲区数据写入文件
        data = ser.read(ser.inWaiting())
        current_file.write(data)
        current_file.flush()
        last_receive_time = time.time()
    else:
        # 空闲超时,关闭当前批次文件
        if current_file is not None and (time.time() - last_receive_time) > IDLE_TIMEOUT:
            current_file.close()
            current_file = None
    
    time.sleep(0.01)

方案2:递增序号命名

如果需要用1.txt、2.txt这类递增序号命名,替换新文件创建逻辑即可,以下是支持脚本重启后序号延续的实现:

# 替换方案1中【新批次传输开始,创建新文件】部分的代码即可
if current_file is None:
    # 读取当前目录下最大的序号文件,避免重启后覆盖
    max_num = 0
    for f in os.listdir(SAVE_DIR):
        if f.endswith('.txt') and f.split('.')[0].isdigit():
            num = int(f.split('.')[0])
            if num > max_num:
                max_num = num
    new_num = max_num + 1
    output_path = os.path.join(SAVE_DIR, f"{new_num}.txt")
    current_file = open(output_path, 'wb')

代码说明

  • 不需要将串口数据转ASCII的可直接保留二进制写入逻辑,避免特殊字符解码报错
  • IDLE_TIMEOUT参数可根据实际传输情况调整:如果传输过程中数据包间隔最大为0.5秒,两次传输最小间隔为10秒,设置为1~5秒区间即可
  • 脚本可配置为树莓派开机自启,无需人工干预即可全自动运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 23:36:03