Anthony S
Posts: 40
Joined: Mon Apr 29, 2019 3:58 pm
Location: Bedfordshire, UK

PySerial: Does "write_timeout" actually do anything?

Fri May 03, 2019 4:52 pm

Hi Guys,

I'm using a Pi3B+ to test the commands and functionality of PySerial. I'm slowly working my way through it, having lots of fun, but when I get to "write_timeout" I find it doesn't seem to do anything. The PySerial 3.4 documentation defines "write_timeout" thus:

Getter: Get current write timeout setting
Setter: Set write timeout
Type: float (seconds)
Read or write current write timeout setting.

I interpreted this to imply that, following a write command, characters would be transmitted only for the time duration specified by write_timeout, and that any subsequent characters waiting in the output buffer would be omitted. In other words, I took it to mean that write_timeout allowed us to specify a 'time window' during which bytes would be transmitted and at the end of the window transmission would cease. (I can't actually think of any reason why you would wish to do this, but I'm sure there must be a use for it somewhere).

Eager to test the write_timeout function, I wrote the following simple program:

Code: Select all

import serial

ser = serial.Serial(port='/dev/ttyS0', baudrate=9600, timeout=1, write_timeout=0.01)

print (ser.write_timeout)

ser.write(b'Hello World! Hello World!')

print (ser.read(25))
Now, at 9600 baud, the character time is roughly 1ms, so my idea was that by setting write_timeout to 10ms, only the first ten characters of the "Hello World! Hello World!" string would be transmitted. I tested the program in 'loopback' mode (TX connected to RX) with a logic/protocol analyser connected to TX. (Incidentally, the third line is there simply to confirm that the write_timeout has been set and recognised correctly).

To my surprise, the protocol analyser displayed the entire string and the program returned:

0.01
b'Hello World! Hello World!'

What on earth is going on? I tried several different values for write_timeout but it made no difference - the entire string was always transmitted.

What's interesting is that when I changed the read timeout to 10ms (i.e., timeout=0.01), the program behaved exactly as you would expect:

0.01
b'Hello Worl'

That is, only the first ten characters were read, the remainder were ignored.

So either I've completely misunderstood the write_timeout functionality, or it just doesn't seem to be doing anything.

Comments welcome.

Thanks,

Tony.

User avatar
MrYsLab
Posts: 333
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: PySerial: Does "write_timeout" actually do anything?

Fri May 03, 2019 11:35 pm

The write timeout also takes into account the write buffer size. Here is a simple test program I wrote:

Code: Select all

import serial

b = bytearray()
for c in range(0, 64):
    b += str(5).encode()

print(b)
    
ser = serial.Serial(port='/dev/ttyACM0', baudrate=9600, timeout=1, write_timeout=0.01)

written = ser.write(b)
print(written)
and its output:

Code: Select all

bytearray(b'5555555555555555555555555555555555555555555555555555555555555555')
64
If you increase the range to 65, it will generate a write_timeout exception. Now if you increase the baud rate you can also increase the number of bytes written before seeing the write_timeout exception.

Unfortunately, the pyserial documentation does not document this very well, so the only way to verify the limits is to create some test code.

Anthony S
Posts: 40
Joined: Mon Apr 29, 2019 3:58 pm
Location: Bedfordshire, UK

Re: PySerial: Does "write_timeout" actually do anything?

Sat May 04, 2019 1:51 pm

Hi MrYsLab,

Many thanks for your suggestions and for your code.

I played around with your program on my Pi3B+ and found that I could output a maximum of 272 characters at 9600 baud with write_timeout=0.01. Increasing to 273 characters generated a write_timeout exception. I can only guess that the difference between my results and yours has something to do with the size of our write buffers. With write_timeout=0.001, I found that I could output 264 characters before generating a write_timeout exception. I haven't experimented with different baud rates but I have no doubt you are right that the maximum number of characters allowable before generating a write_timeout exception will be related to baud rate.

However, all of this seems rather academic. Surely the number of characters allowable before generating the write_timeout exception should be related only to the baud rate and to the value specified in the write_timeout. I can't see why it should be influenced by the size of the write buffer. The fact that we both get different results suggests that if the size of the write buffer is having an effect on the behaviour then it is a rather arbitrary effect.

I agree entirely that the pyserial documentation does not document this very well!

Thanks again,

Tony.

Return to “Python”