ASM330LHH加速度计数据无法按6667Hz频率写入CSV文件求助
问题核心原因
你当前的代码性能瓶颈主要出在以下几个地方,和CSV写入本身的性能上限无关:
- 每次写入都重复打开/关闭文件:主循环中每写一行数据就执行一次
open()和close()操作,文件句柄的创建和销毁是极耗时的IO操作,直接把写入速度拉到了Hz级。 - 未使用传感器的FIFO缓冲:你已经在寄存器配置中开启了FIFO,但代码完全没有读取FIFO队列,而是每次直接读实时采样寄存器。6667Hz的采样率意味着每150微秒就会产生一条新数据,而你单次读6个轴需要发起12次I2C读请求,I2C通讯的延迟根本跟不上这个速度,大部分采样数据都被FIFO的覆盖规则冲掉了。
- 单条写入无批量优化:csv模块默认行缓冲,你每次写一行就强制flush(关闭文件触发),完全没有利用批量写入的性能优势。
- 线程同步逻辑低效:用全局变量做线程间同步没有加锁,不仅会产生数据竞争风险,还会额外拖慢运行效率。
优化方案
1. 优化文件IO逻辑
采集开始前一次性打开CSV文件,采集结束后再关闭,避免每次写入都开关文件:
# 采集开始前打开文件 csv_file = open(aquire_folder + "acc.csv", 'a', newline='') writeracc = csv.writer(csv_file) # 写表头 if contador < 1: writeracc.writerow(headeracc) contador = 1 # 主循环写入 while 1: if luz: # 写入逻辑 ... # 采集结束后再关闭 csv_file.close()
2. 批量读取FIFO数据
配置FIFO阈值中断,当FIFO中攒够N条采样数据(比如100条)时一次性读出所有FIFO内的采样数据,大幅降低I2C通讯的频次开销,避免丢数。
3. 批量写入CSV
不要每读一条就写一条,将一批采样数据先暂存到内存列表中,攒到指定数量后一次性调用writerows()批量写入:
buffer = [] BATCH_SIZE = 1000 while 1: if luz and acc: acc = False buffer.append([ax,ay,az,tempo]) # 攒够一批再写入 if len(buffer) >= BATCH_SIZE: writeracc.writerows(buffer) buffer.clear() # 程序退出前把剩余缓冲的数据写完 if buffer: writeracc.writerows(buffer)
4. 优化线程间通讯
用queue.Queue替代全局变量做线程间的数据传输,既避免数据竞争,也能提升同步效率。
优化后完全可以跑满6667Hz的采样率,这个速率下每秒产生的CSV数据量不到100KB,普通存储设备完全可以支撑。
内容的提问来源于stack exchange,提问作者Manuel Orsini
相关产品推荐
相关产品推荐

