如何提高PySerial的读取速度 [英] How can I improve PySerial read speed

查看:752
本文介绍了如何提高PySerial的读取速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在构建一台使用Arduino Mega2560作为其主要控制器的机器. Arduino通过串行连接,获取一条命令,执行该命令,然后每1ms发出一堆测量数据.我有一个运行Python的Raspberry Pi,它为用户提供了一个不错的GUI,可以发送命令并以可读的形式显示数据.

I'm currently building a machine that uses an Arduino Mega2560 as its main controller. The Arduino is connected to over serial, gets a command, executes it and spits out a bunch of measurement data every 1ms. I have a Raspberry Pi running Python to give the user a nice GUI to send the command, and to present the data in a readable form.

我面临的问题:Arduino能够每毫秒吐出15个字节的数据(所以只有15kbyte/s),但是我正在运行的代码每10毫秒只能应付约15个字节,所以1.5 kB/s.

The problem I face: the Arduino is able to spit out 15 byte of data each millisecond (so that's only 15kbyte/s), but the code I'm running can only cope with about 15 byte each 10 milliseconds, so 1.5kB/s.

运行cat /dev/ttyACM0 > somefile时,我很好地看到了所有数据点.

When I run cat /dev/ttyACM0 > somefile, I nicely see all datapoints.

我有以下精简的Python代码

I have the following slimmed down Python code

# Reset Arduino by starting serial
microprocBusy = True
serialPort = serial.Serial("/dev/ttyACM0", baudrate=460800, timeout=0)
time.sleep(0.22);
serialPort.setDTR(False);
time.sleep(0.22);
serialPort.setDTR(True);
time.sleep(0.10);

logfile = open(logfilenamePrefix + "_" + datetime.datetime.now().isoformat() + '.txt', 'a')

# Bootloader has some timeout, we need to wait for that
serialPort.flushInput()
while(serialPort.inWaiting() == 0):
    time.sleep(0.05)

# Wait for welcome message
time.sleep(0.1)
logfile.write(serialPort.readline().decode('ascii'))
logfile.flush()

# Send command
serialPort.write((command + '\n').encode('ascii'))

# Now, receive data
while(True):
    incomingData = serialPort.readline().decode('ascii')
    logfile.write(incomingData)
    logfile.flush() 

    if(incomingData[:5] == "FATAL" or incomingData[:6] == "HALTED" or incomingData[:5] == "RESET"):
        break;
    elif(incomingData[:6] == "RESULT"):
            resultData = incomingData;

logfile.flush() 

运行此命令时,第一个〜350个数据点进入了,然后我看到一些错误的数据并错过了大约2000个数据点,之后又看到了另外350个左右的数据点.在此过程中,CPU使用率为100%

When I run this, the first ~350 datapoints come in, then I see some mangled data and miss about 2000 datapoints, after which I see another 350 or so datapoints. The CPU usage is at 100% during the process

出了什么问题? PySerial优化不佳,还是我错过的代码中有一些错误?我可以从Python运行cat /dev/ttyACM0 > somefile然后读取该文件,但这不是一个很好的解决方案,对吗?

What is going wrong? Is PySerial poorly optimized, or is there some mistake in my code I missed? I could just run cat /dev/ttyACM0 > somefile from Python and then read that file, but that's not really a nice solution, is it?

非常感谢:)

推荐答案

我已经从PySerial切换为 PyTTY ,它解决了我的问题.只需将其插入此代码(进行一些小的更改,例如将serialPort.inWaiting() == 0替换为serialPort.peek() == b''),即可使我的代码能够处理数据流,且CPU使用率不超过50%,这意味着其运行速度至少是其10倍.我仍然在使用PySerial设置DTR线.

I've switched from PySerial to PyTTY, which solves my problem. Just plugging it into this code (with some small changes, like replacing serialPort.inWaiting() == 0 by serialPort.peek() == b'' for example) makes my code able to handle the datastream and not get above 50% CPU usage, which means it is at least 10x as fast. I'm still using PySerial to set the DTR lines though.

所以,我想这个问题的答案是PySerial的优化确实很差.

So, I guess the answer to the question is that indeed PySerial is indeed poorly optimised.

这篇关于如何提高PySerial的读取速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