【发布时间】:2015-06-15 22:21:48
【问题描述】:
我目前正在构建一台使用 Arduino Mega2560 作为其主控制器的机器。 Arduino通过串口连接,获取命令,执行它并每1ms吐出一堆测量数据。我有一个运行 Python 的 Raspberry Pi,为用户提供了一个很好的 GUI 来发送命令,并以可读的形式呈现数据。
我面临的问题:Arduino 能够每毫秒吐出 15 个字节的数据(所以只有 15kbyte/s),但我正在运行的代码每 10 毫秒只能处理大约 15 个字节,所以 1.5千字节/秒。
当我运行 cat /dev/ttyACM0 > somefile 时,我很好地看到了所有数据点。
我有以下精简的 Python 代码
# 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%
出了什么问题? PySerial 是否优化不佳,或者我错过了我的代码中的一些错误?我可以从 Python 运行 cat /dev/ttyACM0 > somefile 然后读取该文件,但这并不是一个很好的解决方案,是吗?
非常感谢:)
【问题讨论】:
-
不要经常刷新你的日志文件,你会立即看到一些性能改进。您通过使其在每个循环中写入磁盘来绕过文件缓冲。
-
我试过了,没用。顺便说一句,它在 linux 上,所以没有实际的写入涉及 AFAIK,它只涉及 Python 缓冲区,而不是 OS 缓冲区
-
尝试将 timeout 设置为 1,并使用
.read函数而不是 readlines 函数。您可以将字节存储在内部缓冲区中,并在循环结束时一次(或在单独的线程中)将它们全部解码,然后写入日志文件。
标签: python arduino raspberry-pi pyserial