62.5Hz32路串口传感器数据高速实时绘图方案咨询
高速实时数据绘图实现需求
场景数据特征
- 数据通过串口传入,到达频率为62.5Hz
- 数据对应32个传感器的采集值,需绘制32条数值随时间变化的曲线
- 数据总吞吐量为32点*62.5Hz = 2000点/秒
核心约束
- 完整保存所有从串口接收到的原始数据,无丢失
- 可正常绘制数据整体趋势,允许采用跳点绘制、均值降采样、丢弃过旧数据仅保留近期数据等优化手段
现有实现的问题
当前编写的绘图循环运行速率低于62.5Hz,会导致串口传入的部分数据丢失。
使用随机数据模拟串口输入的测试代码如下:
import numpy as np import time import matplotlib.pyplot as plt # 速率调试记录 hz_ = [] # 循环速率记录列表 time_=[] # 时间轴记录列表,用于绘制速率变化图 # 全量存储所有生成的数据 store_data = np.zeros((1, 33)) # 待绘制数据切片 to_plot = np.zeros((1, 33)) # 每条曲线的配色 colours = [f"C{i}" for i in range (1,33)] fig,ax = plt.subplots(1,1, figsize=(10,8)) ax.set_xlabel('time(s)') ax.set_ylabel('y') ax.set_ylim([0, 300]) ax.set_xlim([0, 200]) start_time = time.time() for i in range (100): loop_time = time.time() # 生成模拟数据:第0列为时间戳,第1-32列为传感器数值 data = np.random.randint(1,255,(1,32)).astype(float) # 模拟62.5Hz频率到达的串口数据 data = np.insert(data, 0, time.time()-start_time).reshape(1,33) # 首列插入相对时间 store_data = np.append(store_data, data , axis=0) to_plot = store_data[-100:,] for i in range(1, to_plot.shape[1]): ax.plot(to_plot[:,0], to_plot[:,i],c = colours[i-1], marker=(5, 2), linewidth=0, label=i) #ax.lines = ax.lines[-33:] # 清除旧绘图元素的优化方案 fig.canvas.draw() fig.canvas.flush_events() Hz = 1/(time.time()-loop_time) # 记录速率变化 hz_.append(Hz) time_.append( time.time()-start_time) print(1/(time.time()-loop_time), "Hz - 程序当前循环频率") # 绘制速率随时间变化的调试图 fig,ax = plt.subplots(1,1, figsize=(10,8)) fig.suptitle('循环速率随运行时间下降趋势', fontsize=20) ax.set_xlabel('time(s)') ax.set_ylabel('Hz') ax.plot(time_, hz_) fig.show()
测试结果显示程序循环速率随运行时间不断下降,对应速率变化趋势如下图所示:
已尝试的优化手段:通过如下代码移除旧的绘图元素提升绘图速率
ax.lines = ax.lines[-33:]
该方法虽有一定提速效果,但程序运行速率仍达不到串口数据的采集速率要求,优化后速率变化如下图所示:
方案咨询
接受任意可行的开发库或实现方案,只要能保证全量采集串口数据不丢失、同时可绘制出数据的整体趋势即可,咨询是否可以采用数据采集与绘图并行运行的架构实现该需求。
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

