Python serial comm and RTS pin

At my work I’m communicating with an embedded device via a serial-to-USB cable. It works fine, except for one little detail: when the “Ready To Send” (RTS) pin is high, the device shuts down. This is by design, but annoying nonetheless, since almost all serial communication software sets this pin to high. I’ve written a little Python program that opens the serial connection, sets the RTS pin to low, and shows all data read from it.

I’ve tested my solution on Linux, not sure if it works on other systems, as I’m using rather low-level calls to get the RTS pin low. Please leave a comment when you’ve tried!

The Python code defines two functions; one to set the RTS pin, and one to copy the data from the serial device to stdout. Here is the full code:

import fcntl
import struct
import sys
import termios
import time

def set_rts(fileobj, on_off):
    # Get current flags
    p = struct.pack('I', 0)
    flags = fcntl.ioctl(fileobj.fileno(), termios.TIOCMGET, p)

    # Convert four byte string to integer
    flags = struct.unpack('I', flags)[0]

    if on_off:
        flags |= termios.TIOCM_RTS
    else:
        flags &= ~termios.TIOCM_RTS

    # Set new flags
    p = struct.pack('I', flags)
    fcntl.ioctl(fileobj.fileno(), termios.TIOCMSET, p)

def output_data(filedev, ignore = '\r'):
    '''Outputs data from serial port to sys.stdout.'''

    while True:
        byte = filedev.read(1)

        if not byte:
            break

        if byte in ignore: continue

        sys.stdout.write(byte)

if len(sys.argv) < 2:
    device = '/dev/ttyUSB0'
else:
    device = sys.argv[1]

# Open device with RTS pin low
print 'Device: %s' % device
usb = open(device, 'rw')
set_rts(usb, False)

try:
    output_data(usb)
except KeyboardInterrupt:
    print 'Keyboard interrupt, closing.'

usb.close()
print '--- Done ---'
dr. Sybren A. Stüvel
dr. Sybren A. Stüvel
Open Source software developer, photographer, drummer

Related