0

(編集者注。おそらく関連: SerialPort クラス)

コマンドを RFID リーダーに送信し、「回答」を受信しようとしています。

たとえば、リーダーがタグを読み取ることができる場合は、UID を受け取りますport.Write("S")port.ReadLine()

私は次のようにSerialDataReceivedEventHandlerを使用しています:

port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    port.ReadLine();  
}

そして、これは私がコマンドを送信している場所です:

public void sendData()
{
    port.Write("S");
    port.Write("r01");
    port.Write("r02");
}

ここでの問題は、「S」に対する最初の応答しか受信せず、3 行すべてが送信されないことです。問題は、3 つのコマンドすべてをリーダーに送信する方法がわからないことです。

無視すると、次のSerialDataReceivedEventHandlerコードを使用できることがわかります。

public void sendandreceive()
{
    port.Write("S");
    port.ReadLine();
    port.Write("r01");
    port.ReadLine();
}

そのコードは、コマンドと応答の両方を送受信します。しかし、 を使用することをお勧めしますSerialDataReceivedEventHandler

4

2 に答える 2

1

DataReceived イベントが発生すると、さらにデータが到着しない限り、再度発生することはありません。何が起きているかというと、シリアル ポートのバッファには 3 つの応答がすべて含まれているのに、1 つしか読み取っていないということです。

解析する必要があるメッセージ構造がある場合、DataRecived の使用は複雑になる可能性があります (各メッセージは EOL ターミネータで終了します)。この問題を解決する方法はたくさんあります。

使用可能なすべてのバイトをバッファーに読み取り、完全なメッセージを取り出してから、メッセージごとに 1 つずつ別のイベントを発生させることができます。バッファに部分的なメッセージがある場合は、次の DataReceived イベントまでそのままにしておきます。

操作全体 (上記の例では sendandreceive) を、完了時に通知する非同期操作として実行できます。これが最も簡単な方法です。SerialPort.ReadLine は、時間内に完全な「行」を取得しない場合、タイムアウトして TimeoutException をスローする可能性があることに注意してください。このため、これは最も堅牢なソリューションではありません。操作がタイムアウトした場合の対処方法を検討する必要があります (バッファに不完全なメッセージがある可能性があります)。

どの方法を使用するかは、アプリケーションの性質によって異なります。プロトコルは常に「コマンドを送信し、応答を取得する」ですか? または、一部のコマンドは連続応答になりますか?

シリアル通信を正しく (堅牢に) 行うことは困難です。最も簡単な解決策から始めて、慎重にテストします。

于 2012-08-09T21:59:25.413 に答える
0

メソッドを使用すると問題なく動作sendandreceiveするので、これを使用し、使用しませんSerialDataReceivedEventHandler

すべてのシリアルポートの例で使用されているため、少し混乱しましたSerialDataReceivedEventHandler

それでも、問題なく動作すると言う前に、テストする必要があります。そうは言っても、私は他の提案を受け入れています。

于 2012-08-10T12:04:42.210 に答える