一年前,我需要一个脚本来捕获串行设备的输入并将其发送到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()
答案 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负载。