-1

I have a RXTX project that I'm working on. I have it set ups as follows:

public void doConnect(ActionEvent event)
    {
        String selectedPort = (String)connectTabController.portList.getValue();
        System.out.println("Connecting to: " + selectedPort);
        selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort);
        CommPort commPort = null;
        try
        {
            commPort = selectedPortIdentifier.open("AT QC ReponseTime", TIMEOUT);
            serialPort = (SerialPort)commPort;
            setConnected(true);
            if (isConnected)
                    {
                        if (initIOStream() == true)
                                {
                                    initListener();
                                    System.out.println("Initializing listener");
                                    connectTabController.gui_changeStatusLabel("Device Connected!");
                                }
                    }
        }
        catch (PortInUseException e)
        {
            System.out.println("Port In use! " + e.toString());
        }

        catch (Exception e)
        {
                    System.out.println("Failed to open! " + e.toString());
        }
    }
    public boolean initIOStream()
    {
        //return value for whether opening the streams is successful or not
        boolean successful = false;

        try {
            //
            input = serialPort.getInputStream();
            output = serialPort.getOutputStream();
            writeData(RESETTPOD);
            System.out.println("Writing Reset command");

            successful = true;
            System.out.println("IO Stream opened successfully!");
            return successful;

        }
        catch (IOException e) {
            System.out.println("I/O Streams failed to open. (" + e.toString() + ")");
            return successful;
        }
    }


    public void initListener()
    {
        try
        {
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        }
        catch (TooManyListenersException e)
        {
            System.out.println("Too many listeners. (" + e.toString() + ")");

        }
    }

That's how the connection is made, and it has a listener that's supposed to notify when data is available, which triggers the following:

@Override
    public void serialEvent(SerialPortEvent evt) {

        BufferedReader reader = null;

        if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
        {
            try
            {
                reader = new BufferedReader(new InputStreamReader(input));

                if (reader.ready())
                {
                fullLine = reader.readLine();
                System.out.println(fullLine + "\n");
                }

            }
            catch (Exception e)
            {
                System.out.println("@SerialEvent Failed to read data. (" + e.toString() + ")");
            }
        }
}

However, I keep getting "UNDERLYING INPUT STREAM RETURNED ZERO BYTES"

This makes no sense, since if there is nothing to read then the listener shouldnt be triggered int he first place. I tried running the app and I keep getting this error message around every 1/3 second, which corresponds to the burst-output of the device that's sending data. (which works fine in programs like PuttY)

  • Aren't you repeatedly creating new buffered readers out of the same input stream? – James_D May 22 '17 at 18:25
  • Well, yeah i guess now that I think about it it does override and create a new buffered reader every time theres a notification. however if I create the buffered reader in the initIOStrema method (right after I assign values to input / output) I still get the same issue – David Boydston May 22 '17 at 19:07
  • It's basically always a mistake to hold a reference to the underlying stream if you wrap it in another stream/reader. – James_D May 22 '17 at 19:14
  • Each buffered reader will try to fill its buffer from the stream. So at some point one of the readers won't have data to read... Why do you need to listen for "data available" anyway? Why not just let the reader read; it will block as needed – James_D May 22 '17 at 19:16
  • Oh! I didnt know that, well I have an output that I need updated everytime the device sends new data, so from what I've read on examples and other projects I've seen around they usually add a listener with the data_available. what other way is there that outputs data as soon as its received? – David Boydston May 22 '17 at 19:42
  • I don't know the library, so I don't know what guarantees are made for the `DATA_AVAILABLE` event, but it is basically certain that creating multiple buffered readers from the same input stream will break things badly. – James_D May 22 '17 at 21:29

1 Answers1

0

If you are going to use the BufferedReader, take a look at the refence API document for javax.comm, CommPort and getInputStream. Then try using different settings for threshold and receive timeout.

eg). serialPort.enableReceiveThreshold(3); serialPort.enableReceiveTimeout(1);

https://docs.oracle.com/cd/E17802_01/products/products/javacomm/reference/api/