Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java SerialPortEvent issue: DATA_AVAILABLE calls faster then incoming data

I'm posting for the first time so I hope that I write everything according to the format.

Currently I'm working on a project using Serial Communication with RXTX between a java application and a measuring device. This works great, but now I want to catch the data that the device sends with events.

The code below works but has the following issue: DATA_AVAILABLE will be called 4 times before all the data will be send. I catch this in a string called vBuffer and I'm able to catch the data to get the full string.

Now I want to return this data (the full string), but cannot find a SerialPortEvent that will wait till all data is send to return this string.

In the example below I use OUTPUT_BUFFER_EMPTY but this is called at the beginning of sending a command. This means that when sending the command for the 2nd time, the OUTPUT_BUFFER_EMPTY event will return vBuffer with data from the first command, and immediately after starts the 2nd command. At 3rd time OUTPUT_BUFFER_EMPTY sends the data from the 2nd command and starts the 3rd etc.

Is there a way in DATA_AVAILABLE to wait till all data is send, or is there another event that will be called after all data is send?

Extra info: A command is send with a Stringbuilder of chars to make sure the right format for the device is send. The lay-out of a command is as follows: <STX><COMMAND><RTX><CR><LF>. Might I be able to catch the end by looking at when the command ends? If so, how?

Update: This is the code how I send a function:

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

After this the DATA_AVAILABLE will kick in. But doesn't wait till all received data is done.

Edit: To bump this up, still not further with the problem.

serialEvent Method :

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;
like image 727
Skillcoil Avatar asked Nov 03 '22 02:11

Skillcoil


1 Answers

I've found a way to check the command set STX and ETX too see if the message is complete (ETX is in the end of the message). If this checks true, then I've got a complete message.

Issue solved!

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);
  }
}
like image 153
Skillcoil Avatar answered Nov 09 '22 12:11

Skillcoil