如何使用Python优化实时打印串行数据
我正在尝试绘制从串行设备实时接收的选项卡分隔值。我对python非常陌生,但我已经设法拼凑了一个脚本来管理它,但是它似乎无法处理接收数据的速度,并且在降低速度并最终冻结之前使用了大量的处理能力。我能做些什么来阻止这一切。我附上了一个我正在使用的数据和脚本的示例 我接收到的数据是这样的,大约每半秒接收一行数据如何使用Python优化实时打印串行数据,python,matplotlib,plot,pyserial,Python,Matplotlib,Plot,Pyserial,我正在尝试绘制从串行设备实时接收的选项卡分隔值。我对python非常陌生,但我已经设法拼凑了一个脚本来管理它,但是它似乎无法处理接收数据的速度,并且在降低速度并最终冻结之前使用了大量的处理能力。我能做些什么来阻止这一切。我附上了一个我正在使用的数据和脚本的示例 我接收到的数据是这样的,大约每半秒接收一行数据 546 5986637 3598844 +26.0 01A0 547 5986641 3598843 +25.50 0198 548 5986634 35988
546 5986637 3598844 +26.0 01A0
547 5986641 3598843 +25.50 0198
548 5986634 3598844 +24.50 0188
<>你可以考虑使用线程来分割你的任务。您可能不需要每次收到新数据时都保存该数字。例如,只需每隔30秒左右更新绘图,即可减少计算量。您还可以拆分对csv的写入,这样您就有三个线程,一个寻找数据,一个存储缓冲数据,一个更新绘图 可能是一个很好的参考 在foo()的末尾,创建一个计时器,在10秒后调用foo()本身。 因为,计时器会创建一个新线程来调用foo()
<>你可以考虑使用线程来分割你的任务。您可能不需要每次收到新数据时都保存该数字。例如,只需每隔30秒左右更新绘图,即可减少计算量。您还可以拆分对csv的写入,这样您就有三个线程,一个寻找数据,一个存储缓冲数据,一个更新绘图 可能是一个很好的参考 在foo()的末尾,创建一个计时器,在10秒后调用foo()本身。 因为,计时器会创建一个新线程来调用foo()
我更改了它以保存终止时的数字,计算负载从~30%减少到~4%。我不熟悉线程,但我也会看看。非常感谢您的帮助。我已将其更改为保存终止时的数字,计算负载已从约30%减少到约4%。我不熟悉线程,但我也会看看。非常感谢你的帮助。
from matplotlib import pyplot as plt
from matplotlib import animation
import serial
from pandas import DataFrame
from datetime import datetime
import csv
filename = datetime.now().strftime("%d-%m-%Y_%I-%M-%S_%p") # Gets time and date in readable format for filenaming.
Data1 = {'Value': [0], 'Frequency 1': [0], 'Frequency2': [0], 'Temperature': [0]}
df = DataFrame(Data1, columns=['Value', 'Frequency1', 'Frequency2', 'Temperature'])
serial_port = 'COM5'; # Different port for linux/mac
baud_rate = 9600; # In arduino, Serial.begin(baud_rate)
write_to_file_path = "output.txt";
data = []
ft = []
output_file = open(write_to_file_path, "w+");
ser = serial.Serial(serial_port, baud_rate)
plt.ion()
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, sharey=False, )
ax1.set_title('Temp')
ax2.set_title('Freq 1')
ax3.set_title('Freq 2')
ax1.set_ylabel('Temperature')
ax2.set_ylabel('Frequency')
ax3.set_ylabel('Frequency')
ax1.ticklabel_format(useOffset=False)
ax2.ticklabel_format(useOffset=False)
ax3.ticklabel_format(useOffset=False)
ax1.ticklabel_format(style='plain', axis='y', scilimits=(0, 0))
ax2.ticklabel_format(style='sci', axis='y', scilimits=(6, 6))
ax3.ticklabel_format(style='sci', axis='y', scilimits=(6, 6))
while True:
line = ser.readline();
line = line.decode("utf-8") # ser.readline returns a binary, convert to string
print(line)
line1 = line.split('\t') # Separates values by tabs
output_file.write(line); # Writes to text file
data.append(line1) # Adds line to data file
newline = [float(line1[0]), float(line1[1]), float(line1[2]), float(line1[3])] # Creates line of float values
ft.append(newline) # Adds to list of floats
f1 = float(line1[0]) # Line number (count)
f2 = float(line1[1]) # Frequency 1
f3 = float(line1[2]) # Frequency 2
f4 = float(line1[3]) # Temperature in C
f5 = str(line1[4]) # Temperature in Hex, treated as a string
# Data2 = {'Value':[f1],'Frequency 1':[f2],'Frequency2':[f3], 'Temperature':[f4]}
# df2 = DataFrame(Data2,columns=['Value', 'Frequency1','Frequency2','Temperature'])
# df.append(df2)
# DataFrame still not working, need to fix so that data is stores as integer or float
plt.pause(0.1)
ax1.plot(f1, f4, marker='.', linestyle='solid') # subplot of freq 1
ax2.plot(f1, f2, marker='.', linestyle='solid') # subplot of freq 2
ax3.plot(f1, f3, marker='.', linestyle='solid') # subplot of Temp in C
plt.subplot
plt.xlabel("Count")
with open(filename + ".csv", "a") as f: # Writes data to CSV, hex values for temp don't seem to be writing
writer = csv.writer(f, delimiter=",")
writer.writerow([f1, f2, f3, f4, f5])
plt.draw()
plt.savefig(filename + '.png', bbox_inches='tight') # Saves the plot
import time, threading
def foo():
print(time.ctime())
threading.Timer(10, foo).start()
foo()
#output:
#Thu Dec 22 14:46:08 2011
#Thu Dec 22 14:46:18 2011
#Thu Dec 22 14:46:28 2011
#Thu Dec 22 14:46:38 2011