Skip to content

Event Based Reading Usage Example

Will Hedgecock edited this page Mar 14, 2019 · 27 revisions

If you would like to use the jSerialComm library in a completely asynchronous fashion, you can enable event-based callbacks via the addDataListener() method. This method takes your own custom callback object as a parameter which must implement the SerialPortDataListener interface.

In any of the event-driven callback modes, you can register your own custom callback to be triggered upon certain serial I/O events. Note that none of the timeouts you may have specified in an earlier call to setComPortTimeouts() will be adhered to in this mode.

The events you can listen for are:

Data Available for Reading Example

In this case, your callback will be triggered whenever there is any data available to be read over the serial port. Once your callback is triggered, you can optionally call bytesAvailable() to determine how much data is available to read, and you must actually read the data using any of the read() or readBytes() methods.

The following example shows one way to use this event trigger:

SerialPort comPort = SerialPort.getCommPorts()[0];
comPort.openPort();
comPort.addDataListener(new SerialPortDataListener() {
   @Override
   public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; }
   @Override
   public void serialEvent(SerialPortEvent event)
   {
      if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE)
         return;
      byte[] newData = new byte[comPort.bytesAvailable()];
      int numRead = comPort.readBytes(newData, newData.length);
      System.out.println("Read " + numRead + " bytes.");
   }
});

Data Writing Successful Example

In this case, your callback will be triggered whenever all data you have written using any of the write() or writeBytes() methods has actually been transmitted.

Note that this mode of operation is only functional on Windows operating systems due to limitations in Linux's handling of serial writes.

The following example shows one way to use this event trigger:

SerialPort comPort = SerialPort.getCommPorts()[0];
comPort.openPort();
comPort.addDataListener(new SerialPortDataListener() {
   @Override
   public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_WRITTEN; }
   @Override
   public void serialEvent(SerialPortEvent event)
   {
      if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_WRITTEN)
         System.out.println("All bytes were successfully transmitted!");
   }
});

Data Bytes Received Example

In this case, your callback will be triggered whenever some amount of data has actually been read from the serial port. This raw data will be returned to you within your own callback, so there is no further need to read directly from the serial port.

The following example shows one way to use this event trigger:

SerialPort comPort = SerialPort.getCommPorts()[0];
comPort.openPort();
comPort.addDataListener(new SerialPortDataListener() {
   @Override
   public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_RECEIVED; }
   @Override
   public void serialEvent(SerialPortEvent event)
   {
      byte[] newData = event.getReceivedData();
      System.out.println("Received data of size: " + newData.length);
      for (int i = 0; i < newData.length; ++i)
         System.out.print((char)newData[i]);
      System.out.println("\n");
   }
});

Fixed-Length Data Packet Received

In this case, your callback will be triggered whenever a set fixed amount of data has been read from the serial port. This raw data will be returned to you within your own callback, so there is no further need to read directly from the serial port.

Note that in this case, you must implement the SerialPortPacketListener which is itself a sub-class of the SerialPortDataListener.

The following example shows one way to use this event trigger. Notice that in this example, we actually define a qualified listener class instead of passing in an anonymous one as in the previous examples. Either method is fine, and both are shown simply for illustrative purposes:

private final class PacketListener implements SerialPortPacketListener
{
   @Override
   public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_RECEIVED; }

   @Override
   public int getPacketSize() { return 100; }

   @Override
   public void serialEvent(SerialPortEvent event)
   {
      byte[] newData = event.getReceivedData();
      System.out.println("Received data of size: " + newData.length);
      for (int i = 0; i < newData.length; ++i)
         System.out.print((char)newData[i]);
      System.out.println("\n");
   }
}

static public void main(String[] args)
{
   SerialPort comPort = SerialPort.getCommPorts()[0];
   comPort.openPort();
   PacketListener listener = new PacketListener();
   comPort.addDataListener(listener);
   try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); }
   comPort.removeDataListener();
   comPort.closePort();
}

Delimited String-Based Message Received

In this case, your callback will be triggered whenever a string-based message has been received based on a custom delimiter that you specify. The raw data will be returned to you within your own callback, so there is no further need to read directly from the serial port.

Note that in this case, you must implement the SerialPortMessageListener which is itself a sub-class of the SerialPortDataListener.

The following example shows one way to use this event trigger. Notice that in this example, we actually define a qualified listener class instead of passing in an anonymous one as in the previous examples. Either method is fine, and both are shown simply for illustrative purposes:

private final class MessageListener implements SerialPortMessageListener
{
   @Override
   public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_RECEIVED; }

   @Override
   public String getMessageDelimiter() { return "\n"; }

   @Override
   public void serialEvent(SerialPortEvent event)
   {
      String newMessage = new String(event.getReceivedData());
      System.out.println("Received the following message: " + newMessage);
   }
}

static public void main(String[] args)
{
   SerialPort comPort = SerialPort.getCommPorts()[0];
   comPort.openPort();
   MessageListener listener = new MessageListener();
   comPort.addDataListener(listener);
   try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); }
   comPort.removeDataListener();
   comPort.closePort();
}

Clone this wiki locally