The Code
Working example code is available here.
First, find out the port name. On Windows, it will depend which COM port is associated with the adapter. You can find out by looking in the device manager (Start->Run... devmgmt.msc) under Ports. Note, however, that RXTX only works with COM ports up to 9, producing a PortInUseException for COM10 and above. If your adapter has been allocated a higher port number, then you should reallocate it (typically using the device manager). On Mac OS, have a look in /dev ('ls /dev' in Terminal) and see if there's anything with an appropriate sounding name.
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("Glove connection failed: serial port "+portName+" in use or does not exist");
}
Next, you need to set up the communication protocol:
try {
port.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException ucoE) {
System.err.println("Glove connection failed: could not configure serial port");
}
An exception may 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 an input stream from the glove. For a reliable connection, it is advisable to wrap the input stream with a buffer:
InputStream in = port.getInputStream();
BufferedInputStream buffer = new BufferedInputStream(in);
Receiving packets is a simple case of calling buffer.read() repeatedly. However, interpreting the data is a bit more complicated, since the 12-bit sensor values are split over one-and-a-half bytes. This extract from the sample code shows how this can be done using bit-level operators:
boolean fullByte;
int data, value, s;
fullByte = true; for(s=2; s<18; s++) { // read sensor values
if(fullByte) { // do this when reading a full byte followed by a nibble
value = buffer.read(); // read first 8 bits of sensor value
value = value<<4; // shift along to make room for the other 4 bits
data = buffer.read(); // read next 8 bits from stream
value = value | data>>4; // copy 4 bits from this to complete the 12 bit sensor value
packet[s] = value;
}
else { // and this when reading a nibble followed by a byte
value = data<<8; // shift the 4 bits already loaded during reading of previous sensor value
value = value & 0xFFF; // discard the 4 bits we don't want
data = buffer.read(); // read the next 8 bits
value = value | data; // and put them in front of the existing 4 bits
packet[s] = value;
}
fullByte = !fullByte;
}
|