如何在CSV文件首行写入CAN总线测量数据与元数据
CAN总线数据CSV存储解决方案
核心思路
先从首条CAN消息中提取并保存元数据,同时将所有三轴测量数据按顺序存入列表;写入CSV时,先输出表头,第一行同时写入第一组三轴数据与元数据,后续行仅填充三轴数据,元数据列留空。
完整代码实现
import can import csv # 初始化CAN总线(根据硬件配置调整参数,比如bustype、channel、bitrate) bus = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000) # 存储三轴测量数据的列表 x_data = [] y_data = [] z_data = [] # 存储元数据的变量 meta_1 = None meta_2 = None # 标记是否为第一条测量消息 first_msg_received = False # 接收1024组三轴数据 for _ in range(1024): msg = bus.recv() # 解析CAN消息(请根据实际消息格式调整数据提取逻辑) raw_data = msg.data if not first_msg_received: # 从首条消息提取元数据,示例假设前4字节为元数据,后6字节为三轴数据 meta_1 = int.from_bytes(raw_data[0:2], byteorder='little') meta_2 = int.from_bytes(raw_data[2:4], byteorder='little') x_val = int.from_bytes(raw_data[4:6], byteorder='little') y_val = int.from_bytes(raw_data[6:8], byteorder='little') z_val = int.from_bytes(raw_data[8:10], byteorder='little') first_msg_received = True else: # 普通消息仅提取三轴数据 x_val = int.from_bytes(raw_data[0:2], byteorder='little') y_val = int.from_bytes(raw_data[2:4], byteorder='little') z_val = int.from_bytes(raw_data[4:6], byteorder='little') # 将数据加入对应列表 x_data.append(x_val) y_data.append(y_val) z_data.append(z_val) # 写入CSV文件 with open('can_measurements.csv', 'w', newline='', encoding='utf-8') as f: # 定义表头 headers = ['x data', 'y data', 'z data', 'meta data 1', 'meta data 2'] writer = csv.DictWriter(f, fieldnames=headers) # 写入表头 writer.writeheader() # 写入第一行(带元数据) writer.writerow({ 'x data': x_data[0], 'y data': y_data[0], 'z data': z_data[0], 'meta data 1': meta_1, 'meta data 2': meta_2 }) # 写入剩余999行(仅三轴数据,元数据列留空) for idx in range(1, 1024): writer.writerow({ 'x data': x_data[idx], 'y data': y_data[idx], 'z data': z_data[idx], 'meta data 1': '', 'meta data 2': '' })
注意事项
- CAN消息解析:代码中的数据提取逻辑是示例,需根据你实际的CAN消息协议调整字节位置、数据类型(整数/浮点)和字节顺序。
- CSV写入细节:使用
csv.DictWriter可以精准匹配表头和数据,元数据列留空通过传入空字符串实现,符合CSV格式要求。 - CAN总线初始化:根据你的硬件(比如USB-CAN适配器)调整
bus的初始化参数,比如bustype设为'usb2can'等。
内容的提问来源于stack exchange,提问作者melfie
相关产品推荐
相关产品推荐

