2013-03-14 14 views
5

Zamieszczam po raz pierwszy, więc mam nadzieję, że piszę wszystko zgodnie z formatem.Problem Java SerialPortEvent: DATA_AVAILABLE wywołania szybciej niż dane przychodzące

Aktualnie pracuję nad projektem wykorzystującym komunikację szeregową z RXTX między aplikacją java i urządzeniem pomiarowym. Działa to świetnie, ale teraz chcę przechwycić dane wysyłane przez urządzenie wraz ze zdarzeniami.

Poniższy kod działa, ale ma następujący problem: DATA_AVAILABLE zostanie wywołany 4 razy, zanim wszystkie dane zostaną wysłane. Łapię to w ciąg o nazwie vBuffer i jestem w stanie złapać dane, aby uzyskać pełny ciąg znaków.

Teraz chcę zwrócić te dane (pełny ciąg), ale nie mogę znaleźć SerialPortEvent, które będą czekać, aż wszystkie dane zostaną wysłane, aby zwrócić ten ciąg.

W poniższym przykładzie używam OUTPUT_BUFFER_EMPTY, ale jest to wywoływane na początku wysyłania polecenia. Oznacza to, że podczas wysyłania polecenia po raz drugi, zdarzenie OUTPUT_BUFFER_EMPTY zwróci vBuffer z danymi z pierwszego polecenia, i zaraz po uruchomieniu 2. polecenia. Po raz trzeci OUTPUT_BUFFER_EMPTY wysyła dane z 2. polecenia i rozpoczyna 3. itd.

Czy jest jakiś sposób, aby w DATA_AVAILABLE czekać na wysłanie wszystkich danych, czy jest inne zdarzenie, które zostanie wywołane po wysłaniu wszystkich danych?

Dodatkowe informacje: Polecenie jest wysyłane z Stringbuilder znaków, aby upewnić się, że wysyłany jest właściwy format urządzenia. Układ polecenia jest następujący: <STX><COMMAND><RTX><CR><LF>. Czy jestem w stanie złapać koniec, patrząc na koniec polecenia? Jeśli tak to jak?

Aktualizacja: Jest to kod, jak wyślę funkcję.

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()); 

Po tym DATA_AVAILABLE rozpocznie się jednak nie czekać, aż wszystkie otrzymane dane są zrobione.

Edycja: Aby to zmienić, nadal nie występuje problem.

serialEvent Metoda:

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

Myślisz, że po otrzymaniu wszystkich danych? Z Twojej strony. – partlov

+0

Nie wiem, co masz na myśli, ale ciąg, który otrzymuję, zawiera dane pomiaru z podłączonego urządzenia. I ten Ciąg, który zamierzam rozdzielić. Zrobiłem to na sztywno (zmusiłem się do snu), ale teraz staram się to osiągnąć, nie mając na stałe zakodowanych kawałków. – Skillcoil

+0

"Czy jest jakiś sposób w DATA_AVAILABLE, aby poczekać, aż wszystkie dane zostaną wysłane". Nie widzę, żebyś coś wysłał, tylko otrzymałeś. Masz na myśli poczekać, aż wszystkie dane zostaną odebrane? – partlov

Odpowiedz

2

Znalazłem sposób na sprawdzenie zestaw poleceń STX i ETX też sprawdzić, czy wiadomość jest kompletna (ETX jest na końcu wiadomości). Jeśli to sprawdza, to mam kompletną wiadomość.

Problem rozwiązany!

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); 
    } 
} 
Powiązane problemy