Python串口模块pySerial缓冲区无法清空

16

我在Windows和Linux下使用pySerial进行串行IO时遇到了问题。使用这段代码,设备从未收到命令并且读取超时:

import serial
ser = serial.Serial('/dev/ttyUSB0',9600,timeout=5)
ser.write("get")
ser.flush()
print ser.read()

这段代码第一次执行会超时,但是后续的迭代会成功:

import serial
ser = serial.Serial('/dev/ttyUSB0',9600,timeout=5)
while True:
    ser.write("get")
    ser.flush()
    print ser.read()

有人能告诉我发生了什么吗? 我尝试添加一个sync()调用,但它不会接受一个串行对象作为参数。

谢谢, 罗伯特

4个回答

23

在写入和读取之间加入一些延迟,例如:

import serial
ser = serial.Serial('/dev/ttyUSB0',9600,timeout=5)
ser.flushInput()
ser.flushOutput()
ser.write("get") 

# sleep(1) for 100 millisecond delay
# 100ms dely
sleep(.1)
print ser.read()

7
通常来说,为了解决问题而增加延迟是不明智的,除非你的设置中某些特定硬件需要物理或电气上的延迟。通常情况下,有更好的解决方法。 - josh798
这些方法已经被废弃,现在使用 reset_input_buffer()reset_output_buffer() 替代,详情请见:doc - Bruno L.

5
这是因为在串口打开之前,pyserial就已经返回了。例如,在open()之后立即调用flushInput()方法,并不能真正清空输入缓冲区。以下是演示代码:
import unittest
import serial
import time
"""
1) create a virtual or real connection between COM12 and COM13
2) in a terminal connected to COM12 (at 9600, N81), enter some junk text (e.g.'sdgfdsgasdg')
3) then execute this unit test
"""

class Test_test1(unittest.TestCase):
    def test_A(self):
        with serial.Serial(port='COM13', baudrate=9600) as s:   # open serial port
            print("Read ASAP:  {}".format(s.read(s.in_waiting)))
            time.sleep(0.1)     # wait for 100 ms for pyserial port to actually be ready
            print("Read after delay:  {}".format(s.read(s.in_waiting)))

if __name__ == '__main__':
    unittest.main()

"""
output will be:
Read ASAP:  b''
Read after delay:  b'sdgfdsgasdg'
.
----------------------------------------------------------------------
Ran 1 test in 0.101s
"""

我的解决方法是在打开后延迟100毫秒再执行任何操作。


5

这个问题很古老,但我觉得这可能是一个相关的补充。

一些设备(例如Agilent E3631)依赖于DTR。一些超便宜的适配器没有DTR线路(或没有将其分离),使用这些适配器,这些设备可能永远无法按预期工作(读写之间的延迟变得非常长)。

如果你发现自己在与这样的设备搏斗,请建议购买一个带有DTR的适配器。


4

非常抱歉,这个解决方法可能已经比较老旧并且对一些人来说很明显,但是我并没有在这里看到有人提到这种选项。当 flush 没有处理我的硬件时,我最终调用了一个 read_all()

# Stopped reading for a while on the connection so things build up

# Neither of these were working
conn.flush()
conn.flushInput()

# This did the trick, return value is ignored
conn.read_all()

# Waits for next line
conn.read_line()

read_all 对我来说似乎是唯一的解决方案。我在想这也可能是 Python 处理线程的 bug?无论如何,这种行为非常“奇怪”。我有一个递归函数,即使条目重置了更高级别的 Python 读取流,它仍然不断地堆积起来。 - Jamie Nicholl-Shelley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接