Pyserial 与虚拟端口不能很好地配合

问题描述 投票:0回答:3

动机

我想开始学习如何使用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

这是怎么回事?

调试失败

这家伙说他使用python 2.6时成功了。我无法让 Pyserial 与 2.6 一起工作。

这个家伙在波特率方面遇到了麻烦。我使用命令

$stty -F /dev/pts/2
仔细检查了我的波特率,并确认它的波特率实际上是 9600。

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

我的问题

如何让我的serialtest.py脚本运行而不出错?

python serial-port pyserial socat virtual-serial-port
3个回答
18
投票

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

#!/usr/bin/env python
import serial

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

请参阅此 PySerial Github 问题以获取更多说明。


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


0
投票

对于任何使用 ESP32 或使用 DTR/RTS 线进行 GPIO0/复位编程的类似板的人,请注意这行代码:-

self.serial = serial.Serial(device, **serial_kwargs)

触发底层 python 库中的一个错误,该错误会在 RTS 线上产生脉冲电压(这会导致 ESP32/etc 重置)。

以下是防止那些不需要的脉冲/重置的解决方法:

self.serial = serial.Serial()
self.serial.port = device
self.serial.baudrate = serial_kwargs["baudrate"]
self.serial.inter_byte_timeout = serial_kwargs["interCharTimeout"]
self.serial.exclusive = serial_kwargs["exclusive"]
self.serial.open()

如果您愿意,您也可以通过这种方式自己手动控制这些引脚:

self.serial.dtr = 0
self.serial.rts = 0

(Python 构造函数忘记允许我们指定这些)

© www.soinside.com 2019 - 2024. All rights reserved.