python serial 100% cpu
Question: A year ago I needed a script to capture input from a serial device and send it
to a web browser. (A touch sensor attached to a 3d printed Egyptian tablet in
a Museum.) I had originally intended to use Perl but as that wasn't playing
ball and I only had a few hours before launch I opted for Python (I'm not a
python dev). I made a script that worked fine and has been for some time, with
the only issue being that the script uses 100% CPU. How can I get Python to
read from the serial port without using the whole CPU, while still bring
responsive regardless of when the input is pressed?

My script is below:

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


Answer: Add a `time.sleep` for a short period at the end of your `readKey`-loop. It
will let other processes run.

Also, be aware that `call` is blocking until the operation is finished.

