我正在使用pyserial来读取arduino发送的数据。 arduino每50毫秒发送一次数据。我尝试过接收两种不同的格式,这两种格式都是字符串。我想知道是否有更快的方式在我的python gui中接收这些数据,无论是使用不同的库,接收不同的数据类型,还是优化代码。 第一格式:
String potcolumn = String(pot0holder) + "." + String(pot1holder) + "." + String(i) + "|" + String(int(pot0holder)+30) + "." + String(int(pot1holder)+30) + "." + String(i) + "|" + String(int(pot0holder)+60) + "." + String(int(pot1holder)+60) + "." + String(i) + "|" + String(int(pot0holder)+90) + "." + String(int(pot1holder)+90) + "." + String(i);
这取平均值:0.0523106797228秒读取
第二格式:
pressure1 = String(pot0array[0]) + "," + String(pot0array[1]);
displacement1 = String(pot1array[0]) + "," + String(pot1array[1]);
iteration1 = String(i-1) + "," + String(i);
full1 = pressure1 + ">" + displacement1 + ">" + iteration1;
pressure2 = String(pot0array[0]+30) + "," + String(pot0array[1]+30);
displacement2 = String(pot1array[0]+30) + "," + String(pot1array[1]+30);
iteration2 = String(i-1) + "," + String(i);
full2 = pressure2 + ">" + displacement2 + ">" + iteration2;
pressure3 = String(pot0array[0]+60) + "," + String(pot0array[1]+60);
displacement3 = String(pot1array[0]+60) + "," + String(pot1array[1]+60);
iteration3 = String(i-1) + "," + String(i);
full3 = pressure3 + ">" + displacement3 + ">" + iteration3;
pressure4 = String(pot0array[0]+90) + "," + String(pot0array[1]+90);
displacement4 = String(pot1array[0]+90) + "," + String(pot1array[1]+90);
iteration4 = String(i-1) + "," + String(i);
full4 = pressure4 + ">" + displacement4 + ">" + iteration4;
fulltotal = full1 + "|" + full2 + "|" + full3 + "|" + full4;
Serial.println(fulltotal);
这取平均值:0.0937848151484秒读取有意义,因为它是数据的两倍
这是一个非常简单的GUI,用于接收数据并使用pyserial,tkinter和python测试读取时间:
import Tkinter
import serial
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from collections import deque
import random
import time
import cProfile
class App:
def __init__(self, master):
self.arduinoData = serial.Serial('com5', 250000, timeout=None)
frame = Tkinter.Frame(master)
self.go = 0
self.run = Tkinter.LabelFrame(frame, text="Testing", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10)
self.run.grid(row=0, column=0, padx=20, pady=20)
self.run_respiration = Tkinter.Button(self.run, text="RUN",bd=10, height=5, width=10, command=self.getData)
self.run_respiration.grid(row=0, column=0, padx=5, pady=5)
self.test_options = Tkinter.LabelFrame(frame, text="Test Options", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10 )
self.test_options.grid(row=0, column=1, padx=20, pady=20)
self.stop = Tkinter.Button(self.test_options, text="STOP", bd=10, height=5, width=10, command=self.stopTest)
self.stop.grid(row=0, column=0, padx=5, pady=5)
frame.grid(row=0, column=0, padx=20, pady=20)
def getData(self):
return self.start()
def stopTest(self):
self.arduinoData.write("<H>")
self.go = 0
def start(self):
self.arduinoData.write("<L>")
self.go = 1
self.timer()
def readData(self):
if (self.arduinoData.inWaiting()>0):
t = time.time()
x = self.arduinoData.readline()
print str(time.time()-t)# + "\t" + str(x)
def timer(self):
if self.go == 1:
self.readData()
root.after(0, self.timer)
root = Tkinter.Tk()
app = App(root)
root.mainloop()
arduino很容易以正确的速度发送数据,只是python gui读取的速度不够快,不能使用。
使用cython或使用C ++的扩展是否有可能读得更快如果有的话,我可以使用任何资源作为指南我还没有找到任何东西。
即使只运行此代码也会产生平均时间.11438秒:
import time
import serial
def readData():
if arduinoData.inWaiting()>0:
t = time.time()
x = arduinoData.readline()
y = str(time.time()-t)
print y
def run():
x = 5000
z = 0
while z < x:
readData()
z += 1
if __name__ == "__main__":
arduinoData = serial.Serial('com5', 250000, timeout=None)
arduinoData.write("<L>")
run()
print('done')
感谢您提供任何帮助和建议
答案 0 :(得分:0)
在对上述代码进行概要分析后,我收到了这个作为输出
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.001 0.001 profile_stack.py:61(readData)
1 0.001 0.001 0.001 0.001 serialwin32.py:234(inWaiting)
2 0.000 0.000 0.000 0.000 {_ctypes.byref}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
270 function calls in 0.025 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
24 0.000 0.000 0.000 0.000 __init__.py:49(create_string_buffer)
1 0.000 0.000 0.025 0.025 profile_stack.py:61(readData)
24 0.000 0.000 0.000 0.000 serialutil.py:404(getTimeout)
1 0.001 0.001 0.001 0.001 serialwin32.py:234(inWaiting)
24 0.023 0.001 0.024 0.001 serialwin32.py:242(read)
146 0.000 0.000 0.000 0.000 {_ctypes.byref}
48 0.000 0.000 0.000 0.000 {isinstance}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.024 0.024 {method 'readline' of '_io._IOBase' objects}
5 function calls in 0.001 seconds
以下是我用来获取此信息的代码:
import Tkinter
import serial
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from collections import deque
import random
import time
import cProfile
class App:
def __init__(self, master):
self.arduinoData = serial.Serial('com5', 250000, timeout=None)
frame = Tkinter.Frame(master)
self.go = 0
self.run = Tkinter.LabelFrame(frame, text="Testing", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10)
self.run.grid(row=0, column=0, padx=20, pady=20)
self.run_respiration = Tkinter.Button(self.run, text="RUN",bd=10, height=5, width=10, command=self.getData)
self.run_respiration.grid(row=0, column=0, padx=5, pady=5)
self.test_options = Tkinter.LabelFrame(frame, text="Test Options", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10 )
self.test_options.grid(row=0, column=1, padx=20, pady=20)
self.stop = Tkinter.Button(self.test_options, text="STOP", bd=10, height=5, width=10, command=self.stopTest)
self.stop.grid(row=0, column=0, padx=5, pady=5)
frame.grid(row=0, column=0, padx=20, pady=20)
def do_cprofile(func):
def profiled_func(*args, **kwargs):
profile = cProfile.Profile()
try:
profile.enable()
result = func(*args, **kwargs)
profile.disable()
return result
finally:
profile.print_stats()
return profiled_func
def getData(self):
return self.start()
def stopTest(self):
self.arduinoData.write("<H>")
self.go = 0
def start(self):
self.arduinoData.write("<L>")
self.go = 1
self.timer()
@do_cprofile
def readData(self):
if (self.arduinoData.inWaiting()>0):
t = time.time()
x = self.arduinoData.readline()
print str(time.time()-t)# + "\t" + str(x)
def timer(self):
if self.go == 1:
self.readData()
root.after(0, self.timer)
root = Tkinter.Tk()
app = App(root)
root.mainloop()