读取COM4端口传感器数据写入CSV及中途数据丢失问题求解
串口数据写入CSV及异常中断数据丢失问题解决方案
写入CSV的实现方法
Python自带的csv模块就可以满足高效写入需求,无需引入额外依赖,针对串口输出的字节数据,只需要先做解码处理即可写入CSV。
中途停止脚本数据丢失的原因
写入文件的内容默认会先存放在操作系统的内存缓冲区中,只有缓冲区满、主动调用flush、或者文件对象正常关闭时,内容才会写入磁盘。如果你直接强制终止脚本,缓冲区的内容没有落地到磁盘,就会出现所有修改丢失的情况,包括提前写入的表头。
解决办法
- 开启文件行缓冲:打开文件时设置
buffering=1,每写入一行就自动刷入磁盘,适合传感器这类低频数据采集场景 - 使用
with上下文管理器管理文件对象,脚本正常退出时会自动关闭文件,触发缓冲区刷入 - 捕获
KeyboardInterrupt中断(即Ctrl+C停止操作),走正常的资源关闭逻辑,避免进程直接被杀死
完整可运行代码
import serial import csv from datetime import datetime # 串口配置,波特率需和传感器输出参数一致 ser = serial.Serial('COM4', baudrate=9600) # 数据保存路径 SAVE_PATH = "sensor_temp.csv" if __name__ == "__main__": # 行缓冲模式打开CSV文件,newline=''避免csv模块额外写入空行 with open(SAVE_PATH, 'w', newline='', encoding='utf-8', buffering=1) as f: csv_writer = csv.writer(f) # 写入表头,可根据实际字段修改 csv_writer.writerow(["采集时间", "温度值"]) try: while True: if ser.in_waiting > 0: # 解码串口字节数据,忽略异常编码,去除首尾空白/换行符 temp_val = ser.readline().decode('utf-8', errors='ignore').strip() # 写入带时间戳的行 csv_writer.writerow([ datetime.now().strftime("%Y-%m-%d %H:%M:%S"), temp_val ]) except KeyboardInterrupt: # 正常关闭串口资源 ser.close() print("采集已停止,数据已保存至", SAVE_PATH)
额外说明
- 如果需要后续采集追加数据不覆盖历史数据,把打开文件的模式从
'w'(覆盖写)改为'a'(追加写)即可 - 如果传感器输出是多列逗号分隔的数据,可以先对解码后的字符串做
split(',')拆分,直接传入writerow实现多列写入 - 高频采集场景下可以关闭行缓冲,改为每累计N条数据后手动调用
f.flush()刷入磁盘,减少IO开销
内容的提问来源于stack exchange,提问作者Morten Nissov
相关产品推荐
相关产品推荐

