shieldfoss
shieldfoss

Reputation: 884

PySerial write() instant timeout

EDIT

I found out what the problem was and have answered my own question.

Original question below this line

I have a serial bridge between COM4 and COM5 implemented in software (Specifically, HDD's Free Virtual Serial Configuration Utility)

I have two different python scripts starting up in two different instances of Powershell, receive first:

import serial
receive = serial.Serial(port = 'COM5', baudrate = 9600)
text = receive.read(100)
receive.close()
print text

And then the sender:

import serial
send = serial.Serial(port = 'COM4', baudrate = 9600, timeout = 0)
send.write("Hello")
send.close()

When starting the sender script, the receiver script gets the sent message (So communication is clearly established) but the sender script immediately ends with an error:

Traceback (most recent call last):
  File ".\sending.py", line 3, in <module>
    send.writelines("Hello")
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 270, in write
    raise writeTimeoutError
serial.serialutil.SerialTimeoutException: Write timeout

I get the same error when I change the sender script to

send = serial.Serial(port = 'COM4', baudrate = 9600)

So my question is: What exactly is timing out? How do I prevent that from happening? I mean, the data IS being sent so I could probably just put the whole thing in a try/except(and do nothing) block but that seems like a bad solution in the long run.

Upvotes: 4

Views: 17285

Answers (2)

JardaG
JardaG

Reputation: 11

The problem may be that the interface tries to comply with RTS, CTS, DSR, or DTS signals. It is possible that if they are not properly virtually connected, they can mysteriously affect communication through a timeout.

I would also recommend looking at the configuration of the used virtual serial bridge.

One solution may be to ignore influence using rtscts=False and/or dsrdtr=False when opening the serial port in Python.

I could use an alternative solution for sniffing communication using hub4com, where I used the parameter --octs = off, for example in this way, but the virtual ports had to be created correctly before. hub4com --baud=115200 --route=0:All --route=1:All --route=2:All --no-default-fc-route=All:All --octs=off \\.\COM1 \\.\CNCB0 \\.\CNCB1

Upvotes: 1

shieldfoss
shieldfoss

Reputation: 884

The clue is in the error message[1]

File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 270, in write
raise writeTimeoutError

so we open that file and find:

if self._writeTimeout != 0: # if blocking (None) or w/ write timeout (>0)
            # Wait for the write to complete.
            #~ win32.WaitForSingleObject(self._overlappedWrite.hEvent, win32.INFINITE)
            err = win32.GetOverlappedResult(self.hComPort, self._overlappedWrite, ctypes.byref(n), True)
            if n.value != len(data):
                raise writeTimeoutError

Read that first conditional again:

if self._writeTimeout != 0:

so let us rewrite our code from before

send = serial.Serial(port = 'COM4', baudrate = 9600, timeout = 0)

becomes

send = serial.Serial(port = 'COM4', baudrate = 9600, writeTimeout = 0)

and Et Voila: No exception.

[1] Well Designed Error Messages? That's new!

Upvotes: 4

Related Questions