我希望能够尽可能接近实时读取串行数据。我的应用程序的实时是每20毫秒收到一个新的数据串。采用以下格式:
285285> 0,0> 7,8- | 315315> 30,30 GT; 7,8- | 345345> 60,60> 7,8- | 375375> 90,90> 7,8-
数字可能会有所不同我使用连接到arduino的电位计,每隔20ms发送一次数据,以最大波特率250000模拟我的传感器。
我为读取此数据而制作的tkinter GUI无法在接收数据的速度附近读取此数据。为了表明这是等待1200个数据点的结果。 (如果以理想速度读取,则每个值的平均读取时间为20ms,总时间为24秒)
以下是结果: 平均阅读时间:0.0439025016626 总时间:68.7999999523
为了找到瓶颈我被告知我应该分析代码。所以这里是分析代码的数据:(我还没弄清楚如何改进它)
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
79 0.001 0.000 0.002 0.000 __init__.py:49(create_string_buffer)
1 0.000 0.000 0.081 0.081 just_read.py:79(readData)
79 0.000 0.000 0.000 0.000 serialutil.py:404(getTimeout)
1 0.000 0.000 0.000 0.000 serialwin32.py:234(inWaiting)
79 0.078 0.001 0.080 0.001 serialwin32.py:242(read)
476 0.000 0.000 0.000 0.000 {_ctypes.byref}
158 0.000 0.000 0.000 0.000 {isinstance}
27 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.001 0.001 0.081 0.081 {method 'readline' of '_io._IOBase' objects}
17 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method 'strip' of 'str' objects}
2 0.000 0.000 0.000 0.000 {time.time}
922 function calls in 0.082 seconds
最后这是我用于GUI的代码:
import Tkinter
import serial
from collections import deque
import random
import time
import cProfile
import profile
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.xdata = []
self.pressure1 = []
self.displacement1 = []
self.cycle1 = []
self.pressure2 = []
self.displacement2 = []
self.cycle2 = []
self.pressure3 = []
self.displacement3 = []
self.cycle3 = []
self.pressure4 = []
self.displacement4 = []
self.cycle4 = []
self.k = 0
self.h= 0
self.timed = []
self.limit = 2400
self.t = time.time()
self.timer()
#@do_cprofile
def readData(self):
if (self.arduinoData.inWaiting()>8):
j = time.time()
x = self.arduinoData.readline()
z = time.time()-j
self.timed.append(z)
self.xdata.append(self.k)
self.xdata.append(self.k+1)
strip_data = x.strip()
split_data = x.split("|")
actuator1 = split_data[0].split(">")
actuator2 = split_data[1].split(">")
actuator3 = split_data[2].split(">")
actuator4 = split_data[3].split(">")
p1 = actuator1[0].split(",")
p2 = actuator2[0].split(",")
p3 = actuator3[0].split(",")
p4 = actuator4[0].split(",")
d1 = actuator1[1].split(",")
d2 = actuator2[1].split(",")
d3 = actuator3[1].split(",")
d4 = actuator4[1].split(",")
c1 = actuator1[2].split(",")
c2 = actuator2[2].split(",")
c3 = actuator3[2].split(",")
c4 = actuator4[2].split(",")
self.pressure1.append(int(p1[0]))
self.pressure1.append(int(p1[1]))
self.displacement1.append(int(d1[0]))
self.displacement1.append(int(d1[1]))
self.cycle1.append(int(c1[0]))
self.cycle1.append(int(c1[1]))
self.pressure2.append(int(p2[0]))
self.pressure2.append(int(p2[1]))
self.displacement2.append(int(d2[0]))
self.displacement2.append(int(d2[1]))
self.cycle2.append(int(c2[0]))
self.cycle2.append(int(c2[1]))
self.pressure3.append(int(p3[0]))
self.pressure3.append(int(p3[1]))
self.displacement3.append(int(d3[0]))
self.displacement3.append(int(d3[1]))
self.cycle3.append(int(c3[0]))
self.cycle3.append(int(c3[1]))
self.pressure4.append(int(p4[0]))
self.pressure4.append(int(p4[1]))
self.displacement4.append(int(d4[0]))
self.displacement4.append(int(d4[1]))
self.cycle4.append(int(c4[0]))
self.cycle4.append(int(c4[1]))
self.h += 1
self.k += 2
if self.k >= self.limit:
self.go = 0
avtime = 0
for u in self.timed:
avtime += u
avgtime = avtime/self.limit
print avgtime
print str(time.time()-self.t)
def timer(self):
if self.go == 1:
self.readData()
root.after(10, self.timer)
root = Tkinter.Tk()
app = App(root)
root.mainloop()
是否有更快的数据类型需要接收?有没有更好的方法(我确定这是因为我是新手)?
感谢您的帮助