1

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

2
  • 1
    Maybe related to buffering that is turned on by default in sys.stdout. Can you run in unbuffered mode python -u to see if the problem persists? Here's another question which digs into the buffering aspect. Commented Nov 18, 2014 at 0:25
  • 1
    Or just do a sys.stdout.flush() after the write. The buffering is explained in the open docs (not the specific details on how sys.stdout is opened, which obviously happens before you even get control). On many systems, the "system default" is to buffer until either a newline is printed or some max line length (like 1024) is reached, which seems like exactly what you're seeing. Commented Nov 18, 2014 at 0:36

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, abarnert!! Worked like a charm.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.