11

I have no idea of what is happening to my code. i am getting no errors and no response as well. I am writing the data to the serialport and waiting for the response by activating port.notifyOnDataAvailable(true); but this event is not triggered and inputstream.available() returns 0 always. What might be wrong ? I am using RXTX in linux.

EDIT

package testConn;  
import forms_helper.global_variables;  
import java.io.BufferedReader; 
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.OutputStream;  
import java.io.PrintStream;  
import java.io.UnsupportedEncodingException;  
import java.util.logging.Level;  
import java.util.logging.Logger;  
import javax.comm.*;  
import java.util.*;  
/** Check each port to see if it is open. **/   
public class openPort implements SerialPortEventListener {

    static Enumeration portList;
    static CommPortIdentifier portId;
    static String messageString;
    public static SerialPort serialPort;
    static OutputStream outputStream;
    InputStream inputStream;
    static boolean outputBufferEmptyFlag = false;
    private BufferedReader is;
    private PrintStream os;

    public void open() {
        Enumeration port_list = CommPortIdentifier.getPortIdentifiers();

        while (port_list.hasMoreElements()) {
            // Get the list of ports
            CommPortIdentifier port_id = (CommPortIdentifier) port_list.nextElement();
            if (port_id.getName().equals("/dev/ttyS1")) {

                // Attempt to open it
                try {
                    SerialPort port = (SerialPort) port_id.open("PortListOpen", 20000);
                    System.out.println("Opened successfully:"+port);
                    try {
                        int baudRate = 9600; //
                        port.setSerialPortParams(
                                baudRate,
                                SerialPort.DATABITS_7,
                                SerialPort.STOPBITS_1,
                                SerialPort.PARITY_EVEN);
                        port.setDTR(true);


                        port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

                        System.out.println("properties are set");
                    } catch (UnsupportedCommOperationException e) {
                        System.out.println(e);
                    }
                    try {
                        //input = new SerialReader(in);
                        port.addEventListener(this);
                        System.out.println("listeners attached" + this);
                    } catch (TooManyListenersException e) {
                        System.out.println("too many listeners");
                    }
                    port.notifyOnDataAvailable(true);

                    //port.notifyOnOutputEmpty(true);
                    //sendMessage(port,"@PL");
                    //port.close ();
                    try {
                        is = new BufferedReader(new InputStreamReader(port.getInputStream()));
                    } catch (IOException e) {
                        System.err.println("Can't open input stream: write-only");
                        is = null;
                    }
                    try {
                        os = new PrintStream(port.getOutputStream(), true);
                    } catch (IOException ex) {
                        Logger.getLogger(openPort.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    try {
                        inputStream = port.getInputStream();
                        System.out.println("inputstream" + inputStream.available());
                        outputStream = (OutputStream) port.getOutputStream();
                        os = new PrintStream(port.getOutputStream(), true, "US-ASCII");


                    } catch (IOException e) {
                        System.out.println(e);
                    }

                    //set the created variables to global variables
                    global_variables.port = port;
                    global_variables.inputStream = inputStream;
                    System.out.println(inputStream);
                    System.out.println(outputStream);
                    global_variables.outputStream = outputStream;
                    global_variables.os = os;
                } catch (PortInUseException pe) {
                    System.out.println("Open failed");
                    String owner_name = port_id.getCurrentOwner();
                    if (owner_name == null) {
                        System.out.println("Port Owned by unidentified app");
                    } else // The owner name not returned correctly unless it is
                    // a Java program.
                    {
                        System.out.println("  " + owner_name);
                    }
                }
            }
        }
    }

    public static void sendMessage(SerialPort port, String msg) {
        if (port != null) {
                System.out.println(msg);
            try {
                byte[] bytes = msg.getBytes("US-ASCII");
                try {
                    global_variables.outputStream.write(bytes);
                    System.out.println(bytes.length);
                    global_variables.outputStream.flush();
                } catch (IOException ex) {
                    Logger.getLogger(openPort.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(openPort.class.getName()).log(Level.SEVERE, null, ex);
            }
                System.out.println("Opened successfully:"+msg.getBytes());
                //global_variables.outputStream.write(msg.getBytes());
                //global_variables.outputStream.flush();
                //global_variables.os.print(msg);
                System.out.println(global_variables.outputStream);
                try {
                    Thread.sleep(2000);  // Be sure data is xferred before closing
                    System.out.println("read called");
                    //SimpleRead read = new SimpleRead();
                    //int read = global_variables.inputStream.read();
                    //System.out.println("read call ended"+read);
                } catch (Exception e) {
                }

        }
    }

    public void serialEvent(SerialPortEvent event) {
        System.out.println(event.getEventType());
        String line;
                try {
                    line = is.readLine();
                    if (line == null) {
                        System.out.println("EOF on serial port.");
                        System.exit(0);
                    }
                    os.println(line);
                } catch (IOException ex) {
                    System.err.println("IO Error " + ex);
                }
        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:
            System.out.println("event.getEventType()");
            break;
             *
             */

            case SerialPortEvent.DATA_AVAILABLE:
                System.out.println("inside event handler data available");
                byte[] readBuffer = new byte[20];


                try {
                    while (inputStream.available() > 0) {
                        int numBytes = inputStream.read(readBuffer);
                    }
                    System.out.print(new String(readBuffer));
                    System.exit(1);
                } catch (IOException e) {
                    System.out.println(e);
                }

                break;
        }
    }
} // PortListOpen

I am opening the port on main method and sending the message on a button click event inside the application.

dsolimano
  • 8,870
  • 3
  • 48
  • 63
Deepak
  • 6,684
  • 18
  • 69
  • 121
  • Can you show some simple code that reproduces the problem? – sarnold Apr 28 '11 at 23:27
  • better :) Thanks; what output do you get from `System.out.println(event.getEventType());`? Further, I'd find it somewhat strange for a serial device to have an `available()` method; the [example](http://rxtx.qbang.org/wiki/index.php/Event_based_two_way_Communication) simply `read()` and see if it has data.. – sarnold Apr 29 '11 at 00:03
  • actually when i enabled port.notifyOnOutputEmpty(true) i got 2 running top to bottom. After i commented that out the controll is not entering the serialEvent().. – Deepak Apr 29 '11 at 00:11
  • actually it is not getting into the eventlistener() so even if i read the inputstream nothing will happen.. – Deepak Apr 29 '11 at 00:15

3 Answers3

8

.available() can not be used in inter-process communication (serial included), since it only checks if there is data available (in input buffers) in current process.

In serial communication, when you send a messaga and then immediately call available() you will mostly get 0 as serial port did not yet reply with any data.

The solution is to use blocking read() in a separate thread (with interrupt() to end it):

Thread interrupt not ending blocking call on input stream read

Community
  • 1
  • 1
Peter Knego
  • 79,991
  • 11
  • 123
  • 154
  • but wont the SerialPortEventListener serves the job for us here ? instead of using separate thread ? – Deepak Apr 28 '11 at 23:59
2

To partially answer your question.

From the javadocs

The available method for class InputStream always returns 0.

http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()

So that part at least is as expected

Kevin D
  • 3,564
  • 1
  • 21
  • 38
  • so does that means that there is no response coming out of the terminal which i am writing the message to ?? – Deepak Apr 28 '11 at 23:37
  • 3
    InputStream is an abstract class, so you are always dealing with some concrete subclass which might override `available`. – Jörn Horstmann Apr 29 '11 at 08:57
  • -1 There's a difference between class `InputStream` and object `inputstream`. – Terry Li Jan 14 '13 at 20:10
  • 1
    This is the full quote " The available method for class InputStream always returns 0. This method should be overridden by subclasses." – mulya Aug 13 '13 at 07:23
2

By using a PrintStream you are suppressing exceptions that you need to know about in any request/response scenario.

Most probably you haven't even sent anything yet.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • but when i call sendMessage(port,message) something wil be written onto the port rite ? – Deepak Apr 29 '11 at 00:16
  • @Deepak: Not if you wrote via the PrintWriter and there was an exception. PrintWriter swallows exceptions. See the Javadoc. It is also very bad practice, indeed incorrect, to use multiple streams layered over the same underlying stream, as you are doing here, especially when one or more of them is buffered. I also don't know why you're creating the PrintStream 'os' twice. You need to simplify all this using a single input stream from, and single output stream to, the port. – user207421 Apr 29 '11 at 00:36