One comment that I had in this site said that the RXTX library is not very reliable in the receiving part (using data available event).
I’m unsure whether it happens because of the RXTX implementation (in the application side) or RXTX library has internal bug. So, here’s some simple loopback test program to test the RXTX.
Note that you will need the RS232 loopback plug (it’s pin-3 and pin-2 are connected), like the schematic below, to use the program.

RS232 Loopback
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;
/**
* RXTX input/output reliability test
*
* @author kunil
*/
public class LoopbackTest {
private SerialPort serialPort;
private OutputStream outStream;
private InputStream inStream;
public void connect(String portName) throws IOException {
try {
// Obtain a CommPortIdentifier object for the port you want to open
CommPortIdentifier portId =
CommPortIdentifier.getPortIdentifier(portName);
// Get the port's ownership
serialPort =
(SerialPort) portId.open("Demo application", 5000);
// Set the parameters of the connection.
setSerialPortParameters();
// Open the input and output streams for the connection.
// If they won't open, close the port before throwing an exception.
outStream = serialPort.getOutputStream();
inStream = serialPort.getInputStream();
} catch (NoSuchPortException e) {
throw new IOException(e.getMessage());
} catch (PortInUseException e) {
throw new IOException(e.getMessage());
} catch (IOException e) {
serialPort.close();
throw e;
}
}
/**
* Get the serial port input stream
* @return The serial port input stream
*/
public InputStream getSerialInputStream() {
return inStream;
}
/**
* Get the serial port output stream
* @return The serial port output stream
*/
public OutputStream getSerialOutputStream() {
return outStream;
}
/**
* Register event handler for data available event
*
* @param eventHandler Event handler
*/
public void addDataAvailableEventHandler(
SerialPortEventListener eventHandler) {
try {
// Add the serial port event listener
serialPort.addEventListener(eventHandler);
serialPort.notifyOnDataAvailable(true);
} catch (TooManyListenersException ex) {
System.err.println(ex.getMessage());
}
}
/**
* Disconnect the serial port
*/
public void disconnect() {
if (serialPort != null) {
try {
// close the i/o streams.
outStream.close();
inStream.close();
} catch (IOException ex) {
// don't care
}
// Close the port.
serialPort.close();
}
}
/**
* Sets the serial port parameters to 57600bps-8N1
*/
private void setSerialPortParameters() throws IOException {
int baudRate = 57600; // 57600bps
try {
// Set serial port to 57600bps-8N1..my favourite
serialPort.setSerialPortParams(
baudRate,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(
SerialPort.FLOWCONTROL_NONE);
} catch (UnsupportedCommOperationException ex) {
throw new IOException("Unsupported serial port parameter");
}
}
@SuppressWarnings("empty-statement")
public static void main(String[] args) {
// Start the loopback testing
String testString = "The quick brown fox jumps over the lazy dog";
// Timeout: 1s
final int TIMEOUT_VALUE = 1000;
// Get the serial port
LoopbackTest loopbackTest = new LoopbackTest();
try {
loopbackTest.connect("/dev/ttyUSB0");
InputStream inStream = loopbackTest.getSerialInputStream();
OutputStream outStream = loopbackTest.getSerialOutputStream();
for (int i = 0; i < testString.length(); i++) {
// Write to serial port
outStream.write(testString.charAt(i));
// wait until we got the loopback data
// Dont forget the timeout
long startTime = System.currentTimeMillis();
long elapsedTime;
do {
elapsedTime = System.currentTimeMillis() - startTime;
} while ((elapsedTime < TIMEOUT_VALUE) &&
(inStream.available() == 0));
if (elapsedTime < TIMEOUT_VALUE) {
// Compare the result
int readChar = inStream.read();
if (readChar != testString.charAt(i)) {
System.err.println("Received: " + readChar +
" Sent:" + testString.charAt(i));
}
}
else {
// Get out from the loop..
System.err.println("Received nothing from serial port");
break;
}
}
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
System.out.println("Test done\r\n");
loopbackTest.disconnect();
}
}
The program will simply send 1-character and wait to receive 1-character to be compared.
The program has not tested the main issue yet (problem with data available event), but this basic test should be ok for any platform and any version of Java / RXTX. I use Linux 2.6 SUSE SLED 10, Java 6, and RXTX 2.1.7 when testing this, and it’s okay for me.
Please post a comment if it doesn’t work for you.
Changelog
20080829 – Add timeout, for case where you forget the loopback. Fix the exception.
Very nice little test and one of the most comprehensive RXTX examples I’ve seen. This really helped me out with a blocking read I needed. Thanks for the good work.
Comment by Foxhunter — September 3, 2009 @ 11:30 pm
Thanks a lot =)
Comment by kunilkuda — September 4, 2009 @ 8:05 am