lordhog
lordhog

Reputation: 3707

Delay from serial port using Python

I am trying to write a small Python script to read data from a serial port and simply display it to the screen. It seems to be working, but there seems to be a delay to when I see data displayed on the screen.

import serial
import sys

SerialGF = serial.Serial(port='/dev/ttyAMA0', baudrate=115200, parity='N', stopbits=1, xonxoff=0, rtscts=0, timeout=0)

def main():
    # openSerial_GF()
    print SerialGF.isOpen()
    SerialGF.flush()
    SerialGF.flushInput()
    SerialGF.flushOutput()
    try:
        while True:
            readSerial_GF()
    except KeyboardInterrupt:
        pass
    SerialGF.close()
    print SerialGF.isOpen()

# def openSerial_GF():
#     global SerialGF = serial.Serial(port='/dev/ttyAMA0', baudrate=115200, parity='N', stopbits=1, xonxoff=0, rtscts=0, timeout=0)

def readSerial_GF():
    s = SerialGF.read(SerialGF.inWaiting())
    sys.stdout.write(s)

if __name__ == "__main__":
    main()

The data on serial port is a stream of dash characters, '-', until some event occurs. What I am seeing a delay when the data is displayed to the screen. What is odd is that 1024 characters are displayed at a time. I have set the timeout to zero (0) so it should return straight away, but it isn't. Does anyone have any ideas why there is a delay?

Thanks, Mark

Upvotes: 1

Views: 2971

Answers (1)

abarnert
abarnert

Reputation: 366213

This is almost certainly a buffering issue. The short answer is, if you want output to show up immediately, do sys.stdout.flush() after each sys.stdout.write(…).

On most platforms, by default,* the stdio streams end up line buffered. This means that anything written is buffered up until you either write a newline, or fill up the buffer inside stdio, which is usually some nice round length like 1024 bytes.

Python 2.x** mostly leaves buffering up to the C stdio library, so for full details, you want to look up your platform's fopen and possibly fwrite implementations. The docs for open explain the options Python gives you for controlling the buffering, and the command line and environment docs explain how you can influence the way the stdio streams are opened. But really, rather than forcing everyone to run your program with -u, it's better to just explicitly flush when you want to make sure output appears.

* If you open the files in binary mode—which is what -u and PYTHONUNBUFFERED control—you get unbuffered output. If you open the files in text mode and isatty() is true or not available, you usually get line-buffered mode. Otherwise, you usually get "fully-buffered" mode, meaning there's a fixed-size buffer and writes happen when that buffer is filled.

** Note that this is all Python 2.x-specific; 3.x has its own file objects that work directly on top of native file descriptors/handles, instead of using C stdio.

Upvotes: 3

Related Questions