Read and write simultaneously on com port

My question is that isn't it possible to read and write simultaneously on one com port? This is just for demo purpose, I will only be reading a port once I press F5 key on the keyboard, but for demo purposes I was trying to read and write simultaneously but can't do it. It says that some other program is using the port.

UPDATE

package com_port;

import java.io.*;
import java.util.*;
import javax.comm.*;

public class simplerad implements Runnable, SerialPortEventListener
{
    static CommPortIdentifier portId;
    static Enumeration portList;

    InputStream inputStream;
    SerialPort serialPort;
    Thread readThread;

    public static void main(String[] args) throws Exception
    {
        portList = CommPortIdentifier.getPortIdentifiers();
        System.out.println("SimpleRead Started.");
        while (portList.hasMoreElements())
            {
                portId = (CommPortIdentifier) portList.nextElement();
                if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)
                    {
                        System.out.println ("Found " + portId.getName());
                        if (portId.getName().equals("COM7"))
                            {
                                OutputStream outputStream;
                                SerialPort writePort = (SerialPort) portId.open("SimpleWriteApp", 2000);
                                writePort.setSerialPortParams(9600,
                                                              SerialPort.DATABITS_8,
                                                              SerialPort.STOPBITS_1,
                                                              SerialPort.PARITY_NONE);
                                outputStream = writePort.getOutputStream();
                                outputStream.write("AT+CENG=2".getBytes());
                                System.out.println("write done");
                                writePort.close();
                                simplerad reader = new simplerad();
                            }
                    }
            }
    }

    public simplerad()
    {
        try
            {
                System.out.println("1");
                serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
            }
        catch (PortInUseException e)
            {
                e.printStackTrace();
            }
        try
            {
            System.out.println("2");    
            inputStream = serialPort.getInputStream();
            }
        catch (IOException e)
            {
                e.printStackTrace();
            }
        try
            {
            System.out.println("3");    
            serialPort.addEventListener(this);
            }
        catch (TooManyListenersException e)
            {
                e.printStackTrace();
            }
        serialPort.notifyOnDataAvailable(true);
        try
            {
            System.out.println("4");
                serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
                                               SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            }
        catch (UnsupportedCommOperationException e)
            {
                e.printStackTrace();
            }
        readThread = new Thread(this);
        readThread.start();
    }

    public void run()
    {
        System.out.println("5");
        try
            {
            System.out.println("6");
                Thread.sleep(200);
            }
        catch (InterruptedException e)
            {
                e.printStackTrace();
            }
    }

    public void serialEvent(SerialPortEvent event)
    {
        System.out.println("7");
        switch (event.getEventType())
            {
            case SerialPortEvent.BI:
            case SerialPortEvent.OE:
            case SerialPortEvent.FE:
            case SerialPortEvent.PE:
            case SerialPortEvent.CD:
            case SerialPortEvent.CTS:
            case SerialPortEvent.DSR:
            case SerialPortEvent.RI:
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                break;
            case SerialPortEvent.DATA_AVAILABLE:
                byte[] readBuffer = new byte[20];

                try
                    {
                    System.out.println("8");
                        while (inputStream.available() > 0)
                            {
                                int numBytes = inputStream.read(readBuffer);
                                System.out.print(new String(readBuffer, 0, numBytes, "us-ascii"));
                            }
                        System.out.print(new String(readBuffer));
                    }
                catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                break;
            }
    }
}

Why the serialEvent doesn't run?

Upvotes: 1

Views: 2542

Answers (2)

Preston
Preston

Reputation: 2653

The problem here is that you are trying to open the same COM port twice, and the answer is no, this will not work - at least the way that you are doing it here. The reason is that the underlying OS only allows one user mode handle per port.

But yes, as long as your COM port is bidirectional (most of them are) you can open a COM port and read/write to it at the same time - this is known as full duplex mode.

To get this behavior in your application you want to open your "COM7" port one time, then give your read thread access to this original object instead of trying to open it a second time. Another way is to just get your InputStream and OutputStream immediately after opening, then use these objects around the rest of your application.

I'm not sure exactly why your event listener is not firing, however your code seems a bit complex for what you are actually trying to do here. It's possible that opening/closing is causing you to miss an event notification.

Here is an example of what you should do on open, and this should be a more efficient solution than opening/closing the port in between reading and writing:

// Each of these could be object members so all your class methods have access
OutputStream outputStream;
InputStream inputStream;
SerialPort serialPort;

// Open the port one time, then init your settings
serialPort = (SerialPort)portId.open("SimpleWriteApp", 2000);
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

// Get the input/output streams for use in the application
outputStream = serialPort.getOutputStream();
inputStream = serialPort.getInputStream();

// Finally, add your event listener
serialPort.addEventListener(this);

Upvotes: 3

Ashish
Ashish

Reputation: 1941

NO,you cant read and write simultaneously on the same port. Because to avoid deadlock condition.

i gone through your code and i found... in the while loop

        while (portList.hasMoreElements())
            {
              } 

the problem is with the while loop since portlist has no elememts to read.

Upvotes: 0

Related Questions