Pyserial:readline() 是阻塞的,虽然定义了超时

Posted

技术标签:

【中文标题】Pyserial:readline() 是阻塞的,虽然定义了超时【英文标题】:Pyserial: readline() is blocking, although timeout is defined 【发布时间】:2021-01-26 10:57:22 【问题描述】:

我对来自 pyserial 的 readline() 有疑问。 我的代码是:

import serial

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

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

我正在从微控制器接收数据。问题是,如果没有从 mc 发送数据,程序将“永远”等待,尽管我定义了 3 秒的超时。 我做错了什么?

【问题讨论】:

【参考方案1】:

好的,我找到了解决办法

问题是,Raspberry Pi 3 和 4 使用“miniUART”作为主 UART,而 Raspberry Pi 1 和 2 使用“PL011”。 您可以在这里查看详细信息:https://www.raspberrypi.org/documentation/configuration/uart.md

要使超时中断起作用,您必须将“PL011”更改为 UART0。默认情况下,UART0(GPIO 14 和 15)设置为“miniUART”,“PL011”用于蓝牙调制解调器。

您必须编辑/boot/config.txt 并添加dtoverlay=disable-bt。 您还必须使用sudo systemctl disable hciuart禁用初始化调制解调器的系统服务,因此它不会连接到UART。

我已经这样做了,现在程序等待消息超时并继续,如果没有收到消息。

【讨论】:

我不想相信这是我的问题,但确实如此。很棒的收获。【参考方案2】:

超时只会影响 readline() 等待的最长时间

timeout = x:设置超时为x秒(允许浮点数)当请求的字节数可用时立即返回,否则等到超时到期并返回直到那时接收到的所有字节

试试这个:

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()

【讨论】:

感谢您的回答我已经尝试过您的代码,但结果是一样的。 readline() 等待的时间长于设置的超时时间(在本例中为 3 秒) 你能用 realines 代替 readline 吗? readlines() 是一样的,但是我又发现了一个。我使用 Raspberry Pi 3 运行 python 代码。我在 Raspberry Pi 2 上测试了相同的代码,一切都按预期工作。 (Python3 和 Pyserial 的版本相同)我知道,Pi2 和 3 使用不同的 UART,您可以在这里阅读:raspberrypi.org/documentation/configuration/uart.md 所以我想问题不是我的代码,而是 pyserial 本身或我的硬件的问题.感谢您的帮助。

以上是关于Pyserial:readline() 是阻塞的,虽然定义了超时的主要内容,如果未能解决你的问题,请参考以下文章

Pyserial readline() 永远挂起程序而不读取串行数据

Pyserial readline() 并等到收到一个值才能继续

在另一个线程中中断 pySerial readline

python pyserial readline 不工作,但 screen 有点工作,在 ubuntu 16 中工作

PySerial 读取问题

PySerial 和值拆分错误