2011-04-28 2 views
6

Je n'ai aucune idée de ce qui arrive à mon code. Je ne reçois aucune erreur et aucune réponse aussi bien. J'écris les données sur le port série et attend la réponse en activant port.notifyOnDataAvailable(true); mais cet événement n'est pas déclenché et inputstream.available() renvoie 0 toujours. Quel pourrait être le problème? J'utilise RXTX sous Linux.inputstream.available() est 0 toujours

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 

J'ouvre le port sur la méthode principale et l'envoi du message sur un bouton événement click dans l'application.

+0

Pouvez-vous montrer un code simple qui reproduit le problème? – sarnold

+0

@sarnold: vérifiez mon edit ... – Deepak

+0

better :) Merci; quelle sortie obtenez-vous de 'System.out.println (event.getEventType());'? En outre, je trouverais quelque peu étrange qu'un périphérique série ait une méthode 'available()'; le [exemple] (http://rxtx.qbang.org/wiki/index.php/Event_based_two_way_Communication) simplement 'read()' et voir s'il a des données .. – sarnold

Répondre

5

.available() ne peut pas être utilisé dans la communication inter-processus (série incluse), s En effet, il vérifie seulement s'il y a des données disponibles (dans les tampons d'entrée) dans le processus en cours.

En communication série, lorsque vous envoyez un messaga et que vous appelez immédiatement available(), vous obtenez généralement 0 car le port série n'a encore répondu à aucune donnée.

La solution consiste à utiliser le blocage read() dans un thread séparé (avec interrupt() pour y mettre fin):

Thread interrupt not ending blocking call on input stream read

+0

mais ne sera pas le SerialPortEventListener sert le travail pour nous ici? au lieu d'utiliser un fil séparé? – Deepak

2

Pour répondre partiellement à votre question.

Des javadocs

La méthode disponible pour la classe InputStream retourne toujours 0.

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

donc qu'une partie au moins est comme prévu

+0

alors cela signifie qu'il n'y a pas de réponse à venir hors du terminal que j'écris le message à ?? – Deepak

+2

InputStream est une classe abstraite, donc vous avez toujours affaire à une sous-classe concrète qui pourrait surcharger 'available'. –

+0

-1 Il existe une différence entre la classe 'InputStream' et l'objet' inputstream'. –

2

En utilisant un PrintStream vous répriment exceptions que vous devez savoir sur dans toute demande/scénario de réponse.

Très probablement, vous n'avez encore rien envoyé.

+0

mais quand j'appelle sendMessage (port, message) quelque chose sera écrit sur le port rite? – Deepak

+0

@Deepak: Pas si vous avez écrit via PrintWriter et qu'il y a eu une exception. PrintWriter avale des exceptions. Voir le Javadoc. C'est également une très mauvaise pratique, voire incorrecte, d'utiliser plusieurs flux superposés sur le même flux sous-jacent, comme vous le faites ici, surtout quand un ou plusieurs d'entre eux sont mis en mémoire tampon. Je ne sais pas non plus pourquoi vous créez le 'os' PrintStream deux fois. Vous devez simplifier tout cela en utilisant un seul flux d'entrée et un seul flux de sortie vers le port. – EJP

+0

ok je vais changer cela et vérifier si cela fonctionne – Deepak