Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么串行读取(1)在收到字符后继续等待直到超时?_Python_Io_Pyserial - Fatal编程技术网

Python 为什么串行读取(1)在收到字符后继续等待直到超时?

Python 为什么串行读取(1)在收到字符后继续等待直到超时?,python,io,pyserial,Python,Io,Pyserial,以下代码通过串行接口与硬件通信。通信成功(硬件启动并报告正确位置),但读取命令始终大约需要s.timeout秒,几乎与s.timeout设置无关(s.timeout必须至少为~3s) 我想知道如何更改此代码,以便read命令在只收到一个字符后立即返回 import serial # installed as pyserial import time, io try: # Best guesses for an undocumented serial device s = ser

以下代码通过串行接口与硬件通信。通信成功(硬件启动并报告正确位置),但读取命令始终大约需要s.timeout秒,几乎与s.timeout设置无关(s.timeout必须至少为~3s)

我想知道如何更改此代码,以便read命令在只收到一个字符后立即返回

import serial # installed as pyserial
import time, io

try:
    # Best guesses for an undocumented serial device
    s = serial.Serial()
    s.port = 'COM1'
    s.baudrate = 9600
    s.timeout = 5
    s.open()

    # Device begins 18s init routine when serial communication established
    sio = io.TextIOWrapper(io.BufferedRWPair(s,s))
    time.sleep(18)
    start = time.time()
    dat = sio.read(1)
    print('Initial position is %s (%0.3fs reply)' % (dat, time.time()-start))

    # Move device from initial position to Position 2
    sio.write('2')
    sio.flush()
    start = time.time()
    dat = sio.read(1)
    print('New position is %s (%0.3fs reply)' % (dat, time.time()-start))

finally:
    del sio
    s.close()
输出:

Initial position is 0 (5.008s reply)
Moved to position 2 (5.003s reply)
Initial position is 0 (0.000s reply)
New position is 2 (2.887s reply)

在这段代码中有两件事我觉得很奇怪

  • 串行端口被一个缓冲区包装,但是如果您想逐个字符地控制硬件,这可能不是您想要的
  • BufferedRWPair
    应用于将两个单工流逻辑组合成一个双工流。但是,
    串行
    类已经是双工的

  • 我会尝试完全删除
    TextIOWrapper
    BufferedRWPair
    ,并直接调用
    Serial
    类的读写方法。

    当我直接使用Serial对象而不是通过TextIOWrapper时,我能够从read(1)中获得预期的行为,如下面的代码所示。不再需要time.sleep(),但我保留了它,以便将代码输出与原始post进行比较

    我使用的是Python3.7.3,继承自的文档没有明确声明读取N个字符后read(N)停止阻塞,尽管我认为有理由假设它应该停止阻塞。实际上,文档似乎建议read(size=1)是正确的实现,尽管以这种方式调用read会导致“read()不接受关键字参数”错误

    我对直接使用串行对象感到满意,但希望有人能为其他可能需要TextIOWrapper的人回答N个字符的问题

    import time, serial
    
    try:
        s = serial.Serial()
        s.port = 'COM1'
        s.baudrate = 9600
        s.timeout = 20
        s.open()
    
        time.sleep(18)
        start = time.time()
        dat = s.read(1)
        print('Initial position is %s (%0.3fs reply)' % \
              (dat.decode('utf-8'), time.time()-start))
    
        s.write('2'.encode())
        s.flush()
        start = time.time()
        dat = s.read(1)
        print('New position is %s (%0.3fs reply)' % \
              (dat.decode('utf-8'), time.time()-start))
    
    finally:
        s.close()
    
    输出:

    Initial position is 0 (5.008s reply)
    Moved to position 2 (5.003s reply)
    
    Initial position is 0 (0.000s reply)
    New position is 2 (2.887s reply)
    

    您使用的是哪个版本的Python?你在什么操作系统上运行它?@TarkaDaal Python 3.7.3在Windows上运行。自动使用的编码是cp1252。