none
有關RS232接收二進位資料 RRS feed

  • 問題

  • 小弟將一個外部設備連接至PC,設備是一個類似data logger的東西,能夠dump資料,並以二進位方式傳送

    (每次傳送一個page,132個bytes)

    目前小弟在接收時先將所有檔案寫入檔案中:

     

    BinaryWriter myBinaryWriter = new BinaryWriter;
    private List<byte> rxImage = new List<byte>();
    
    private void port_Reader_DataReceived(object sender, SerialDataReceivedEventArgs e)  
    {
    	byte[] inputData = new byte[1];    
    
    	try
    	{
    		while (comport.BytesToRead > 0 && comport.IsOpen) 
    		{
    			inputData[0] = Convert.ToByte(comport_Reader.ReadByte());
    
    			myBinaryWriter.Write(inputData[0]);
    			rxImage.Add(inputData[0]);
    		}
    	}
    }
    

    其中,myBinaryWriter指向一個檔案.。

    serialPort的相關設定:

          // 設定serial port參數
    
          currentComPort.BaudRate = 38400;
          currentComPort.DataBits = 8;
          currentComPort.StopBits = StopBits.One;
          currentComPort.Parity = Parity.None;
    
          currentComPort.PortName = cmbPortName_Reader.Text;
    
          currentComPort.Handshake = Handshake.None;
          currentComPort.Encoding = Encoding.ASCII;
          currentComPort.DiscardNull = false;
          currentComPort.ReceivedBytesThreshold = 1;
          currentComPort.ReadBufferSize=65534;
          currentComPort.DtrEnable = false;
          currentComPort.RtsEnable = false;
    
    
          // 開啟Port
          try
          {
            currentComPort.Open();
    
          }
          catch (Exception)
          {
            return;
          }
    

     

    等傳輸完成後再將檔案抓出來做parse

    目前遇到的問題是,當一次要求較大量的資料時,接收的過程中會產生byte錯誤,如有些page會少一、兩個byte,

    造成parse時產生錯誤。

    設備端目前的處理方法是,收到dump指令後,便開始dump page,每個page 輸出前會檢查先前的資料是否已送完,再加上一小段delay,連續發送至送完為止

    (BaudRate為38400)

    (線材長度大約2公尺,有使用usb ->rs232轉換線)

    本以為是baud rate設太大,但降為19200後,錯誤率的確降底一些,但仍會發生。

    由於設備的程式(使用microchip的PIC )也是小弟自己動手做@@,因此做了點測試,連續丟固定的132 bytes數千次到PC端,再以putty加上monitor程式觀察,發現大約傳了2、30k bytes後,便開始可能發生資料錯誤,錯誤位置似乎是隨機的。

    SerialPort並不是穩定的傳輸方式,但是不知道有沒有相關資料說發送多少bytes錯誤率會開始提高?

    想請教各位先進,是否有使用rs232做二進位傳輸的經驗,一般可以達到怎樣速度呢?若想要保証資料的正確性,不知有什麼較好的做法?

    因為如果要自己加上check sum,再由PC端判斷重送,那效率會相當差,不知道有哪些注意事項可以提高傳輸的穩定性?

     

     


    zeus
    2010年11月23日 上午 07:01

解答

  • 撰寫RS232接收端時常遇到的問題.
    通常是因為DataReceived函式處理時間過長導致 RS232 lose data.

    解決方法是
    DataReceived只單純的作資料接收.而資料接收後放到一個Queue,然後再撰寫workThread來非同步處理資料.
    你可以使用下面連結的Library來處理此問題.
    http://www.codeproject.com/KB/threads/smartthreadpool.aspx

     

    • 已標示為解答 宙斯 2010年11月24日 上午 10:35
    2010年11月23日 上午 08:58
  • 在你的迴圈中加 Sleep

    電腦運算很快,你資料讀完到下次回圈執行時,不見得資料就已經傳進來了,你依此作為判斷條件很有問題。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 宙斯 2010年11月24日 上午 10:35
    2010年11月23日 下午 03:27

所有回覆

  • 撰寫RS232接收端時常遇到的問題.
    通常是因為DataReceived函式處理時間過長導致 RS232 lose data.

    解決方法是
    DataReceived只單純的作資料接收.而資料接收後放到一個Queue,然後再撰寫workThread來非同步處理資料.
    你可以使用下面連結的Library來處理此問題.
    http://www.codeproject.com/KB/threads/smartthreadpool.aspx

     

    • 已標示為解答 宙斯 2010年11月24日 上午 10:35
    2010年11月23日 上午 08:58
  • 在你的迴圈中加 Sleep

    電腦運算很快,你資料讀完到下次回圈執行時,不見得資料就已經傳進來了,你依此作為判斷條件很有問題。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 宙斯 2010年11月24日 上午 10:35
    2010年11月23日 下午 03:27
  • 感謝兩位的指導

    programlin大所提的ThreadPool,看起來相當實用,小弟會試著將它加入!

    心冷大所提的意思,是否是因為迴圈跑太快,會讓comport.BytesToRead來不及更新,使rs232的input buffer資料長度與BytesToRead不同步?

    這樣的確需要做delay,不知有沒有方法能較精確的等待,例如讀取時是否有flag會被設定,用來做判斷?

     

    後來再測試之後,其實這個問題跟設備端也有關係,在PIC中,要輸出字時,是將byte丟到txReg (一個register)中,丟的方式會影響輸出,測試的結果是,將要輸出的資料放在一個大buffer中,一次輸出較好 (原本的做法是取到一部份資料便丟一些),因為輸出動作可能受到中斷干擾,不過這部份跟C#沒什麼關係,順便提一下就是了。

     

     


    zeus
    2010年11月24日 上午 04:21
  • RS232天生在資料傳輸上就有著容易受影響的問題, 拿 RS485和RS232來比較,

    RS232的信號準位是對地線的, 一旦線路受外在影響, 準位差就會出問題

    而RS485的準位則是正極參考負極, 而這兩條線通常會在一起, 就算被影響也是一起升或一起降, 所以+/-準位差距通常較RS232能夠保持住.

    當你將RS232的傳輸率拉高時, 對於環境的要求就會跟著提高, 包含

    (a) 串列埠晶片 (b) 線路品質,如線徑、長度與隔離 (c) 外部環境,如重電強磁的影響 等等..

    所以依據不同的狀況多半都要慢慢測試出最佳組合, 說實話, 這件事還挺煩的.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年11月24日 上午 10:09
    版主