当我用Python刷新串行缓冲区时,它会停止读取

时间:2013-02-23 20:30:07

标签: python serial-port arduino pyserial

我编写了一个Arduino来将数据串行发送到我的电脑。 pySerial正在从串口中正确读取,但由于我总是希望获得最新的信息,我以为我可以使用flushInput()刷新输入缓冲区,但是当执行命令时,我再也无法读取连载。我尝试每次只刷一次51次(因为51是一个素数,我可以很容易地用计数器计数51次而不必重置它),这样Arduino就有足够的时间发送下一个数据包(运行在57600波特) ),但仍然无法正常工作。也就是说,我使用了一个变量来使用deadline()来存储读取行的长度,但是,一旦我达到51并且输入缓冲区被刷新,我总是得到0的读数,这意味着它不会读取任何内容。我已经阅读了pySerial的文档,但没有找到任何相关信息。 flushInput()也会终止串行连接吗?非常感谢。

编辑:我正在运行Mac OS 10.7.5和Python 2.7.3

try:
    self.s = serial.Serial("/dev/tty.usbmodemfa131", 57600, timeout = 0)
    self.FlightLoopCB = self.FlightLoopCallback
    XPLMRegisterFlightLoopCallback(self, self.FlightLoopCB, self.interval, 0)
except serial.SerialException:
    self.s = None
    .
    .
    .

    self.length=0
    self.myline=self.s.readline()
    self.length=len(self.myline)
    print "Test: %i %i" % (self.length, self.j)
    if(self.length>=7):
        if(self.myline[0:2]=="R,"):
            if(self.j%51==0):
                self.s.flushInput()

            self.length=len(self.myline)
            self.myline=self.myline[2:6]
            self.myLineBytes=[0,0]

            self.myLineBytes[0]=unpack('>H', self.myline[0:2])
            self.myLineBytes[1]=unpack('>H', self.myline[2:4])

1 个答案:

答案 0 :(得分:9)

Serial.flushInput()是否也关闭了广告资源?

所以我深入研究了pySerial的代码(可用,you can pull it over SVN,如果你有进一步的麻烦,我建议你这样做。)

由于您使用的是OSX,因此python会将os.name报告为“posix”,因此serial.Serial实际上会解析为serial.serialposix.SerialflushInput()的定义是:

def flushInput(self):
    """Clear input buffer, discarding all that is in the buffer."""
    if not self._isOpen: raise portNotOpenError
    termios.tcflush(self.fd, TERMIOS.TCIFLUSH)

(如果你想看到它,那就是第500行的here

所以基本上它只是termios.tcflush()的包装器。 docs就是这样说的:

  

termios.tcflush(fd,queue)

     

丢弃文件描述符fd上的排队数据。队列选择器指定哪个队列:输入队列的TCIFLUSH,输出队列的TCOFLUSH或两个队列的TCIOFLUSH。

根据文档,然后关闭基础流,只丢弃数据。这可能是你首先想到的行为。

这让我想到你的代码可能还有其他问题。没有足够的发布代码能够推断出究竟问题是什么。

这只是一个猜测,但也许增加self.j的代码在一个块中,在它到达51之后没有被调用,所以你总是在冲洗?如果您可以发布一个产生问题的完整代码示例(可能是一些简化的代码集,它只是解决了您正在看到的问题),那么我可能会提供帮助。

PS - 关于过早优化的说明:

除非在串行接口的另一端产生数据产生数据的速度远远超过你所消耗的数据,否则可能首先不需要刷新,因为不会产生大量数据在缓冲区。不知何故,我怀疑运行在57600波特的串行接口是否能够做到这一点。在进行冲洗之前,您应该检查并确保首先实际需要冲洗。

不要仅因为您认为可能需要或“只是为了确保”而这样做。在做之前检查它是否真的解决了问题,否则这是一个过早的优化,它只是无缘无故地增加了代码的复杂性和脆弱性。