Skip to main content
 首页 » 编程设计

python之当我在 Python 中刷新串行缓冲区时,它停止读取

2025年05月04日16虾米姐

我对 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]) 

请您参考如下方法:

Serial.flushInput() 是否也关闭流?

所以我深入研究了 pySerial 的代码(它是可用的,you can pull it over SVN, 我建议你这样做,如果你有更多的麻烦你想弄清楚)。

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

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)

Discard queued data on file descriptor fd. The queue selector specifies which queue: TCIFLUSH for the input queue, TCOFLUSH for the output queue, or TCIOFLUSH for both queues.

然后根据文档,它不会关闭底层流,只会丢弃数据。这可能是您最初期望的行为。

这让我说您的代码可能还有其他问题。发布的代码不足,无法推断出问题所在。

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

PS -- 关于过早优化的注释:

除非在串行接口(interface)的另一端产生数据的速度比你消耗的速度快得多,否则可能一开始就不需要刷新,因为不会积累大量数据在缓冲区中。不知何故,我怀疑以 57600 波特率运行的串行接口(interface)是否能够做到这一点。在执行此操作之前,您应该首先检查并确保确实需要冲洗。

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