0

シリアル通信ポートに接続された計測器があります。Windows XP で Python 3.2 と pySerial モジュールを使用しています。通信ポートを開き、構成し、文字列を書き込み、通信ポートから文字列を受信する一連のステートメントで構成されるスクリプトを実行すると、問題が発生します。これらの文字列は、機器に関連するコマンド (制御) または機器からの応答 (応答) のいずれかです。

これらのステートメントが Python インタープリターで対話的に (>>> で) 実行されると、期待どおりの結果が得られ、結果は適切で正しいものになります。ただし、インタープリター内またはシェルからスクリプトを実行すると、必要なものが得られません。スクリプト内のステートメントは、対話型インタープリターで使用するものと同じです。

奇妙な動作をするのはなぜですか? また、対話型インタープリターのように動作するようにスクリプトを変更するにはどうすればよいですか?

def read(comport):

    wrt_str=b'movt 3000'+b'\r\n'
    ret_str=comport.write(wrt_str)

    wrt_str=b'scan'+b'\r\n'
    ret_str=comport.write(wrt_str)

    rsp_str=comport.readlines() #########1

    wrt_str=b'hllo'+b'\r\n'
    ret_str=comport.write(wrt_str)

    rsp_str=comport.readlines()#########2

問題は、上記の ####### の行にあります。対話モードでは、#1 で約 1 秒、#2 で 9 秒の遅延があります。私はそこで正しい反応を得ます。しかし、上記のスクリプトを実行すると、遅延はまったくなく、間違った結果 (ゴミ) が得られます。通信ポートのセットアップで読み取りタイムアウトを0に設定しました。

comport.timeout=0

そのため、comport が行末またはファイルの終わりを待つ場合は、ブロック モードにする必要があります。

更新 (2011 年 8 月 19 日)

数日前に作成した元の投稿を更新しました。私は問題が何であるかを知っていると思います。誰かが解決策を持っているかどうか知りたいです:

すべてのステートメントの後に「print」と「time.sleep(delay)」を配置した後、スクリプトが実行されているときに、「comport.write(..)」や「comport.readlines」などの pyserial ステートメントを回避しているように見えることがわかりました。 (...)" pyserial コマンドの実行中 (シリアル ポートが遅いことがわかります)。たとえば、Python インタラクティブ シェルですべてのステートメントを実行すると、前のステートメントが返されない場合、新しいステートメントを入力して実行することができません。そうですね、comport.readlines() が返されない場合、次の comport.write(...) ステートメントを入力して実行することはできません。ただし、実行中のスクリプトでは、comport.readlines() が読み取りでビジーである場合、次のステートメントが実行中であり、次のステートメントが読み取りを中止する comport.write() である場合です。

Pythonスクリプトを正確に順番に実行するように強制する方法はありますか?

4

3 に答える 3

2

私はpyserialのドキュメントを読みました:

timeout = None: wait forever
timeout = 0: non-blocking mode (return immediately on read)
timeout = x: set timeout to x seconds (float allowed)

comport.timeout=0 を設定すると、readlines() はすぐに戻ります。comport.timeout = 10 を設定してみてください。

于 2011-08-18T02:24:30.287 に答える
1

各コマンド文字列を独自の関数に貼り付けてから、一時停止して順番に呼び出してみます。

または、出力データ文字列の長さがわかっている場合は、read()/を設定してreadlines()、そのバイト数が経過した後に読み取りを停止するか、読み取り文字列が可変長の場合は任意の数値を設定できます。

于 2012-10-17T18:23:10.230 に答える
0

time.sleep(1)それぞれの後に(たとえば)一時停止を貼り付けてみてくださいcomport.write。これにより、応答を探す前に、デバイスが各コマンドに応答する時間が与えられます。

HYRYが指摘しているように、に設定timeoutするとすぐに戻るので、思ったとおり0に動作しません。ただし、ステートメントを1つずつ実行すると、各行に入力するときに遅延が発生します。それらをスクリプトで実行すると、間に大きなギャップなしで実行されます。

于 2011-08-18T23:17:54.173 に答える