数据可用时串口read()不返回(python / cygwin)

时间:2017-05-01 15:33:37

标签: python cygwin pyserial

我在PC上使用Cygwin使用pySerial访问串口。 我的comport是连接到响应查询的设备的USB comport。 我们有36个comports,我使用的是COM36(/ dev / ttyS35)。

鉴于我们的库,我需要继续使用python 2.7。 我在端口上执行read(),它总是等待,直到我请求的数据的长度完全被读取,而不是像C ++那样在数据可用时返回。

使用'超时'参数不是一个选项,因为它会强制它每次都等待超时。太短,它错过了数据和旋转占用处理器时间,太长时间,它会减慢程序的速度。我知道在我的C ++应用程序中,库会等到读取至少一个字节并继续读取更多内容,直到有一个重要的'在返回之前读取字节之间的暂停我想要python中的行为。

当我看到“interCharTimeout”时,我以为我找到了答案。串行构造函数,但是没有用。它仍然挂起,直到读取所有100个字节。 然后我查看了PySerial代码,看起来它没有在对象中设置正确的var(我可能是错的),所以我调用了#set; SetInterCharTimeout'方法直接。但结果仍然相同。

这是我的简单代码示例。

#!/bin/env python

import serial
from lib.Hex import *

# COM35, a USB serial port
s = serial.Serial(port="/dev/ttyS34", baudrate=19200, interCharTimeout=0.01)
s.close()
s.open()
s.setInterCharTimeout( 0.01 )
s.setTimeout( 2 )

# Send message the causes the device to generate a reply
data = fromHex( "AABB01072851EE" )
s.write( data )

data = s.read(100) # Note: this does return data if 'timeout' was used
print "Got: ", toHex(data)

我读了posixserial.py代码,我看到Serial总是循环,直到读完所有字节。然后我看到有PosixPollSerial覆盖了read()。我试着用它。

 s = serial.PosixPollSerial(port="/dev/ttyS34", baudrate=19200, interCharTimeout=0.1)

但我得到了这个错误:

Traceback (most recent call last):
File "./go2.py", line 18, in <module>
  data = s.read(100)
File "/usr/lib/python2.7/site-packages/pyserial-2.7-py2.7.egg/serial/serialposix.py", line 672, in read
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'

serialposix.py中的第672行是:

672                 for fd, event in poll.poll(self._timeout*1000):

1 个答案:

答案 0 :(得分:0)

检查以下内容:

  

pySerial 3.0文档serial.Serial.in_waiting
  的 in_waiting
      Getter:获取输入缓冲区中的字节数
      输入:int
      返回接收缓冲区中的字节数       在3.0版中更改:从inWaiting()

更改为属性

例如,阅读所有等待或至少1 serial.in_waiting or 1

B_SIZE = 10

def RxEvent(b):
    print('RxEvent(%s) %d' % (b, len(b)))

def Thread_serial_read(serial, alive, rxEvent):
    serial.timeout = 0.5  # make sure that the alive event can be checked from time to time
    n = 0
    b_tmp = []
    while alive.isSet():
        time.sleep(0.25)
        b = serial.read(serial.in_waiting or 1)
        if b:
            b_tmp.extend(b)
            n += len(b)
            if n >= B_SIZE:
                rxEvent( b_tmp[:B_SIZE] )
                b_tmp = b_tmp[B_SIZE:]
                n = len(b_tmp)

if __name__ == '__main__':
    alive = threading.Event()
    Thread_serial_read(Serial(), alive, RxEvent)

使用Python测试:3.4.2和2.7.9