所以,我有一个微控制器连接到我的笔记本电脑使用UART。为了对微控制器何时向另一个微控制器发送数据有一个好主意,我通过UART链路发送数据副本,并对其加时间戳,以便我可以稍后进行一些吞吐量和粗略的延迟分析。
目前,我可以发送一系列10条消息,并且我能够在40%的时间内读取所有数据。当我增加发送的消息数量时,事情变得非常糟糕,我的脚本会丢失大量数据。
我会警告你,自从我做了python以来已经有一段时间了,所以我的大部分代码都是非常的,让我们说“非pythonic”。
通过UART发送的消息是数据消息“sent:X”,其中X是20bytes的垃圾。现在,因为它不能正常工作,代码很乱,除非收到神奇的send_done
消息,否则它将永远运行。正如我所提到的,这对于10条消息的爆发运行得相当好。从那些,我可以得知数据速率大约是32kbps。
我的问题是是否可以通过修复一些我无法发现的明显错误来获得更高的准确性,或者是否只是python太慢,而且我需要转向C。
def main():
launch_time=time.time()
time.clock()
[wday, month, day, clocktime, year]=time.ctime(launch_time).split(' ')
print(launch_time)
milis=launch_time-math.floor(launch_time)
milis=str(milis)
print(milis)
launch_time=clocktime+milis[1:len(clocktime)+1]
Port5=serial.Serial(4,38300,rtscts=True,xonxoff=True) #Devkit
sio5=io.TextIOWrapper(io.BufferedRWPair(Port5,Port5))
timers=[]
k=0
msg=0
buf=''
while True:
data=Port5.read(Port5.inWaiting())
if data:
if ":" in data: #Only safe as long as messages cannot contain lowercase s
timers.append(time.clock())
k+=1
print(k)
buf+=(data)
#os.system('cls')
#print(buf)
#print(data)
if "send_done" in buf:
f=open("log.txt","a")
f.write(launch_time+'\n')
f.close()
#print(len(timers))
#print(timers)
for string in buf.split("sent:"):
if "send_done" in string:
[string, discard]=string.split("send_done")
if string:
print(msg)
print(string)
print(k)
f=open("log.txt","a")
f.write(addseconds(launch_time,str(timers[msg])[0:12])+' '+string.encode('Hex').upper()+'\n')
f.close()
msg+=1
print(timers)
return
修改 看起来这可能不是传输结束时的问题,因为在测试A similar post中讨论的线程脚本以及使用Termite进行测试后,整套数据并非100%到达在任何一个。我可能不得不修改微控制器上的一些设置。
答案 0 :(得分:2)
你确定它是38300而不是38400波特吗?
即使对于目前最差的PC上的python,也不应该有低于4 KB / s数据流的性能瓶颈(并且38.3kbps左右)。要测试它,你应该直接写入从串口读取的每个数据的文件,而无需重新打开,打印到控制台或其他任何数据。
另一方面,将'cls'作为系统命令运行并将不断增加的大小缓冲区打印到屏幕上非常慢,这可能会给您带来麻烦。
另请注意buf += (data)
(为什么不buf += data
没有括号?)将每轮构建一个新字符串,所以如果它变大,内存分配+数据复制也将是性能问题,但不是在10条消息之后。
编辑:可能(但在您的情况下可能不太可能)性能改进可能是将传入的非空数据块存储在列表中。随着列表大小的增加,附加到列表的末尾不会花费更多。然后只加入它的最后9个元素来检查'send_data'字符串。像这样:
incoming = ['asdf', None, 'vf', None, None, 'afsd', 'gfts', 'end', None, '_', 'do', 'nett', 'rest of data not processed']
in_list = []
for data in incoming:
if data:
in_list.append(data)
if "send_done" in "".join(in_list[-9:]):
string, discard = "".join(in_list).split("send_done")
print "Str: '%s' discard: '%s'" % (string, discard)
break