在 while 循环中绘制或 time.sleep 或 csv 保存数据会导致感测数据和从力传感器读取数据之间存在滞后

Posted

技术标签:

【中文标题】在 while 循环中绘制或 time.sleep 或 csv 保存数据会导致感测数据和从力传感器读取数据之间存在滞后【英文标题】:Plotting or time.sleep or csv saving datas in a while loop induces lags between sensed and read datas from a force sensor 【发布时间】:2021-12-27 15:04:43 【问题描述】:

我对使用 Python 很陌生。我需要它从插入 COMPORT (6) 的力传感器获取串行数据。使用下面的代码,我可以毫无问题地将数据存储在列表中并在之后保存。我还可以打印每个数据而不会注意到任何延迟。

但是,当我尝试在我的 while 循环中实现绘图时,在我触摸传感器和写入数据的时间(从几秒到几十秒)之间会出现一个相当烦人的变化。我首先认为这是因为 matplotlib 是一个消耗内存的库,但即使我添加了简单的行“time.sleep(0.00001)”,与采集速率(60 FPS)相比,这是一个非常短的暂停,我得到了相同的结果滞后。我还尝试将数据保存在 csv 文件中,并使用多进程在不同的函数中绘制数据,但即使保存数据也会触发滞后。

这是有问题的,因为可视化我的实时数据是我实验的重要组成部分。 有人可以帮我解决这个特定问题吗?

非常感谢。

import serial
import struct
import platform
import multiprocessing

import time
import numpy as np
import csv
# from pylab import *
import matplotlib.pyplot as plt



class MeasurementConverter:
    def convertValue(self, bytes):
        pass


class ForceMeasurementConverterKG(MeasurementConverter):
    def __init__(self, F_n, S_n, u_e):
        self.F_n = F_n
        self.S_n = S_n
        self.u_e = u_e

    def convertValue(self, value):
        A = struct.unpack('>H', value)[0]
        # return (A - 0x8000) * (self.F_n / self.S_n) * (self.u_e / 0x8000)
        return self.F_n / self.S_n * ((A - 0x8000) / 0x8000) * self.u_e * 2


class GSV3USB:
    def __init__(self, com_port, baudrate=38400):
        com_path = f'/dev/ttyUSBcom_port' if platform.system(
        ) == 'Linux' else f'COMcom_port'
        # print(f'Using COM: com_path')
        self.sensor = serial.Serial(com_path, baudrate)
        self.converter = ForceMeasurementConverterKG(10, 0.499552, 2)



    def read_value(self):
        self.sensor.read_until(b'\xA5')
        read_val = self.sensor.read(2)
        return self.converter.convertValue(read_val)



   
            
# initialization of datas
gsv_data=[]
temps=[]
t_0=time.time()




def data_gsv():
    dev = GSV3USB(6)
    # fig=plt.figure()
    # ax = fig.add_subplot(111)
    i=0
    # line1, = ax.plot(temps, gsv_data)

    try:
        while True:
            

            gsv_data.append(dev.read_value())
            t1=time.time()-t_0
            temps.append(t1)
            
            
            # I can print the datas without noticing any lags
            print(dev.read_value())   
            # I cannot plot the datas without noticing any lags
            plt.plot(temps,gsv_data)
            plt.draw ()
            plt.axis([temps[i]-6,temps[i]+6,-2,10])
            plt.pause(0.00001)
            plt.clf()
            i=i+1
            # I cannot pause without noticing any lags
            time.sleep(0.0001)
            # I cannot save datas without noticing any lags
            with open('student_gsv.csv', 'w') as f: 
                write = csv.writer(f) 
                write.writerow(gsv_data)                 
            
 
    except KeyboardInterrupt:
        print("Exiting")
        return



if __name__ == "__main__":
    data_gsv()``` 

【问题讨论】:

【参考方案1】:

您的主循环的构造方式是,每次使用 gsv_data.append(dev.read_value()) 获取值时,都会再次绘制该图。这可能需要时间,如果测量设备 (GSV-3 USB) 发送测量数据的数据频率非常高 - 比如说 >10 帧/秒 - 你会得到这些“滞后”。

我会降低情节更新率:

将测量数据附加到数组中(就像您已经做的那样) 使用计数器或比较时间差来获得大约每秒 4 次 (250ms) 的绘图更新率。这是人眼经常使用的更新速率。

【讨论】:

以上是关于在 while 循环中绘制或 time.sleep 或 csv 保存数据会导致感测数据和从力传感器读取数据之间存在滞后的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法修复 while 循环不使用 time.sleep 更新 tkinter 标签?

如何在while循环中评估函数

初识while循环

0010_while循环

python while循环语句

Linux定时循环执行python脚本