Aterus
Aterus

Reputation: 555

Pyserial: readline() is blocking, although timeout is defined

I have an issue with readline() from pyserial. My code is:

import serial

uart = serial.Serial(port='/dev/ttyS0', baudrate=9600, timeout=3)

data = uart.readline().decode()
print(data)
uart.close()

I'm receiving data from a microcontroller. The problem is, if no data is send from the mc, the program is waiting "forever", although I defined a timeout of 3 seconds. What am I doing wrong?

Upvotes: 2

Views: 5015

Answers (2)

Aterus
Aterus

Reputation: 555

Ok, I have discovered the solution

The problem is, that the Raspberry Pi 3 and 4 uses the "miniUART" as the primary UART and the Raspberry Pi 1 and 2 uses the "PL011". You can the details here: https://www.raspberrypi.org/documentation/configuration/uart.md

To get the timeout break working, you have to change the "PL011" to UART0. By default UART0 (GPIO 14 and 15) is set to "miniUART" and "PL011" is used for the bluetooth modem.

You have to edit the /boot/config.txt and add dtoverlay=disable-bt. You also have to disable the system service, that initialises the modem, so it does not connect to the UART, using sudo systemctl disable hciuart.

I have done that and now the program waits the timeout for a message and goes on, if no message is received.

Upvotes: 4

Belhadjer Samir
Belhadjer Samir

Reputation: 1659

timeout will only affect the maximum time that readline() will wait

timeout = x: set timeout to x seconds (float allowed) returns immediately when the requested number of bytes are available, otherwise wait until the timeout expires and return all bytes that were received until then

try this :

import serial
uart = serial.Serial(port='/dev/ttyS0', baudrate=9600, timeout=3)
while True:
   data = uart.readline().decode()
   print(data)
   if not data :
      break
uart.close()

Upvotes: 0

Related Questions