2014-02-24 64 views
1

一年前,我需要一個腳本來捕獲串行設備的輸入並將其發送到Web瀏覽器。 (一個觸摸傳感器連接到一個博物館的3D打印的埃及平板電腦上。)我原本打算使用Perl,但因爲那不是玩球,所以我在發佈前只有幾個小時選擇了Python(我不是python dev)。我製作了一個腳本,運行良好並且已經有一段時間了,唯一的問題是腳本使用100%的CPU。如何在不使用整個CPU的情況下讓Python從串口讀取數據,而不管何時輸入被按下,仍然能夠響應?python serial 100%cpu

我的腳本如下:

#!/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

readKey -loop結束在短期內添加time.sleep。它會讓其他進程運行。

此外,請注意,call正在阻塞,直到操作完成。

+0

'time.sleep'是有點問題,因爲你可能最終放慢了應用程序的速度,因爲它無法跟上輸入的數據(因爲它似乎是一個交互式的用例,你會可能會很好,但)。它也被認爲是不好的做法。 – Stefan

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負載。