Lectura puerto serie

Hola
Estoy trabajando con la librería javacomm, leo y escribo en un puerto serie.El problema que tengo es que no se como hacer para que leer y escribir por el mismo puerto.
Actualmente estoy empleado el código de lectura de este link http://www.itapizaco.edu.mx/paginas/JavaTut/froufe/parte19/cap19-3.html , básicamente crea un hilo y si se efectúa un evento en el puerto donde este escuchando lee el dato que entre, lo que pasa es que si yo quiero escribir por el mismo puerto me falla, ya que dicho puerto esta en uso.
¿Cómo puedo leer y escribir por un mismo puerto? ¿
Un saludo

1 Respuesta

Respuesta
1
Para que puedas escribir y leer en el mismo puerto no tienes que crear una conexión separada para lectura y otra para escritura, cuando abres tu puero serial con el objeto Serial obtén un InputStream y un OutputStream del mismo. Tu thread de lectura estaría verificando el InputStream y cada que quieras escribir utilizas el OutputStream pero no pierdas la referencia de estos objetos. Si intentas abrir una nueva conexión cada vez que escribes entonces es cuando obtienes el error que mencionas.
Si no te queda muy claro puedes pegar algo de tu código y trabajamos sobre el.
Te voy a poner el código que estoy empleando, por que soy algo novato con esta librería, el código con el que estoy trabajando es de este link: http://www.itapizaco.edu.mx/paginas/JavaTut/froufe/parte19/cap19-3.html.
Tiene una clase que escribe y otra clase que lee:
Clase de Escritura:
import java.io.*;
import java.util.*;
import javax.comm.*;
public class java1901 {
static Enumeration listaPuertos;
static CommPortIdentifier idPuerto;
static String mensaje = "Tutorial de Java, Comunicaciones Serie\n";
static SerialPort puertoSerie;
static OutputStream salida;
public static void main( String[] args ) {
listaPuertos = CommPortIdentifier.getPortIdentifiers();
while( listaPuertos.hasMoreElements() ) {
idPuerto = (CommPortIdentifier)listaPuertos.nextElement();
if( idPuerto.getPortType() == CommPortIdentifier.PORT_SERIAL ) {
// if( idPuerto.getName().equals("/dev/term/a") ) {
if( idPuerto.getName().equals("COM1") ) {
// Si el puerto no está en uso, se intenta abrir
try {
puertoSerie = ( SerialPort )idPuerto.open("AplEscritura",2000);
} catch( PortInUseException e ) {}
// Se obtiene un canal de salida
try {
salida = puertoSerie.getOutputStream();
} catch( IOException e ) {}
// Se fijan los parámetros de comunicación del puerto
try {
puertoSerie.setSerialPortParams( 9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE );
} catch( UnsupportedCommOperationException e ) {}
// Se envía el mensaje
try {
salida.write( mensaje.getBytes() );
} catch( IOException e ) {}
}
}
}
}
}
Clase de Lectura:
import java.io.*;
import java.util.*;
import javax.comm.*;
public class java1902 implements Runnable,SerialPortEventListener {
  static CommPortIdentifier idPuerto;
  static Enumeration listaPuertos;
  InputStream entrada;
  SerialPort puertoSerie;
  Thread tLectura;
  // En este ejemplo implementa un thread que es el que se encarga de
// que la aplicación se quede esperando en el puerto que se haya
// abierto a que se reciban datos.
  // Primero abre el puerto y luego le fija los parámetros
  public java1902() {
    // Si el puerto no está en uso, se intenta abrir
    try {
      puertoSerie = (SerialPort)idPuerto.open( "AplLectura",2000 );
    } catch( PortInUseException e ) {}
    // Se obtiene un canal de entrada
    try {
      entrada = puertoSerie.getInputStream();
    } catch( IOException e ) {}
    // Añadimos un receptor de eventos para estar informados de lo
    // que suceda en el puerto
    try {
      puertoSerie.addEventListener( this );
      } catch( TooManyListenersException e ) {}
    // Hacemos que se nos notifique cuando haya datos disponibles
    // para lectura en el buffer de la puerta
    puertoSerie.notifyOnDataAvailable( true );
    // Se fijan los parámetros de comunicación del puerto
    try {
      puertoSerie.setSerialPortParams( 9600,
        SerialPort.DATABITS_8,
        SerialPort.STOPBITS_1,
        SerialPort.PARITY_NONE );
    } catch( UnsupportedCommOperationException e ) {}
    // Se crea y lanza el thread que se va a encargar de quedarse
    // esperando en la puerta a que haya datos disponibles
    tLectura = new Thread( this );
    tLectura.start();
    }
  public void run() {
    try {
      // En los threads, hay que procurar siempre que haya algún
      // método de escape, para que no se queden continuamente
      // bloqueados, en este caso, la comprobación de si hay datos
      // o no disponibles en el buffer de la puerta, se hace
      // intermitentemente
      Thread.sleep( 20000 );
    } catch( InterruptedException e ) {}
    }
  public void serialEvent( SerialPortEvent _ev ) {
    switch( _ev.getEventType() ) {
      // La mayoría de los eventos no se trata, éstos son los
// que se producen por cambios en las líneas de control del
// puerto que se está monitorizando
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;
      // Cuando haya datos disponibles se leen y luego se
      // imprime lo recibido en la consola
      case SerialPortEvent. DATA_AVAILABLE:
        byte[] bufferLectura = new byte[20];
        try {
          while( entrada.available() > 0 ) {
            int nBytes = entrada.read( bufferLectura );
            }
          System.out.print( new String(bufferLectura) );
        } catch( IOException e ) {}
        break;
      }
    }
  public static void main( String[] args ) {
    // Lista de los puertos disponibles en la máquina. Se carga en el
    // mimo momento en que se inicia la JVM de Java
    listaPuertos = CommPortIdentifier.getPortIdentifiers();
    while( listaPuertos.hasMoreElements() ) {
      idPuerto = (CommPortIdentifier)listaPuertos.nextElement();
      if( idPuerto.getPortType() == CommPortIdentifier.PORT_SERIAL ) {
//        if( idPuerto.getName().equals("/dev/term/a") ) {  // UNIX
        if( idPuerto.getName().equals("COM1") ) {           // WINDOWS
          // Lector del puerto, se quedará esperando a que llegue algo
          // al puerto
          java1902 lector = new java1902();
          }
        }
      }
    }
  }
