javamultithreadingrxtxreal-time-data

Read & Write simultaneously on same JAVA RXTX Serial Port within same thread


Read & Write simultaneously on same JAVA RXTX Serial Port within same thread

Is it possible to read and write from same serial port within same Java thread in real time.Actually I am reading data from Arduino and I need to send same data to Arduino in realtime. Im using while true condition inside my Runnable that's why unable to get data inside EventListner.

Code Snippet

 public void initialize() 
{
        CommPortIdentifier portId = null;
        Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

        //First, Find an instance of serial port as set in PORT_NAMES.
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier currPortId
                    = (CommPortIdentifier) portEnum.nextElement();
            for (String portName : PORT_NAMES) {
                if (currPortId.getName().equals(portName)) {
                    portId = currPortId;
                    break;
                }
            }
        }
        if (portId == null) {
            System.out.println("Could not find COM port.");
            logText="Could not find COM Port. Please Change your device port to COM3.";
            isconnected=false;
            return;
        } else {
            System.out.println("Port Name: " + portId.getName() + "\n"
                    + "Current Owner: " + portId.getCurrentOwner() + "\n"
                    + "Port Type: " + portId.getPortType());
            logText = portId.getName()+ " Successfully Connected!";
            isconnected=true;
            isRunning=true;
            //Controller.labelStatus.setText(" Successfully Connected!");
        }

        try {
            // open serial port, and use class name for the appName.
            serialPort = (SerialPort) portId.open(this.getClass().getName(),
                    TIMEOUT);

            // set port parameters
            serialPort.setSerialPortParams(DATA_RATE,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);

            // open the streams
            inputstream = serialPort.getInputStream();
            output = serialPort.getOutputStream();
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
             thread = new Thread(){
                public void run(){
                    while(isRunning) {
                        System.out.println("Thread Running "+bytesToHexString(BtnHexData.getInstance().getSendingPack()));

                        try {
                            output.write(BtnHexData.getInstance().getSendingPack());

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        try {
                            Thread.sleep(200);
                            //System.out.println("\t\t Thread Receiving "+bytesToHexString(input.readAllBytes()));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };

            thread.start();

        } catch (Exception e) {
            serialPort.close();
            System.err.println(e.toString());
            logText="Error: "+e.toString();
        }
    }

Solution

  • I had same problem but finally I got the Solution !

    There is another JAVA comm library "com.fazecast.jSerialComm" which is the ultimate solution for real-time read & write operations on serial port simultaneously. I'm posting my findings, if someone needs help regarding this issue...

    SerialPort Class using jSerialComm

    import com.fazecast.jSerialComm.SerialPort;
    import com.fazecast.jSerialComm.SerialPortDataListener;
    import com.fazecast.jSerialComm.SerialPortEvent;
    
    public class MySerialPort {
        public static SerialPort arduinoPort = null;
        public static InputStream arduinoStream = null;
        static String logText="";
        private static boolean isRunning=false;
        private   byte[] sendingPack;
        private   byte[] receivingPack;
        public static boolean isRunning() {
            return isRunning;
        }
    
        public static void setRunning(boolean running) {
            sendingPack = new byte[6];
            receivingPack= new byte[36];
            isRunning = running;
           
        }
       public static void connectPort(String port) {
            devicePortName = port;
    
            int len = SerialPort.getCommPorts().length;
            SerialPort serialPorts[] = new SerialPort[len];
            serialPorts = SerialPort.getCommPorts();
    
            for (int i = 0; i < len; i++) {
    
                String portName = serialPorts[i].getDescriptivePortName();
                System.out.println(serialPorts[i].getSystemPortName() + ": " + portName + ": " 
                 + i);
               
                if (portName.contains(devicePortName)) {
                    try {
                        arduinoPort = serialPorts[i];
                        arduinoPort.setBaudRate(115200);
                        arduinoPort.openPort();
                        setRunning(true);
                        System.out.println("connected to: " + portName + "[" + i + "]");
                        logText="Connected to: " + portName ;
    
                        break;
                    } catch (Exception e) {
                        e.printStackTrace();
                        loogger.stop();
                        arduinoPort.closePort();
                    }
               } }
     
          (new Thread(new SerialReader(receivingPack))).start();
          (new Thread(new SerialWriter(sendingPack))).start();
         }
        public static class SerialReader implements Runnable
          {
            byte[] buffer;
    
            public SerialReader ( byte[] buffer )
            {
                this.buffer = buffer;
                System.out.println("Reader");
    
            }
    
            public void run () {
    
                readData(buffer,isRunning());
            }
        }
      public static class SerialWriter implements Runnable
        {
            byte[] buffer;
    
            public SerialWriter ( byte[] buffer )
            {
                this.buffer = buffer;
    
            }
    
            public void run () {
    
                sendData(buffer);
    
            }
        }
       public static void sendData(byte[] buffer){
               
            while (isRunning){
                 
                arduinoPort.writeBytes(sendingPack,6,0);
    
         System.out.println("Sending"+bytesToHexString(sendingPack));
                try {
                    Thread.sleep(200);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                }
           }
    
      public static void readData(byte[] buffer,boolean loopStatus){
            while (isRunning()){
    
                arduinoPort.readBytes(receivingPack,36,0);
               
                if(receivingPack()[0] & 0xff)==144 ){           
                        
             String bufferD=bytesToHexString(receivingPack);
                        System.out.println(bufferD);
                    
                }
                try {
                    Thread.sleep(50);
                } catch (Exception e) {
                    e.printStackTrace();
            }    }
            
    
      public static String bytesToHexString(byte[] bytes){
              StringBuilder sb = new StringBuilder();
            for (byte b : bytes){
                sb.append(String.format("%02x", b&0xff));
            }
            return sb.toString();
        }
        }
    

    Main Class

       public static void main(String[] args) {
                MySerialPort.setRunning(true);
                MySerialPort.connectPort("COM3");
        }