python serial 100%cpu

时间:2014-02-24 10:29:52

标签: python serial-port pyserial

一年前,我需要一个脚本来捕获串行设备的输入并将其发送到Web浏览器。 (一个连接到博物馆里的3D打印埃及平板电脑的触摸传感器。)我原本打算使用Perl,但因为那不是打球而我在发布之前只有几个小时我选择了Python(我不是python开发)。我制作了一个运行良好的脚本并且已经有一段时间了,唯一的问题是该脚本使用100%的CPU。如何在不使用整个CPU的情况下让Python从串口读取,同时无论何时按下输入都能提供响应?

我的脚本如下:

#!/usr/bin/python

import time
import serial
import sys
from subprocess import call
import traceback

myport = 0

ser = serial.Serial()

def readkey():
        while 1:
                out = '';
                while ser.inWaiting() > 0:
                        out += ser.read(1);
                        if out != '\xf8' and out != '\xf9':
                                call(["xdotool", "key", "F8"])
                                call(["xdotool", "type", str(ord(out))])
                                call(["xdotool", "key", "F9"])
                        out = ''

def main_sys():
        global ser
        print "Opening Stela serial port"
        ser.open();
        ser.isOpen();
        print "Starting Stela subsystem"

        while 1:
                try:
                        readkey()
                        break
                except Exception as e:
                        print "caught os error".format(e)
                        time.sleep(1)
                        main_sys()


def init():
        global ser
        global myport
        while 1:
                try:
                        theport = '/dev/ttyACM'+str(myport)
                        print "Trying " + theport

                        ser = serial.Serial(
                                port=theport,
                                baudrate=115200,
                                parity=serial.PARITY_NONE,
                                stopbits=serial.STOPBITS_ONE,
                                bytesize=serial.EIGHTBITS
                        )
                        main_sys()
                        break;
                except Exception as e:
                        traceback.print_exc()
                        myport += 1
                        if myport > 5:
                                myport = 0
                        time.sleep(1)
                        init()

init()

2 个答案:

答案 0 :(得分:2)

time.sleep循环结束时短时间内添加readKey。它会让其他进程运行。

另外,请注意call在操作完成之前一直阻塞。

答案 1 :(得分:1)

我会尽量避免ser.inWaiting()来电。相反,我会直接致电ser.read(1)。这样,调用将阻塞,直到有更多数据可用。在此期间,CPU可以自由地做其他事情:

def readkey()
    out = ser.read(1);
    if out != '\xf8' and out != '\xf9':
            call(["xdotool", "key", "F8"])
            call(["xdotool", "type", str(ord(out))])
            call(["xdotool", "key", "F9"])

这应该具有相同的行为,但几乎没有CPU负载。