23

我有一个 Python 程序,它通过PySerial模块从串行端口读取数据。我需要记住的两个条件是:我不知道有多少数据会到达,我不知道什么时候会收到数据。

基于此,我想出了以下代码片段:

#Code from main loop, spawning thread and waiting for data
s = serial.Serial(5, timeout=5)  # Open COM5, 5 second timeout
s.baudrate = 19200

#Code from thread reading serial data
while 1:
  tdata = s.read(500)    # Read 500 characters or 5 seconds

  if(tdata.__len__() > 0):        #If we got data
    if(self.flag_got_data is 0):  #If it's the first data we recieved, store it
      self.data = tdata        
    else:                         #if it's not the first, append the data
      self.data += tdata
      self.flag_got_data = 1

因此,此代码将永远循环从串行端口获取数据。我们将获得多达 500 个字符来存储数据,然后通过设置一个标志来提醒主循环。如果没有数据存在,我们将回到睡眠状态并等待。

代码正在运行,但我不喜欢 5s 超时。我需要它,因为我不知道需要多少数据,但我不喜欢它每 5 秒醒来一次,即使没有数据存在。

有什么方法可以在执行之前检查数据何时可用read?我正在考虑类似于selectLinux中的命令。

注意:我找到了该inWaiting()方法,但实际上这似乎只是将我的“睡眠”更改为投票,所以这不是我想要的。我只想睡觉,直到数据进来,然后去拿它。

4

3 回答 3

22

好的,我实际上为此得到了一些我喜欢的东西。使用read()无超时和inWaiting()方法的组合:

#Modified code from main loop: 
s = serial.Serial(5)

#Modified code from thread reading the serial port
while 1:
  tdata = s.read()           # Wait forever for anything
  time.sleep(1)              # Sleep (or inWaiting() doesn't give the correct value)
  data_left = s.inWaiting()  # Get the number of characters ready to be read
  tdata += s.read(data_left) # Do the read and combine it with the first character

  ... #Rest of the code

这似乎给出了我想要的结果,我猜这种类型的功能在 Python 中不作为单一方法存在

于 2012-10-22T19:19:48.397 回答
14

您可以设置timeout = None,然后read调用将阻塞,直到请求的字节数存在。如果您想等到数据到达,只需执行read(1)with timeout None。如果您想在不阻塞的情况下检查数据,请执行read(1)超时为零的操作,并检查它是否返回任何数据。

(请参阅文档https://pyserial.readthedocs.io/en/latest/

于 2012-10-22T19:08:52.920 回答
2
def cmd(cmd,serial):
    out='';prev='101001011'
    serial.flushInput();serial.flushOutput()
    serial.write(cmd+'\r');
    while True:
        out+= str(serial.read(1))
        if prev == out: return out
        prev=out
    return out

像这样称呼它:

cmd('ATZ',serial.Serial('/dev/ttyUSB0', timeout=1, baudrate=115000))
于 2015-11-18T18:17:29.080 回答