La idea es coger este código y adaptarlo para tener una c lase de lectura y otra clase de escritura, y crear un objeto de lectura y escritura en mi clase principal y emplearlos.
Haber si me puedes ayudar ya que ando algo perdido, gracias¡
Crea una sola clase, el problema que tienes ahorita es que tienes definidas variables estáticas en ambas clases y en ambas clases estas intentando abrir el puerto serial. La idea es que hagas algo como esto:
class SerialPortManager {
  Enumeration listaPuertos; 
  CommPortIdentifier idPuerto; 
  String mensaje = "Tutorial de Java, Comunicaciones Serie\n"; 
  SerialPort puertoSerie; 
  OutputStream salida; 
  InputStream entrada;
  public void abrirPuerto(){
     .....
     salida = puertoSerie.getOutputStream();
     entrada = puertoSerie.getInputStream();
  }
  public void escribirEnPuerto(...){
     .....
  }
}
Para la parte de leer datos del puerto puedes usar el patrón de observador, es decir que cuando lleguen datos al puerto estos van a ser leídos por un thread, cuando los datos estén disponibles les avisas a los objetos que estén observando que hay un dato nuevo.
Hola buenas finalmente cree como me indicaste una clase llamada puertoSerie, que tiene los siguientes métodos:
1-AbrirPuerto
2-ConfigurarPuerto
3-LeerPuerto
4-EscribirPuerto
He probado a emplearla para enviar una serie de comandos AT a un terminal gsm para enviar un SMS y ha funcionado correctamente¡, el problema que tengo ahora es que a parte de enviar también quiero recibir.
La idea que me diste de crear un hilo que escuche en el puerto serie y que se active si ahí algo que leer, es lo siguiente que voy hacer, lo que pasa es que no se muy bien como emplearlo, ahí un ejemplo arriba llamado clase lectura que hace eso pero no se como implementarlo con lo que ya tengo hecho... me puedes indicar unas pautas, no tengo experiencia con hilos.
También te quería consultar si sabes los comandos AT que ahí que pasarle al terminal para que en caso de que llegue un sms lo pueda leer.
Bueno ante todo gracias¡ Si quieres la clase que he creado pásame tu correo y te la envío, un saludo¡
No precisamente requieres otro solo para la lectura, lo sugería como una forma de poner todo lo que tiene que ver con el puerto serial en otro thread para que no interfiriera digamos con el flujo normal del programa en el caso de que hubiera un error o se quedara esperando mucho tiempo.
En cualquier caso si quieres crear un thread la forma más fácil es que crees una clase que implemente la interfaz Runnable y escribas tu código dentro del método Run. Para arrancar este thread usarías algo así:
Thread t = new Thread(clasequeimplementaRunnable);
t.start();
Sobre los comandos AT ahí si te voy a quedar mal je je, pero me imagino que en internet puede haber alguna referencia a ellos o quizás en el sitio del fabricante de tu modem haya algo de info.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas