Python PySerialモジュールを介してシリアルポートからデータを読み取るプログラムです。注意する必要がある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
を実行する前にデータが利用可能になったことを確認する方法はありますか? Linuxのselect
コマンドのようなものを考えています。
注:inWaiting()
メソッドを見つけましたが、実際には「スリープ」をポーリングに変更するだけなので、ここでは望んでいません。データが入るまでスリープ状態にしてから、取得します。
わかりました、私は実際に私がこれのために私が好む何かを得た。タイムアウトなしの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の単一のメソッドとして存在しないと思います
_timeout = None
_を設定すると、read
呼び出しは、要求されたバイト数になるまでブロックされます。データが到着するまで待機する場合は、タイムアウトNone
を指定してread(1)
を実行します。ブロックせずにデータを確認する場合は、タイムアウトゼロでread(1)
を実行し、データが返されるかどうかを確認します。
(ドキュメントを参照してください http://pyserial.sourceforge.net/pyserial_api.html )
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))