私はリモート診断デバイスと通信するためにシリアルポートを使用しています。SerialPort.DataReceivedは定期的に購読/購読解除します
リモートデバイスからの応答の長さは、コマンドによって異なりますが、あらかじめわかっています。したがって、現在、私はコマンドを送信し、必要な数の応答バイトが受信されるのを待ちます。
私が積極的にデータを要求していないときはいつでも、 'SerialPort.DataReceived'イベントに登録します。このイベントのハンドラは、単に「迷惑な」受信データをログにダンプします(通常、リモートデバイスが予期せず再起動した場合にのみ非請求データが受信されます)。
場合によっては、約60Hzの速度でコマンドを送信したいと考えています。
私の質問は、私が 'SendCommand'メソッドを呼び出してデータを積極的に求めてくるたびに 'SerialPort.DataReceived'イベントを購読/購読解除するのが最善かどうかです。あるいは、イベント購読だけを残して、私が積極的にそれを求めているときにDataReceivedハンドラが着信データを無視するために使用できるTransferInProgressフラグ?私が正しく、単にDataReceivedハンドラ内のすべての受信データを処理したり、一つの他のオプションを持っているだろう理解していた場合
public virtual bool SendCommand(byte[] command, ref byte[] response) {
try {
TransferInProgress = true;
OnTransferStarted();
// temporarily unsubscribe since we're actively soliciting data
_port.DataReceived -=
new SerialDataReceivedEventHandler(SerialPort_DataReceived);
_port.DiscardInBuffer();
_port.Write(command, 0, command.Length);
OnCommandSent(command);
// read the requested number of response bytes
int responseBytesRead = 0;
while (responseBytesRead < response.Length) {
responseBytesRead +=
_port.Read(response, responseBytesRead, (response.Length - responseBytesRead));
}
OnCommandResponseReceived(response);
return true;
}
catch (Exception ex) {
OnCommandSendFailed(ex.Message);
return false;
}
finally {
_port.DataReceived +=
new SerialDataReceivedEventHandler(SerialPort_DataReceived);
OnTransferComplete();
TransferInProgress = false;
}
}
-Trevor
キューを使用してコマンドを追跡するというアイデアは気に入っていますが、私は迷惑なデータをどのように検出できるのでしょうか?この方法を使用して、リモートデバイスがコマンドの間に数バイトを発生させるかどうかをどのように判断できますか? (注:リモートデバイスは時折、自分自身をリセットしていくつかの 'スタートアップ'タイプのバイトを送信するようですが、残念なことにこれを制御できません)。 – user158485
あなたはまだデータ受信ハンドラで迷惑なデータを検出していますが、 "SentCommandsQueue"にコマンドがないため、迷惑だとわかるでしょう。 私はシリアル通信で同様の問題を抱えていました。受信したデータをバッファリングして、リセットメッセージを解析する回答をまとめる必要があります。完全な応答が得られたら、キューからコマンドを削除します。リセットバイトはシーケンスの先頭に何らかの署名があるように見えるので、簡単にそれらを解析することができます。 – nathan
私はおそらくこのようなものを実装できると思います。私の唯一の予約は、リセットバイトが必ずしも同じではない(順序または数量で)ため、リセットされたデータが通常のコマンドの間に受信された場合に、意図しないオフセットで終わる可能性があります。 つまり、この特定のシリアルデバイスにはコマンドエコーを有効にするオプションがあると思います。レスポンス配列の解析中に、コマンドヘッダを識別ヘッダとして使用できます。 – user158485