Python串行无法读取大量数据

Python串行无法读取大量数据,python,python-2.7,pyserial,Python,Python 2.7,Pyserial,所以,我用UART把一个微控制器连接到我的笔记本电脑上。为了更好地了解微控制器何时向另一个微控制器发送数据,我正在通过UART链路发送数据的副本,并对其加上时间戳,以便稍后进行吞吐量和粗略的延迟分析 目前,我可以传输一系列10条信息,并且我能够在40%的时间内读取所有数据。然而,当我增加发送的消息量时,事情变得非常不稳定,我的脚本会丢失大量数据 我要警告您,我已经有一段时间没有使用python了,所以我的大部分代码都非常,比如说“非python” 通过UART发送的消息是数据消息“sent:X”

所以,我用UART把一个微控制器连接到我的笔记本电脑上。为了更好地了解微控制器何时向另一个微控制器发送数据,我正在通过UART链路发送数据的副本,并对其加上时间戳,以便稍后进行吞吐量和粗略的延迟分析

目前,我可以传输一系列10条信息,并且我能够在40%的时间内读取所有数据。然而,当我增加发送的消息量时,事情变得非常不稳定,我的脚本会丢失大量数据

我要警告您,我已经有一段时间没有使用python了,所以我的大部分代码都非常,比如说“非python”

通过UART发送的消息是数据消息“sent:X”,其中X是20字节的垃圾。现在,由于它不能正常工作,代码很混乱,除非收到神奇的
send\u 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  
编辑
在传输的这一端,这似乎不是一个问题,因为在测试中讨论的线程脚本以及使用Termite进行测试之后,完整的数据集在这两种情况下都不会100%到达。我可能需要修改微控制器上的一些设置。

你确定它是38300波特而不是38400波特吗

即使在当前最差的PC上,python的数据流速度也不应该低于4kb/s(38.3kbps左右)。为了测试这一点,您应该直接写入从串行端口读取的每个数据,而无需重新打开它、打印到控制台或其他任何东西

另一方面,将“cls”作为系统命令运行并将不断增加的大小缓冲区打印到屏幕上的速度非常慢,这可能会给您带来问题

另外,请注意,
buf+=(数据)
(为什么不
buf+=data
不带括号?)每轮都会生成一个新字符串,因此如果它变大,内存分配+数据复制也将是一个性能问题,但不是在10条消息之后

EDIT:一个可能的(但在您的情况下可能是不必要的)性能改进是将传入的非空数据块存储在列表中。随着列表大小的增加,追加到列表末尾的成本不会增加。然后只连接它的最后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

您得到了一行代码:
[string,discard]=string.split(“send\u done”)
。方括号应该是圆括号吗?你确实是对的,波特率应该是38400,但是变化很小。感谢您注意到“buf+=(数据)”,这可能是以前尝试留下的一些碎片,与打印相同。但是,对于不断增长的字符串大小,您是否建议在数据收集期间拆分缓冲区?或者我应该把它吸起来,然后穿线?只是运行了一个快速测试,如果微控制器肯定会在合理的时间内发送“send_done”,我认为你不需要修改它。将100K字符逐个添加到20MB字符串只需0.2秒。