2012-10-04 90 views
0

我正在開發一個Java軟件,它必須能夠讀取設備通過串行COM端口發送的一些數據,通信的速度對我來說非常重要,所以波特率設置爲921600. 開始時一切正常(因此它讀取設備通過串口發送的正確數據),但一段時間後軟件開始讀取錯誤的數據。 看起來軟件速度太慢,當它們進入輸入緩衝區時可能會丟失一些數據(也許輸入緩衝區第一次被完全填滿時)。 爲了加快閱讀操作,我正在使用一種閱讀方式,在閱讀方式中,軟件每次閱讀處理儘可能多的字節。 我也試圖使輸入緩衝區的大小更大(通過使用serialPort.setInputBufferSize(字節)方法,但它並沒有解決我的問題) 所以有人曾經用java做過快速串行通信?我錯過了什麼嗎? 爲什麼一切正常工作一段時間,然後停止正常工作?Java:讀取串行端口(波特率921600)

這是我讀取部分的代碼(甚至是驅動),請跳過部分數據轉換,這是因爲每個數據實際上都是由2個字節組成的,所以我也必須在寫入它們之前將它們組合起來一個txt文件。

/** 
* 
* @param evt 
*/ 
@Override 
public void serialEvent(SerialPortEvent evt) { 

    switch(evt.getEventType()) { 

     case SerialPortEvent.OUTPUT_BUFFER_EMPTY: 
      System.out.println("THE OUTPUT BUFFER IS EMPTY"); 
      break; 

     case SerialPortEvent.DATA_AVAILABLE: 
      try {  

       while(SerialPortEvent.DATA_AVAILABLE == 1) { 


        num_bytes = input.available(); 
        array = new byte[num_bytes]; 

        bytes_read = input.read(array, 0, num_bytes); 

        dato = new short[bytes_read]; 
        datoc = new int[bytes_read/2]; 
        datos = new String[bytes_read/2]; 


        for(j=0;j<bytes_read;j++){       
         dato[j] = (short) (((byte) array[j]) & 0xff); 
        } 

        k = 0; 
        for(j=0;j<(bytes_read/2);j++){ 

         datoc[j] = dato[k]; 
         datoc[j] = (datoc[j]<<8) + dato[k+1]; 
         datoc[j] = datoc[j] & 0xffffffff; 
         k = k + 2; 
        } 

        for(j=0;j<(bytes_read/2);j++){ 

         System.out.println(datoc[j]); 
         datos[j] = Integer.toString(datoc[j]); 
         output1.write(datos[j] + " "); 
        } 

       } 
      } catch(IOException ex) { 
       logText = "Failed to read data. (" + ex.toString() + ")"; 
       System.out.println(logText); 
      } 
      break; 

    } 
+0

多長時間了?如果你可以在數據處理失敗之前的一個小時內處理數據,我猜你可能會有內存泄漏,或者在Java進行垃圾回收時失敗(只是猜測Java會這麼做)。另外,串行事件是否在處理完最後一個事件之前再次觸發? – Jeff

回答

0

減慢串行通信速度的原因是使用了System.out.println()。沒有這一點,數據接收最終得到罰款

0

這聽起來像你的項目未能足夠快的速度服務於輸入數據;它會工作一段時間,因爲輸入進入緩衝區,並且當您清空緩衝區時,有更多空間可用於更多輸入。但是,如果數據進入的速度比您處理數據的速度快,那麼最終您的緩衝區已滿並且數據仍然存在,無處可去。這種數據通常在串行通信中被放置在(虛擬)層上。

設置狀態指示「緩衝區溢出」也很典型。首先我要檢查的是,在你用來讀取串行數據的任何庫中,是否可以使用這種狀態,並查看它是否被設置。這將驗證上述是發生了什麼。

另一件要檢查的事情是,如果它在您的環境中是合理的,則爲XON/XOFF功能。這是一些串行通信的特徵,它允許接收者向發送者指示其緩衝區已滿,並在告知再次開始(XON)之前可以停止發送(XOFF)。並非所有硬件和軟件都支持此功能。

如果因爲某種原因無法正常工作,而且確實存在問題,那麼您將不得不更好地處理數據或進一步緩衝數據。一個簡單的蠻力方法是將字節寫入存儲器,然後在單獨的線程中讀取它們。例如,如果這是一個傳統的計算機系統,您可以將它們寫入磁盤,然後處理磁盤文件,將其打開以便在一個線程中讀取並在另一個線程中寫入(很有趣!)。

+0

XON/XOFF是軟件流控制,因此它不涉及硬件支持。使用XON/XOFF非常少見。更常見的流量控制解決方案是硬件RTS/CTS。絕大多數硬件支持RTS/CTS。 – TJD

+0

要支持XON/XOFF,必須有全雙工;也許我已經回到了歷史的過去 - 我懷疑有很多半雙工系統 - 但確實需要爲軟件發送信號提供硬件支持。你是對的,它是基於軟件的,我忘了提及RTS/CTS - OP應該看看,我很高興你提到它。 – arcy