2011-04-28 47 views
6

No tengo idea de qué está pasando con mi código. no recibo errores ni respuestas. Estoy escribiendo los datos en el puerto serie y esperando la respuesta activando port.notifyOnDataAvailable(true);, pero este evento no se desencadena y inputstream.available() devuelve 0 siempre. ¿Qué podría estar mal? Estoy usando RXTX en Linux.inputstream.available() es 0 siempre

EDITAR

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 

estoy abriendo el puerto en el método principal y enviar el mensaje en un evento de clic de botón dentro de la aplicación.

+0

¿Puedes mostrar un código simple que reproduzca el problema? – sarnold

+0

@sarnold: verifique mi edición ... – Deepak

+0

mejor :) Gracias; ¿Qué salida obtiene de 'System.out.println (event.getEventType());'? Además, me parece un tanto extraño que un dispositivo serial tenga un método 'available()'; el [ejemplo] (http://rxtx.qbang.org/wiki/index.php/Event_based_two_way_Communication) simplemente 'read()' y ver si tiene datos ... – sarnold

Respuesta

5

.available() no se puede usar en la comunicación entre procesos (serial incluida), s ya que solo verifica si hay datos disponibles (en los buffers de entrada) en el proceso actual.

En la comunicación en serie, cuando envía una mensajera y luego llama inmediatamente al available(), obtendrá en su mayoría 0, ya que el puerto serie todavía no respondió con ningún dato.

La solución es utilizar el bloqueo de read() en un hilo separado (con interrupt() para acabar con ella):

Thread interrupt not ending blocking call on input stream read

+0

pero ¿no servirá el SerialPortEventListener para nosotros? en lugar de usar hilo separado? – Deepak

2

Para responder parcialmente a su pregunta.

De los javadocs

El método disponible para la clase InputStream siempre devuelve 0.

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

de modo que parte al menos es como se esperaba

+0

así que eso significa que no hay respuesta fuera de la terminal a la que estoy escribiendo el mensaje? – Deepak

+2

InputStream es una clase abstracta, por lo que siempre se trata de una subclase concreta que puede anular 'disponible'. –

+0

-1 Hay una diferencia entre la clase 'InputStream' y el objeto' inputstream'. –

2

Mediante el uso de un PrintStream estás suprimiendo excepciones que usted necesita saber acerca de cualquier solicitud/escenario de respuesta.

Probablemente aún no haya enviado nada.

+0

pero cuando llamo sendMessage (port, message) algo se escribirá en el rito del puerto? – Deepak

+0

@Deepak: No si escribió a través del PrintWriter y hubo una excepción. PrintWriter traga excepciones. Ver el Javadoc. También es una práctica muy mala, de hecho incorrecta, utilizar varias secuencias en capas sobre la misma secuencia subyacente, como lo está haciendo aquí, especialmente cuando una o más de ellas están almacenadas en búfer. Tampoco sé por qué está creando PrintStream 'os' dos veces. Debe simplificar todo esto utilizando una sola corriente de entrada desde, y una sola salida, al puerto. – EJP

+0

ok, voy a cambiar eso y verificar si funciona – Deepak