When porting some Ruby code over to JRuby for a prototype I’ve been working on recently, I ran into a small hiccup that I should have seen coming but wasn’t originally very worried about: my app talks over a serial port via ruby-serialport. The serialport gem is built with native code, as Bundler was kind enough to remind me; I couldn’t use its convenient interface in my new JRuby app.
So I hit Google, thinking surely — by now — someone has published a nice JRuby serial library. This is apparently not the case; while I did find an older (abandoned?) project called dgn110-jruby, there was a lot of code I knew I wouldn’t need, and the tests looked incomplete, so I kept looking.
Happily, Ian Dees wrote a neat PragPub article about testing Arduino code using JRuby and included example code for a nice little adapter to bridge Ruby code to the RXTX library. While Ian wasn’t attempting to make a fully-compliant replacement for serialport’s interface, it sure looked good enough for my needs, and easy to read and modify. I copied his code, tweaked the read/write methods to better suit my project, and I was back in business without any major modifications to the original prototype code.
Here’s the code for what I called JrSerialPort:
To test it out, the following code starts a simple serial terminal, relaying each line you type to the connected serial port and printing every byte received from the port to stdout on arrival:
These examples assume that your system has serial ports available and configured or that you’ve got a USB-serial cable with drivers installed (Linux systems usually have many USB-serial cable drivers preinstalled), and that you know how to address your port(s), e.g., /dev/ttyUSB0.
You’ll need to add two binary dependencies to your project: the cross-platform
RXTXcomm.jar and the native binary for your target platform, such as
librxtxSerial.so (for Linux) or rxtxSerial.dll (for Windows), etc. You’ll also need to let Java know where to find that native library, so update your JRuby command or your
JRUBY_OPTS environment variable.
As an example, I set up my project to be run assuming the current working directory is the root of my project, so I:
- Setup my shell environment:
This isn’t a gem yet, as it’s only being used in prototype code, has no tests, and I don’t have a ton of experience wrangling serial communication parameters in different and challenging environments. But I am planning to release this little guy as a convenient gem to quickly connect to a serial interface and get things up and talking. For now, feel free to clone the example code and use it as you please.