Pyserial 不能很好地使用虚拟端口

Posted

技术标签:

【中文标题】Pyserial 不能很好地使用虚拟端口【英文标题】:Pyserial does not play well with virtual port 【发布时间】:2016-01-16 19:24:24 【问题描述】:

动机

我想开始学习如何使用 python 库Pyserial。这似乎是一个非常好的图书馆,适用于很多人。我想在即将进行的项目中使用它,在该项目中我必须自动化串行通信。

环境

我正在运行 Ubuntu 15.04。我正在使用 Python 2.7。

设置虚拟端口

我目前没有可以通过串行端口与之通信的设备。我正在使用socat 应用程序创建两个以 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

太棒了!似乎端口可以工作!

一个简单的pyserial脚本

我使用 pip 安装 pyserial

$ sudo pip install pyserial

然后我写了一点serialtest.py

#!/usr/bin/env python
import serial

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

这就是整个serialtest.py

运行脚本并遇到错误

$ 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

这是怎么回事?

调试尝试失败

This guy说他用python 2.6成功了。我无法让 Pyserial 与 2.6 一起使用。

This guy 遇到了波特率问题。我使用命令$stty -F /dev/pts/2 仔细检查了我的波特率,并确认它实际上是波特率 9600。

This guy 还声称波特率有问题并将其归因于他的内核。那是在 2012 年,所以我认为它不再相关了。

我的问题

如何让我的 serialtest.py 脚本正常运行?

【问题讨论】:

见github.com/pyserial/pyserial/issues/59。 @AustinPhillips 你是一个很酷的家伙。我对串行通信和 RS-232 以及 readytosend/cleartosend 了解不多,因此您在 Pyserial wiki 上提出的问题在概念上对我来说并不清晰。但是,我盲目地反转了 serialposix.py 的第 310 和 312 行的逻辑,并再次尝试了我的脚本。有效!我现在可以使用 Pyserial 读写我的虚拟端口。尽管您似乎对自己的修复没有 100% 的信心,但我愿意接受它。感谢您的宝贵时间! 【参考方案1】:

为了完成这个问答,这是一个解决方案(在 Austin Philips 的链接中找到):

#!/usr/bin/env python
import serial

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

更多解释请参见PySerial Github issue。

【讨论】:

【参考方案2】:

根据 Sebastian 提到的问题,这个问题从 Pyserial 3.1 版本开始解决。

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

zsquareplusc 于 5 月 29 日发表评论

发布 3.1 哪里有错误设置 open() 中的控制线被忽略(但不会在以后的调用中)。

通过 pip、github 或下载页面更新:https://pypi.python.org/pypi/pyserial

【讨论】:

以上是关于Pyserial 不能很好地使用虚拟端口的主要内容,如果未能解决你的问题,请参考以下文章

不能多次写入同一个端口(pyserial)

pySerial:端口只工作第一个命令

如何使用 pyserial 将文件逐行写入 com0com?

使用 pySerial 控制发酵罐

我没有很好地关闭 --yarn dev- (端口 4444 已经在使用中。)

如何让 PySerial 接受 921600 波特率