Java developers and applications that access serial ports with RXTX on a Raspberry Pi, Beaglebone Black, or similar debian-based platform using non-standard serial port names (ie. /dev/ttyO1, /dev/ttyAMA0), need to do a bit of setup before things will work as expected.
Native Libraries
After install the JRE, RXTX native libraries also need to be installed:
sudo apt-get install librxtx-java
This installs librxtxSerial.so in /usr/lib/jni. This path is automatically included in the Java Library Path on some platforms, but not all, so you need to update this property. The library path can be set in code, but since the goal of Java is to ensure portability, it probably doesn’t make sense to hard-code paths into applications. Instead, set the property at run time:
java -Djava.library.path=/usr/lib/jni <your-options-here>
Depending on your application, changing the library path may have other consequences, so you may want to set this only on some platforms. See Shell Scripts below for one possible solution.
On-Board UART
RXTX automatically scans for serial ports using known-conventions for various platforms and will automatically detect standard serial ports (ie. /dev/ttySx) and USB serial devices (ie. /dev/ttyUSBx), but won’t enumerate ports using other names.
If you want to use the built-in UARTs to communicate directly with a device connected via GPIO header, you will need to tell RXTX about your port using the gnu.io.rxtx.SerialPorts property. Again, you could do this in your code if your application only targets one platform, but to keep things portable, you can set the property at run time:
java -Djava.library.path=/usr/lib/jni -Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0
The only problem with this approach is that it disables USB serial ports. For a general, portable solution, see Shell Scripts below.
Raspbian Serial Console
There’s another gotcha when using the built-in UART: by default, Raspbian starts a serial console on /dev/ttyAMA0, which may interfere with devices communicating on this port. This issue is well known and the resolution is well documented. I like the explanation on Adafruit how to disable the console.
Raspberry Pi Hardware Connection
Wiring a serial device directly to the Raspberry Pi is easy. Here’s a chart I use to wire an XBee to the GPIO header:
Signal | Pi | XBee |
---|---|---|
3.3V | 1 | 1 |
GND | 6 | 10 |
TX/RX | 8 | 3 |
RX/TX | 10 | 2 |
Beaglebone UARTs
There are a few additional steps required to enable UARTs on the Beaglebone. Here is a nice summary, including pinouts.
Shell Scripts
Starting Java applications using shell scripts is fairly common. Here’s a script that will set the appropriate properties so RXTX will work properly on Raspbian and not interfere on other platforms:
Java-Only
Shell scripts may be fine when distributing applications, but have some limitations, like running from within an IDE, using Ant, invoking tests, or for Java libraries. In this case, it may be best to tell RXTX about non-standard serial ports in the application or library code.
Since most applications using RXTX will take the port name as an argument anyway, use it to also set the gnu.io.rxt.SerialPorts property. Here is a sample open() method in a library that uses RXTX:
public void open(String port, Integer baud) { Properties properties = System.getProperties(); String currentPorts = properties.getProperty("gnu.io.rxtx.SerialPorts", port); if (currentPorts.equals(port)) { properties.setProperty("gnu.io.rxtx.SerialPorts", port); } else { properties.setProperty("gnu.io.rxtx.SerialPorts", currentPorts + File.pathSeparator + port); } /** do RXTX stuff here, like call Serial.open(port, baud) **/
It is important to add the current port to the system property instead of overwriting it, especially in libraries that might be combined in an application using other serial ports at the same time.