11
votes

Motivation

I want to start leraning how to use the python library Pyserial. It seems like a really nice library that works for a lot of people. I want to use it for an upcoming project in which I have to automate serial communications.

Environment

I'm running Ubuntu 15.04. I'm using Python 2.7.

Setting up virtual ports

I don't currently have a device that I can communicate with over a serial port. I'm using the socat application to create two virtual ports that are connected to each other with a baudrate of 9600.

$ socat -d -d pty,raw,echo=0,b9600 pty,raw,echo=0,b9600
2016/01/16 12:57:51 socat[18255] N PTY is /dev/pts/2
2016/01/16 12:57:51 socat[18255] N PTY is /dev/pts/4
2016/01/16 12:57:51 socat[18255] N starting data transfer loop with FDs [5,5] and [7,7]
$ echo "hello" > /dev/pts/2
$ cat /dev/pts/4
hello

Great! It seems like the ports work!

A simple pyserial script

I install pyserial using pip

$ sudo pip install pyserial

Then I wrote a little serialtest.py

#!/usr/bin/env python
import serial

ser = serial.Serial('/dev/pts/2', 9600)

That is the entirety of serialtest.py

Running the script and encountering an error

$ python serialtest.py 
Traceback (most recent call last):
  File "serialtest.py", line 4, in <module>
    ser = serial.Serial('/dev/pts/2')
  File "/home/sbl/.local/lib/python2.7/site-packages/serial/serialutil.py", line 180, in __init__
    self.open()
  File "/home/sbl/.local/lib/python2.7/site-packages/serial/serialposix.py", line 311, in open
    self._update_dtr_state()
  File "/home/sbl/.local/lib/python2.7/site-packages/serial/serialposix.py", line 605, in _update_dtr_state
    fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
IOError: [Errno 22] Invalid argument

What's up with that?

Unsuccessful attempts at debugging

This guy said he had success when using python 2.6. I couldn't get Pyserial to work with 2.6.

This guy was having trouble with is baudrate. I double check my baudrate with the command $stty -F /dev/pts/2 and confirmed that it was, in fact, at a baudrate of 9600.

This guy also claims to have problems with baudrate and attributes it to his kernel. That was back in 2012, so I don't think it's relevant anymore.

My Question

How can I get my serialtest.py script to run without error?

2
@AustinPhillips you are one cool dude. I don't know much about serial communication and RS-232 and readytosend/cleartosend, so the issue you raised on the Pyserial wiki wasn't conceptually clear to me. However, I blindly inverted the logic on lines 310 and 312 of serialposix.py and tried my script again. It worked! I can now read and write to my virtual ports using Pyserial. Even though it seems that you're not 100% confident in your fix, I'm willing to run with it. Thanks for your time!Spencer B Liberto

2 Answers

17
votes

To make this Q&A complete, this is a solution (as found in the link by Austin Philips):

#!/usr/bin/env python
import serial

ser = serial.Serial('/dev/pts/2', 9600, rtscts=True,dsrdtr=True)

See this PySerial Github issue for more explanation.

2
votes

According to the issue mentioned by Sebastian, This issue is resolved as of version 3.1 of Pyserial.

https://github.com/pyserial/pyserial/issues/59

zsquareplusc commented on May 29

released 3.1 where an error setting control lines in open() is ignored (but not in later calls).

Update via pip, github or the download page: https://pypi.python.org/pypi/pyserial