Lore Michael Lones

Using a Polhemus Patriot with Java

The Polhemus Patriot electromagnetic position sensing device comes with Windows C/C++ bindings. This creates a slight obstacle for those wanting to use it with Java in a non-Windows environment. Fortunately, however, the Patriot can be attached to a serial port (or, perhaps more likely these days, a serial-to-USB adapter) and communicated with using the open-source RXTX Java library.

This HOWTO describes how to use the Patriot with Java, RXTX and a Prolific PL-2303 based serial-to-USB adapter (i.e. most serial-to-USB adapters at the time of writing) on Windows XP and Mac OS X.

First, you will need an up-to-date driver for the serial-to-USB adaptor. In my experience, most communication problems result from using an outdated driver, such as the one that came with the adapter. Drivers are available from here, although unfortunately they don't seem to have plans for a Vista driver. I have been using v2.0.2.1 for XP and v1.2.1r2 for Mac OS. There is also an open source version available for Mac OS from here, which also seems to work.

( UPDATE: Some serial-to-USB adapters now come with Vista drivers - which may also work with older adapters. )

Next, install RXTX for your platform. RXTX is available from here. I use version 2.1.7. Since it needs to communicate with platform specific hardware, this involves installing a native library in addition to placing the JAR files on the CLASSPATH. However, this is not much of a challenge.

The Code

Connecting to the Patriot from Java is fairly straightforward. Sample code is available here.

First, find out the port name. On Mac OS, this will be along the lines of /dev/tty.usbserial. If this doesn't work, have a look in /dev ('ls /dev' in Terminal) and see if there's anything with an appropriate sounding name. If there isn't, this would suggest that the adapter's driver has not been installed correctly. On Windows, it will depend which USB port you stuck the adapter in. COM4 or COM5 are quite likely. You can find out by looking in the device manager (Start->Run... devmgmt.msc) under Ports. Once you have the name of the port, you can create an RXTXPort object in Java. For example:

String osname = System.getProperty("os.name");
RXTXPort port;
if(osname.startsWith("Mac"))
 
portName = "/dev/tty.usbserial";
else if(osname.startsWith("Windows"))
 
portName = "COM5";
try {
 
port = new RXTXPort(portName);
}
catch(PortInUseException piuE) {
 
System.err.println("Patriot connection failed: serial port "+portName+" in use or does not exist");
}

If this throws an exception, try re-inserting the adapter, reset the Patriot and then re-run the code. RXTX really doesn't like it if you unplug the adapter whilst it is running. If this happens, you will probably need to relaunch your Java program.

Next, you need to set up the communication protocol. Assuming you want the Patriot to run at full speed, do the following:

try {
 
port.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException ucoE) {
 
System.err.println("Patriot connection failed: could not configure serial port");
}

If this doesn't work, check that the CONFIG switches on the back of the Patriot are set to match the communications protocol you have specified in the Java code. The manual shows you how to do this. An exception may also be thrown at this point if your adapter's driver is not sufficiently up-to-date.

Assuming the connection was successfully established, you can now retrieve input and output streams to the Patriot:

InputStream in = port.getInputStream();
OutputStream out = port.getOutputStream
();

To set the Patriot going, try:

out.write('c');    // continuous output
out.write(0x0d)// carriage return required

The Patriot is very fussy about what you send it. It really doesn't like line feed characters, so be careful if you are sending data direct from standard input under Mac OS (or Linux).

Now, to receive all the lovely position data, you need to read from the Patriot's output stream. This may sound trivial, but I have found the only way to receive data reliably (especially under Windows) is to wrap the output stream in a BufferedReader. Trying to read data into a custom buffer always seems to result in lost data and misery.

try {
 
reader = new BufferedReader(new InputStreamReader(in));
 
while(true) { // something along these lines...
   
while(!reader.ready()) {}
   
data = reader.read();
   
if(data==-1) break;
 
}
}
catch (IOException e) {
 
System.err.println("Error reading Patriot data.");
}

Note that pulling the USB cable out does not cause an exception to be thrown. Under Windows, this causes RXTX's native library to produce lots of error messages on stderr, which is a little annoying!

To stop the Patriot from spewing out data:

out.write('p');

Note that this is NOT followed by a carriage return. Sending one will not make it happy ;)

These web pages use Google Analytics to track visits. See Privacy Statement.
© Michael Lones 2005-2016. Page last updated 30th October, 2013.