2013-03-14 30 views
5

Sto postando per la prima volta quindi spero di scrivere tutto in base al formato.Problema Java SerialPortEvent: DATA_AVAILABLE chiama più velocemente dei dati in entrata

Attualmente sto lavorando a un progetto utilizzando la comunicazione seriale con RXTX tra un'applicazione java e un dispositivo di misurazione. Funziona alla grande, ma ora voglio prendere i dati che il dispositivo invia con gli eventi.

Il codice seguente funziona ma presenta il seguente problema: DATA_AVAILABLE verrà chiamato 4 volte prima che tutti i dati vengano inviati. Prendo questo in una stringa chiamata vBuffer e sono in grado di catturare i dati per ottenere la stringa completa.

Ora voglio restituire questi dati (la stringa completa), ma non riesco a trovare un SerialPortEvent che attenderà fino a quando tutti i dati vengono inviati per restituire questa stringa.

Nell'esempio seguente utilizzo OUTPUT_BUFFER_EMPTY ma questo viene chiamato all'inizio dell'invio di un comando. Ciò significa che quando si invia il comando per la seconda volta, l'evento OUTPUT_BUFFER_EMPTY restituirà vBuffer con i dati dal primo comando e immediatamente dopo avvierà il secondo comando. Al 3 ° tempo OUTPUT_BUFFER_EMPTY invia i dati dal 2 ° comando e avvia il 3 ° ecc.

C'è un modo in DATA_AVAILABLE di attendere fino a quando tutti i dati vengono inviati, o c'è un altro evento che verrà chiamato dopo che tutti i dati vengono inviati?

Ulteriori informazioni: Un comando viene inviato con un Stringbuilder di caratteri per assicurarsi che venga inviato il formato corretto per il dispositivo. Il layout di un comando è il seguente: <STX><COMMAND><RTX><CR><LF>. Posso essere in grado di afferrare la fine guardando quando termina il comando? Se é cosi, come?

Update: Questo è il codice come mando una funzione:.

StringBuilder message = new StringBuilder(); 
    message.append(new Character((char) 2)); // STX (Start of Text) 
    message.append("M");      // Command character 
    message.append(new Character((char) 3)); // ETX (End of Text 
    message.append(new Character((char) 13)); // CR (Carriage Return) 
    message.append(new Character((char) 10)); // LF (Line Feed) 
    outputStream.write(message.toString().getBytes()); 

Dopo questo il DATA_AVAILABLE entreranno in gioco, ma non aspetta fino a che tutti i dati ricevuti è fatto.

Modifica: per aumentare questo problema, non ancora il problema.

serialEvent Metodo:

public void serialEvent(SerialPortEvent event) 
{ 
    switch (event.getEventType()) 
    { 
    case SerialPortEvent.BI: 
    case SerialPortEvent.OE: 
    case SerialPortEvent.FE: 
    case SerialPortEvent.PE: 
    case SerialPortEvent.CD: 
    case SerialPortEvent.CTS: 
    case SerialPortEvent.DSR: 
    case SerialPortEvent.RI: 
    case SerialPortEvent.OUTPUT_BUFFER_EMPTY: 
    if (vBuffer != "") 
    { 
     System.out.println(vBuffer); 
    } 
    break; 
    case SerialPortEvent.DATA_AVAILABLE: 
    byte[] readBuffer = new byte[40]; 

    try 
    { 
     while (inputStream.available() > 0) 
     { 
     int numBytes = inputStream.read(readBuffer); 
     } 
     vBuffer += new String(readBuffer); 
     System.out.print(new String(readBuffer)); 
    } 
    catch (IOException e) 
    { 
     System.out.println(e); 
    } 
    break; 
+0

Pensi che quando tutti i dati vengono ricevuti? Da parte vostra. – partlov

+0

Non so davvero cosa intendi, ma la stringa che ricevo contiene dati di misura dal dispositivo connesso. E quella corda che ho intenzione di dividere. Ho fatto questo in modo codificato (forzato a dormire), ma ora sto cercando di ottenere questo risultato senza pezzi hardcoded in mezzo. – Skillcoil

+0

"C'è un modo in DATA_AVAILABLE di attendere fino alla trasmissione di tutti i dati". Non vedo che stai inviando qualcosa, solo ricevendo. Vuoi dire aspettare fino a quando tutti i dati sono stati ricevuti? – partlov

risposta

2

ho trovato un modo per controllare il comando set STX e ETX anche vedere se il messaggio è completo (ETX è nella fine del messaggio). Se questo è vero, allora ho un messaggio completo.

Problema risolto!

public void serialEvent(SerialPortEvent event) 
{ 

if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) 
{ 
    System.out.println("Data available event received"); 

    try 
    { 
    int available = inputStream.available(); 
    byte[] readBuffer = new byte[available]; 

    if (available > 0) 
    { 
     inputStream.read(readBuffer); 
    } 

    messageBuffer = messageBuffer + new String(readBuffer); 

    try 
    { 
     int start = messageBuffer.indexOf(new Character((char) 2)); 
     int end = messageBuffer.indexOf(new Character((char) 10)); 

     if (start >= 0 && end >= 0) 
     { 
     System.out.println("We found 1 complete message!!"); 
     System.out.println(messageBuffer.substring(start, end)); 
     _fireBufferEvent(); 
     messageBuffer = ""; 
     } 
    } 
    catch (IndexOutOfBoundsException ex) 
    { 
     System.out.println("IndexOutOfBoundsException, message not complete yet. Waiting for more data."); 
    } 
    } 
    catch (IOException ex) 
    { 
    System.out.println("IOException while reading data:"); 
    System.out.println(ex); 
    } 
}