我正在使用串行端口與遠程診斷設備進行通信。SerialPort.DataReceived重複訂閱/取消訂閱
來自遠程設備的響應長度因命令而異,但會提前知道。所以,目前我發送命令並等待接收到所需數量的響應字節。
無論何時我沒有主動請求數據,我都會訂閱'SerialPort.DataReceived'事件。這個事件的處理程序只是簡單地將任何'主動'收到的數據轉儲到日誌中(通常只有在遠程設備意外重啓時纔會收到未經請求的數據,等等)。
在某些情況下,我想以大約60Hz的速率發送命令。
我的問題是,每次我調用我的'SendCommand'方法來主動請求數據時,是否最好取消訂閱/訂閱'SerialPort.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 2009-08-18 16:48:18
您仍然會在您的數據接收處理程序中檢測到未經請求的數據,但您會知道它是未經請求的,因爲您的「SentCommandsQueue」中沒有命令。 我在串口通信中遇到了類似的問題,你必須緩衝你接收到的數據,並將解出重置消息的答案拼湊在一起。一旦你有完整的迴應,從你的隊列中刪除命令。由於重置字節似乎對序列的開頭有某種簽名,因此您應該能夠輕鬆解析它們。 – nathan 2009-08-18 16:57:44
我想我可以實現像這樣的東西。我唯一的預留是復位字節並不總是相同的(按順序或數量),所以如果在正常命令之間接收到復位數據,最終可能會產生意外偏移。這就是說,我相信這個特殊的串口設備有一個選項來啓用命令回顯。在解析響應數組時,我可以使用echo作爲標識頭。 – user158485 2009-08-18 17:59:14