Im using JSSC library to communicate with a hardware device in my project.
My software and my team hardware need to work synchronously (My software needs to display what is currently displayed in the hardware and vice versa)
Everything works perfectly with our team's breadboard, until we make it into a real PCB with buttons mounted.
Our team's currently using this USB-to-Serial adapter for the device: https://www.sparkfun.com/products/14050
When we were doing the testing with the breadboard, it's connected through COM3. The current device's connected through COM5.
My software now can just receive the data from the device and cannot send back a signal when a button in my software is clicked (Actually the writeString method returns true but our device receives nothing)
Let's have a look at some code snippet of my software:
I've got this CONNECT button to open the port and establish the communication:
private void connectButtonActionPerformed(java.awt.event.ActionEvent evt) {
if (selectedPort != null && selectedPort.isOpened()) {
// Disconnect
selectedPort.closePort();
connectButton.setText("Connect");
} else { // Connect
selectedPort = new SerialPort(listPort.getSelectedItem().toString());
try {
connectButton.setText("Disconnect");
selectedPort.openPort();
selectedPort.setParams(9600, 8, 1, 0, true, false);
selectedPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
int mask = SerialPort.MASK_RXCHAR;
selectedPort.setEventsMask(mask);
selectedPort.addEventListener(new SerialPortReader());
} catch (SerialPortException ex) {
System.out.println(ex);
}
}
}
I've also got a jcombobox to send a character to the device:
private void modeListActionPerformed(java.awt.event.ActionEvent evt) {
try {
JComboBox cb = (JComboBox) evt.getSource();
String selectedItem = (String) cb.getSelectedItem();
switch (selectedItem) {
case "VOLTAGE_DC":
dataMode = VOL_DC;
selectedPort.writeString("v");
break;
case "VOLTAGE_AC":
dataMode = VOL_AC;
selectedPort.writeString("V");
break;
case "CURRENT_DC":
dataMode = "CUR_DC";
selectedPort.writeString("i");
break;
case "CURRENT_AC":
dataMode = "CUR_AC";
selectedPort.writeString("I");
break;
case "RESISTANCE":
dataMode = RES;
selectedPort.writeString("r");
break;
case "RESISTANCE_CON":
dataMode = CON;
selectedPort.writeString("c");
break;
default:
break;
}
selectedPort.closePort();
selectedPort.openPort();
selectedPort.addEventListener(new SerialPortReader());
} catch (SerialPortException ex) {
Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
}
}
My SerialPortReader:
public class SerialPortReader implements SerialPortEventListener {
@Override
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR() && event.getEventValue() > 0) {
try {
byte[] buffer = selectedPort.readBytes(event.getEventValue());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
update_display_by_buffer(buffer);
});
}
catch (SerialPortException ex) {
System.out.println(ex);
}
}
Recap few important points:
- My software can communicate smoothly with the breadboard while testing (COM3)
- My software now can just receive data but not the other way around with the real device (even writeString method return true)
- Our real device works perfectly with Putty
What could the reasons for this problem?
Any pointers will be appreciated.
// UPDATED:
Problem's solved by using jSerialComm library
Conclusion:
RXTX is a mess.
JSSC library sucks.
I observed same behaviour in another project and sometimes it was due to "not flushing data" after writing to serial port. JSSC does not seem to have any flushing.