【解決方法】複数のコマンドをシリアル ポートに送信し、応答を待ってから別のコマンドを送信する


こんにちは、みんな、

受信したシリアル ポート データについてヘルプを求めてください。

複数のコマンドを保存したファイルがあります。
コマンドを1つずつシリアルポートに送信し、応答を待って表示し、他のコマンドを送信し続ける必要があります。

各コマンド送信の間に thread.sleep を使用していますが、機能しません。

助けてください。

ありがとう

私が試したこと:

I'm using thread.sleep between each command send but it does not work. 

解決策 1

Thread.Sleep で遊ぶのはやめましょう。おそらく役に立たないでしょう。
私が行う方法は、コマンドのキューを設定し、DataReceived イベントを使用して応答を取得することです。 応答が完了したら、次のコマンドをキューから取り出して送信し、DataReceived イベントで応答を処理させます。
キューが空になると、一連のコマンドが完了します。

解決策 2

一般に、アプリケーションのブロックを回避するために、すべての非同期 IO 操作は独自のスレッドで実行する必要があります。 そうしないと、GUI に遅延が発生するか、最悪の場合、GUI が完全にブロックされます。

あなたの場合、応答を受信し、キューに入れられたコマンドを送信するために、少なくとも 1 つのスレッドが必要です。

受信スレッドは、完全な応答が受信されるまでデータをバッファする必要があります。 これを行う方法は、データによって異なります (たとえば、テキスト データでの改行、またはプロトコル ヘッダーで通知されたバイト数の受信後)。

完全な応答が受信されると、これが他のスレッドに通知されます。 あなたの場合、これは応答を表示するメイン(GUI)スレッドと、次のコマンドの送信を有効にする送信キューになります。 スレッドから GUI 要素にデータを渡すには、特別な処理が必要であることに注意してください。

送信スレッドは、とにかく待機する必要があるため、ブロッキング呼び出しを使用して単純に送信できます。 送信後、応答受信信号を待つ必要があります。

送信と受信を 1 つまたは 2 つのスレッドに入れることができます。

受信用の擬似コード (テキスト データを想定):

C#
// Check for kill (terminate thread) event (wait with no timeout)
while (!KillEvent)
{
    do 
    {
        // Blocking call until a character is available
        // Should have a timeout and corresponding handling (break here)
        rxChar = ReceiveChar();
        Buffer += rxChar;
    }
    while (rxChar != '\n');
    // Signal other threads that a response has been received
    // Pass a copy of Buffer to the main thread for display
}

送信スレッドでは、コマンド送信後に上記を呼び出すか、受信が自スレッドで行われる場合はイベントを待ちます。

呼び出しを避けるスレッドとイベントの使用 sleep これは通常避けるべきであり、システム時間が無駄にならないようにする必要があります。

解決策 3

私の SerialDevice ここにクラス:
GPIB/Visa/シリアルインターフェースのマルチスレッド通信[^]

上記の Solution2 で説明したプロセスを正確に実装します。非同期コマンドを使用すると、I/O は、書き込み/読み取り用の単純なブロック呼び出しを使用する別のスレッドで実行されます。

解決策 1 に関する 1 つのコメント: DataReceived イベントは非 UI スレッドで呼び出されるため、スレッドを使用する場合は、とにかくスレッドについて何かを学ぶ必要があります (たとえば、DataReceived ハンドラーは、同期されたコールバックを呼び出して共有フィールドの問題を回避することができます)。 UI コンポーネント)。

解決策 4

その間に、DataReceived ハンドラーを使用せずに解決策を見つけました。
コマンドをシリアルポートに書き込み、書き込み後にシリアルポートから応答を読み取るだけです。
そして、私が探しているものに従って動作します。

しかし、これが正しい方法かどうかはわかりません。
例:
書く();
読む();

コメント

タイトルとURLをコピーしました