pySerial缓冲区不会刷新

发布于 2024-12-02 13:24:02 字数 470 浏览 0 评论 0原文

我在 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()的调用,但它不会将串行对象作为参数。

谢谢, 罗伯特

I'm having a problem with serial IO under both Windows and Linux using pySerial. With this code the device never receives the command and the read times out:

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

This code times out the first time through, but subsequent iterations succeed:

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

Can anyone tell what's going on? I tried to add a call to sync() but it wouldn't take a serial object as it's argument.

Thanks,
Robert

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

错々过的事 2024-12-09 13:24:02

在写入和读取之间设置一些延迟
例如

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

Put some delay in between write and read
e.g.

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()
静水深流 2024-12-09 13:24:02

问题确实很老,但我觉得这可能是相关的补充。

某些设备(例如 Agilent E3631)依赖于 DTR。一些超便宜的适配器没有 DTR 线(或者 不要损坏它out),并且使用这些设备,此类设备可能永远不会以预期的方式运行(读取和写入之间的延迟变得非常长)。

如果您发现自己在使用此类设备,我的建议是购买带有 DTR 的适配器。

Question is really old, but I feel this might be relevant addition.

Some devices (such as Agilent E3631, for example) rely on DTR. Some ultra-cheap adapters do not have DTR line (or do not have it broken out), and using those, such devices may never behave in expected manner (delays between reads and writes get ridiculously long).

If you find yourself wrestling with such a device, my recommendation is to get an adapter with DTR.

谜兔 2024-12-09 13:24:02

这是因为 pyserial 在端口实际准备好之前就从打开端口返回。我注意到像flushInput()这样的东西实际上并没有清除输入缓冲区,例如,如果在open()之后立即调用。以下是演示代码:

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 毫秒的延迟。

This is because pyserial returns from opening the port before it is actually ready. I've noticed that things like flushInput() don't actually clear the input buffer, for example, if called immediately after the open(). Following is code to demonstrate:

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
"""

My workaround has been to implement a 100ms delay after opening before doing anything.

小ぇ时光︴ 2024-12-09 13:24:02

抱歉,这对某些人来说已经过时且显而易见,但我没有看到这里提到这个选项。当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()

Sorry that this is old and obvious to some, but I didn't see this option mentioned here. I ended up calling a read_all() when flush wasn't doing anything with my hardware.

# 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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文