重启后Pyserial的串行连接问题

Posted

技术标签:

【中文标题】重启后Pyserial的串行连接问题【英文标题】:Serial connection problem with Pyserial after reboot 【发布时间】:2020-05-15 17:10:27 【问题描述】:

我有一个 Python 脚本可以通过 RS232 串行端口与测量仪器进行通信。 一切正常,但每次我打开电脑(Windows 10)时,通信一开始就无法正常工作。我必须打开一个串行终端(例如 hterm)按“连接”和“断开”按钮。之后,Python 脚本按预期工作,从仪器读取和写入都没有问题。 下面是一个简短的代码示例:

import serial, time
ser = serial.Serial(port='COM6', baudrate=19200, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=0, xonxoff=False, rtscts=False, dsrdtr=False)
time.sleep(1)
print(ser.isOpen()) #output: true
ser.write(b'READ:CH1\r\n')
time.sleep(1)
print("read:" + ser.read(18).decode('utf-8'))
ser.close()
print(ser.isOpen()) #output: false

仪器没有收到数据“READ:CH1”或任何其他命令。因此,没有通过 ser.read() 向 PC 传输任何数据。 我尝试了硬件握手和很长的睡眠时间的所有可能性。我猜Windows和Pyserial之间存在问题。在 Python 中,端口是打开的,但 Windows 不发送数据。你有什么想法我能做什么吗? 感谢您的帮助。

最好的问候

使用解决方案编辑:

除了“Serial.flushInput()”和“Serial.flushOutput()”之外,您还需要“Serial.reset_input_buffer()” em>”和“Serial.reset_output_buffer()”。

【问题讨论】:

ser.write(b'READ:CH1\r\n')之前有没有试过阅读,也许那里有什么。 感谢您的帮助。我现在试了,什么都没有。 "代替或附加到 "Serial.flushInput()" 和 "Serial.flushOutput()" ..." -- 这没有意义,因为后者只是前者的重命名版本。以前的例程自 3.0 版以来已被弃用,并已分别重命名为 reset_input_buffer() 和 reset_output_buffer()。见***.com/questions/61596242/… github.com/pyserial/pyserial/issues/329 【参考方案1】:

如果您使用的是第三方工具并且脚本运行良好,那么我认为任何一方的缓冲区中都存在一些垃圾数据,刷新硬件设备上的串行端口和 python 脚本也可能工作并验证在硬件设备上接收到的数据可能会在命令上附加垃圾,还可以尝试使用一些头位来防止这种通信中的错误。

使用一些串口嗅探器来验证正在发送的内容,例如this

【讨论】:

感谢您的帮助。在向设备发送数据之前,我添加了命令“ser.flushInput()”和“ser.flushOutput()”。我已经在完整的脚本中实现了它。但是即使 PC 发送垃圾,如果设备收到未知命令,每次都会向 PC 发送“NO”。我用示波器测量了信号线(RX/TX)的电压。 PC根本不发送任何东西。第三方软件中有一个命令,在按下“连接”后物理打开 COM 端口,但在我的 Python 代码中没有。 您需要“Serial.reset_input_buffer()”和“Serial.reset_output_buffer()”来代替“Serial.flushInput()”和“Serial.flushOutput()”。现在效果很好。 实际上,正如@sawdust 所建议的那样,它们是flushInput 和flushOutput 的重命名版本,因为它们现在已被弃用。看看pyserial.readthedocs.io/en/latest/pyserial_api.html,很高兴听到它现在起作用了,干杯!【参考方案2】:

看https://github.com/pyserial/pyserial/issues/329

https://github.com/pyserial/pyserial/issues/329#issuecomment-400852426

https://github.com/pyserial/pyserial/issues/329#issuecomment-503059537

你看到了吗?

另一个可能相关的问题:

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

您可以尝试的另一件事是先打开和关闭端口。

这和你用 hterm for 做的事情是一样的

ser = serial.Serial()
time.sleep(1)
print(ser.isOpen()) #output: true
ser.close()

ser = serial.Serial()
time.sleep(1)
print(ser.isOpen()) #output: true
...

这行得通吗?

【讨论】:

以上是关于重启后Pyserial的串行连接问题的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Pyserial 中打开串行连接:“termios.error: (22, 'Invalid argument')”

如何为pyserial读取运行线程

PySerial 报告看似未使用的串行端口的“资源忙”

从 Pyserial 读取串行输出不能可靠地工作

使用 pyserial 识别给定 USB VID 和 PID 的 USB 到串行端口

使用pyserial测试usb到串口到usb没有输出