23

PySerialモジュールを介してシリアルポートからデータを読み取るPythonプログラムがあります。覚えておく必要のある2つの条件は、次のとおりです。到着するデータの量がわからないことと、データをいつ期待するかわからないことです。

これに基づいて、次のコードスニペットを考え出しました。

#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文字でデータを保存し、フラグを設定してメインループに警告します。データが存在しない場合は、スリープ状態に戻って待機します。

コードは機能していますが、5秒のタイムアウトが気に入らないのです。どれだけのデータが期待できるかわからないので必要ですが、データがない場合でも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 = Noneread要求されたバイト数が存在するまで呼び出しがブロックされます。データが到着するまで待ちたい場合は、read(1)タイムアウトを指定してくださいNone。ブロックせずにデータをチェックしたい場合は、read(1)タイムアウトゼロでaを実行し、データが返されるかどうかをチェックします。

(ドキュメント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 に答える