串行数据保存的定时添加

2024-06-06 22:59:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经编写了一个程序来保存arduino的串行数据,绘制它,给它添加一个时间戳,并将数据保存到CSV。串行数据每隔几秒钟发送一次。然而,arduino程序的时间安排与Python程序不一致,并且经常会出现相位不一致的情况,我在CSV文件的错误列中得到了一个时间戳,这使得处理数据变得困难

我认为解决方案是一个由range控制的for循环,但无法完全解决如何做到这一点

下面是相关代码,串行数据在1-32个图之间,但出于空间原因,我在这里将其压缩为3,但我通常会注释掉不相关的数据,因此需要一个循环范围

line=ser.readline()      #ascii
print(line)
seconds = time.time()

line_as_list = line.split(b',')
J = float(line_as_list[0]) 
L = float(line_as_list[1])
M = float(line_as_list[2])
relProb = line_as_list[4] 
relProb_as_list = relProb.split(b'\n')
relProb_float = float(relProb_as_list[0])

# Add x and y to lists
xs.append(seconds)
As.append(J)
bs.append(L)
cs.append(M)


# Limit x and y lists to 20 items
#xs = xs[-20:]
#ys = ys[-20:]

# Draw x and y lists
ax.clear()
ax.plot(xs, As, label="Plot 1")
ax.plot(xs, bs, label="Plot 2")
ax.plot(xs, cs, label="Plot 3")


dateTimeObj = datetime.now()
f = open('Datafile.csv','a')
line=str(line,"utf-8") ## the UTF-8 bit is essential to make it not have b' '
timestampStr = dateTimeObj.strftime("%d-%b-%Y (%H:%M:%S.%f)")#convert time to string


f.write(timestampStr)#write the time to the file
f.write(",") # seperate the time from the data
f.write(line)
f.close()

Tags: theto数据程序timeasline时间
1条回答
网友
1楼 · 发布于 2024-06-06 22:59:29

我怀疑问题在于循环的处理时间太长,您可能不仅缺少部分行,有时还缺少整行本身。串行缓冲区填满时会发生什么情况取决于硬件和使用的特定驱动程序(可能是usb串行驱动程序?)。串行输入缓冲区似乎已满,并悄悄地抛出了一些数据。我认为绘制绘图可能是代码中最慢的部分,因为matplotilb使用cpu渲染,并且是为定制而设计的,而不是为了速度。我看到了解决这个问题的两种方法:将代码加速到可以保持的速度,或者将绘制图形的过程与使用线程读取串行端口的过程分开

您可能可以做很多小事情来加速代码,但最大的事情之一可能是研究matplotlib的animation功能,这些功能旨在最大限度地减少只更新已更改的图形部分所需的额外处理

另一个选项(尽管两者实际上可以结合使用)是将串行端口的读取移动到单独的线程,以便图形的绘制不会中断数据流。基于您的代码的快速示例可能如下所示(关于您的代码的一些推断):

import serial
import time
from threading import Thread
import matplotlib.pyplot as plt
import datetime

ser = serial.Serial()
xs = []
As = []
bs = []
cs = []

fig, (ax,) = plt.subplots(1,1)
f = open('Datafile.csv','a')

keep_reading = True

def reader_thread():
    while keep_reading:
        #do processing on img
        
        line=ser.readline()      #ascii
        print(line)
        seconds = time.time()
        
        line_as_list = line.split(b',')
        J = float(line_as_list[0]) 
        L = float(line_as_list[1])
        M = float(line_as_list[2])
        relProb = line_as_list[4] 
        relProb_as_list = relProb.split(b'\n')
        relProb_float = float(relProb_as_list[0])
        
        # Add x and y to lists
        xs.append(seconds)
        As.append(J)
        bs.append(L)
        cs.append(M)
        
        
        # Limit x and y lists to 20 items
        #xs = xs[-20:]
        #ys = ys[-20:]
        dateTimeObj = datetime.now()
        
        line=str(line,"utf-8") ## the UTF-8 bit is essential to make it not have b' '
        timestampStr = dateTimeObj.strftime("%d-%b-%Y (%H:%M:%S.%f)")#convert time to string
        
        
        f.write(timestampStr)#write the time to the file
        f.write(",") # seperate the time from the data
        f.write(line)

try:
    t = Thread(target=reader_thread)
    t.start()
    while True:
        # Draw x and y lists
        ax.clear()
        ax.plot(xs, As, label="Plot 1")
        ax.plot(xs, bs, label="Plot 2")
        ax.plot(xs, cs, label="Plot 3")
        time.sleep(.1) #not strictly necessary
except KeyboardInterrupt: #ctrl-c to quit
    pass
finally:
    keep_reading = False
    t.join()
    ser.close()
    f.close()

相关问题 更多 >