2010-08-27 20 views
0

我正在寫一個方法,它發送一個特定的數據包並從電子設備獲取答案。我用rtsEnabled = true使用system.io.ports。system.io.ports使用rtsenabled接收錯誤的數據包

問題是,當進入應用程序接收到的數據包被改變。我正在使用eltima和eltima接收的數據包來監視正在接收的內容,並且應用程序有兩個不同的字節。

應用程序正在將每個以十六進制表示的雙字節(例如FF或BB)的字節更改爲3F。 以下是什麼Eltima是給:

5B 00 00 09 32 13 31 33 35 36 31 39 31 30 30 38 32 35 00 01 FF 64 01 00 0F BB 5D --Eltima

5B 00 00 09 32 13 31 33 35 30 32 37 31 30 30 38 32 35 00 01 3F 64 01 00 3F 04 5D --MyApplication

以下是我的代碼:

public string MakeSerialConnection(string COM, int baud, string dest) 
    { 
     SerialPort port = new SerialPort(COM, baud, Parity.None, 8, StopBits.One); 
     try 
     { 
      if (!(port.IsOpen)) 
      { 
       string destination = dest; 
       //BUILD PACKET FOR SENDING 
       byte[] fullPacket = BuildPacket(destination); 
       port.Open(); 
       port.RtsEnable = false; 

       port.Handshake = Handshake.None; 

       //SEND PACKET TO DEVICE 
       port.Write(fullPacket,0,9); 

       #region RECEIVE DATA FROM SERIAL 
       //MAKE PROCESS STOP FOR 5sec 
       Thread.Sleep(240); 

       port.RtsEnable = true; 

       Thread.Sleep(1000); 
       string reading = port.ReadExisting(); 
       // int readingint = port.ReadByte(); 

        port.Close(); 
        port.Dispose(); 
        return reading; 
       #endregion 
      } 
      else 
      { 
       return ""; 
      } 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      if (port != null) 
      { 
       //port.Close(); 
       if (port.IsOpen) 
       { 
        port.Close(); 
       } 
       port.Dispose(); 
      } 

     } 

請幫助我的身影爲什麼發生這種情況

+0

ps忽略代碼中的註釋其中一些不正確 – IanCian 2010-08-27 12:10:31

回答

1

它看起來在一個ASCII代碼圖中,你會看到0x3f是字符代碼?這是Encoding.GetString()無法將字節值轉換爲字符時將會得到的替換字符。有意義的是,默認的SerialPort.Encoding是ASCII碼,0xff在該編碼中不是有效的字符碼。

根本問題是您正在閱讀字符串。但設備不發送字符串,它發送字節。您必須使用SerialPort.Read()而不是ReadExisting()。

+0

OP是否只是更改SerialPort的編碼並仍然使用ReadExisting()調用? – SwDevMan81 2010-08-27 14:24:55

+1

@SwDev:字節不能1對1映射到一個字符串,那些日子已經結束。很多字節值在Unicode中沒有相應的代碼點。 – 2010-08-27 14:31:35

+0

同意Hans,這也是我的分析。 – Roast 2010-08-27 19:23:29

0

設備規格對Handshaking有什麼意見?您可能必須將握手設置爲RequestToSend。另外,如果可能的話,使用DataReceived來接收數據而不是睡覺。

我還會檢查串口的Encoding以確保它與設備的使用相匹配。缺省值爲ASCIIEncoding,因此如果設備使用其他設備(例如:Unicode),則需要更改它。

+0

握手不是問題,我懷疑編碼問題,因爲其他數據包正在接收良好。除非十六進制數值相同(例如bb或ff),否則這個數據包中的數據全部匹配。 – IanCian 2010-08-27 13:37:52

+1

@IanCian - 編碼實際上會在字節沒有識別時改變它。作爲一個例子看這篇文章:http://stackoverflow.com/questions/2714533/how-to-apply-encoding-when-reading-from-a-serial-port – SwDevMan81 2010-08-27 13:41:30

+1

該編碼不支持字節與高位設置並將它們翻譯爲'?' (十六進制中的3F是「?」)。 – SwDevMan81 2010-08-27 13:42:33

1

請勿將您的讀取字節放入字符串中。正如SwDevMan所述,你不是通過端口發送字符串,而是一個字節數組。作爲一種好的做法,避免將數據轉換爲不屬於的類型。有時,框架背後的代碼會在您不知情的情況下更改數據。

使用Read()或ReadByte()並將您的字節放入您將構建的數組或字節或列表中。 Read()是合乎邏輯的方式,但ReadByte有它的用途。使用ReadByte()將一次讀取一個字節。如果你期望第一個字節是一個特殊的標誌,例如一個命令標誌的開始,你可以馬上驗證它並選擇放棄或繼續閱讀。

 while (serialport.BytesToRead > 0) 
     { 
      startingByte= Convert.ToByte(serialport.ReadByte()); 
      CheckIfStartOfCommand(startingByte) 
      ... 
     } 

否則,請使用Read()將一定數量的字節獲取到預設數組中。