octubre
10
en la Categoría: Mira que he aprendido hoy!!, escrito por Joste el 10-10-2007

Esta semana mientras trabajaba me ha surgido un problema. Tenía que controlar y escuchar un GPS bluetooth mediante java. Obviamente lo interesante no ha sido el escuchar al gps y parsear los datos, eso es una tarea bastante normalucha. Pero si que ha sido interesante descubrir como se puede uno comunicar mediante java a cualquier puerto del ordenador correctamente configurado.

Para ello es necesaria una libreria de comunicaciones. En su día funcionó muy bien la famosa comm.jar, pero ya está en desuso y ahora se utiliza la RXTXcomm.jar No se muy bien cuales son las ventajas y desventajas, pero sun se desentendió de su librería y ahora no hay mas remedio que utilizar esta (si alguien conoce otra forma que lo diga).

Os la podeis descargar desde aquí:

ftp://ftp.qbang.org/pub/rxtx/rxtx-2.1-7-bins-r2.zip

En el zip encontrareis el jar y luego varios añadidos dependiendo del sistema operativo. Para windows hay que copiar unls dll en el directorio de java. Miraros las instrucciones que están muy bien.

Una vez que teneis todo instalado, podeis comunicaros con los puertos serie y paralelo. Puertos como COM y LPT, que controla impresoras, dispositivos externos, escaners… y podeis trabajar con ellos.

Un codigo para leer los puertos existentes:

/**

* private method that lists all the available ports of the device and then ask the user to select one

* @return selected port

*/

private String ListPorts() {

Vector names = null;

int index = -1;

while (index == -1) {

int j = 1;

names = new Vector();System.

out.println(“Available ports: “);

CommPortIdentifier c;

for (Enumeration i = CommPortIdentifier.getPortIdentifiers() ; i.hasMoreElements() ;) {

c = (CommPortIdentifier) i.nextElement();

System.out.print(j++ +“. “ + c.getName());

names.add(c.getName());

if (c.getPortType() == CommPortIdentifier.PORT_SERIAL)

System.out.print(“\t SERIAL\n”);

if (c.getPortType() == CommPortIdentifier.PORT_PARALLEL)System.out.print(“\t PARALLEL\n”);

}

System.out.print(“Select port: “);

String input = readFromUser();

 

try {

index = Integer.parseInt(input);}

catch (NumberFormatException e) {

index = -1;

continue;

}

 

if ( (index < 1) || (index >= names.size()) ) {

index = -1;

continue;

}

}

 

return names.elementAt(index – 1).toString();

}

Con este codigo podeis listar toodos los puertos que estan disponibles en vuestro pc y listarlos para elegir el que quereis seleccionar.

 Para abrir un puerto no hay mas que:

CommPort port = CommPortIdentifier.getPortIdentifier(portname).open(“NMEAPrueba”, 3000);

Donde el portname es una variable String que contiene el nombre del puerto a abrir, en mi caso era “COM18″. Esta variable era el retorno del codigo que he puesto antes. Y “NMEAPrueba” es el nombre de quien lo abre, para que al poseerlo los demas sepan quien es el dueño.

Una vez abierto el puerto, podemos obtener un InputStream y un OutputStream para mandar y recibir informacion. Yo utilizo BufferedInputStream porque me es mas comodo

BufferedInputStream input = new BufferedInputStream(port.getInputStream());

BufferedOutputStream output = new BufferedOutputStream(port.getOutputStream());

Una vez con  estos objetos ya todo depende del desarrollador. Por ejemplo para el GPS bluetooth solo hay que escuchar los datos que se reciben e interpretarlo, no hace falta enviar (bueno, se pueden enviar cosas dependiendo del protocolo que siga el GPS pero en general sin enviar nada se puede escuchar continuamente lo que manda el GPS). Todo depende del programador y del destino.

IMPORTANTIIIISIMO: cerrar los puertos y los streams que si no, se bloquean a veces y quedan inservibles. Hasta que me di cuenta de un error de codigo que tenía en mi GPS, me pase dos días configurando cada 5 minutos un nuevo puerto porque el viejo ya no funcionaba.

Mas o menos así

input.close();

output.flush();

output.close();

port.close();

Dudas, a los comentarios

Technorati , , , ,

Comentarios

wendigo el 10-10-2007 a las 9:36

Seria muy interesante añadirle esto del GPS por BT a mi Lego NXT.. aunque de momento con manejarlo con el mando de la Wii ya tengo bastante ¬¬’


joste el 10-10-2007 a las 10:18

Todo es probarlo… podemos hacer experimentos y luego publicarlo por aqui!


Jaume el 10-10-2007 a las 14:09

Hola Joste,

Yo tambien utilizo esta libreria pero no hay manera de enviar mensajes aunque los puedo recibir, y a veces estan truncados los que recibo en varios mensajes.

Te pongo el codigo java del programa que envia y el que recibe a ver si me das alguna pista.

el Que envia:

import java.io.IOException;
import java.io.OutputStream;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.BufferedOutputStream;

public class Escritura {
public Escritura() {
}

static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream outputStream;
static BufferedOutputStream output;

public static void envio(String mensaje) {

Rutinas ctl = new Rutinas();

SerialPort serialPort = Hits.getSerialPort();
try {
output = new BufferedOutputStream(serialPort.getOutputStream());
} catch (IOException e) {
ctl.logWrite(” ******* Exception ” + e.getMessage() + ” capturada en Escritura () a “+ctl.hora_actual()+”********”);
}
try {

output.write(mensaje.getBytes());
System.out.println(“Sended from me:”+mensaje);
} catch (IOException e) {
ctl.logWrite(” ******* Exception ” + e.getMessage() + ” capturada en Escritura () a “+ctl.hora_actual()+”********”);
}

}


Jaume el 10-10-2007 a las 14:10

El que recibe:

import java.io.*;
import java.util.*;

import gnu.io.*;

public class Hits implements SerialPortEventListener {

static CommPortIdentifier portId;
static Enumeration portList;

//InputStream inputStream;
BufferedInputStream inputStream;

static SerialPort serialPort;
Thread readThread;

protected static String mensaje = new String();

public static int periodo = 10;
public static int retardo = 0;

public static SerialPort getSerialPort() {
return serialPort;
}

public Hits() {
Rutinas ctl = new Rutinas();
try {
serialPort = (SerialPort) portId.open(“HITS”, 2000);

} catch (PortInUseException e) {
serialPort.close();
ctl.logWrite(” ******* Exception ” + e.getMessage() + ” capturada en HITS () a “+ctl.hora_actual()+”********”);
}
try {
// BufferedInputStream input = new BufferedInputStream(serialPort.getInputStream());
// inputStream = serialPort.getInputStream();
inputStream = new BufferedInputStream(serialPort.getInputStream());
} catch (IOException e) {
ctl.logWrite(” ******* Exception ” + e.getMessage() + ” capturada en HITS () a “+ctl.hora_actual()+”********”);
}
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
ctl.logWrite(” ******* Exception ” + e.getMessage() + ” capturada en HITS () a “+ctl.hora_actual()+”********”);
}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
ctl.logWrite(” ******* Exception ” + e.getMessage() + ” capturada en HITS () a “+ctl.hora_actual()+”********”);
}

}

public void serialEvent(SerialPortEvent event) {
Rutinas ctl = new Rutinas();
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:
break;
case SerialPortEvent.DATA_AVAILABLE:
try {
Thread.sleep(1000);
} catch (Exception r) {

}

byte[] readBuffer = new byte[600];
try {
int numBytes = 0;
while (inputStream.available() > 0) {
numBytes = inputStream.read(readBuffer);
}
String result = new String(readBuffer);

mensaje = result.substring(1, numBytes);

// Monitorizo salida

System.out.println(“Received from Hits:”+mensaje);

// Aqui se Captura los envios de parametros (evenListener)

if (mensaje.startsWith(“DR”)) { // Sincronizacion Inicial

ctl.envioLA();
ctl.sincronismoArranque();
} else if (mensaje.startsWith(“PS”)) { // Post
ctl.envioLA();

} else if (mensaje.startsWith(“LS”)) { // Post
ctl.envioLA();

}

} catch (IOException e) {

}

break;
}
}


Jaume el 10-10-2007 a las 15:38

El problema que estoy detectando tanto enviando como recibiendo es que los mensajes estan truncados, es decir, envio 1 mensaje de 40 posiciones por ejemplo y recibo 3 mensajes de vuelta. Parece como si el buffer no funcionara como dios manda…

Jaume.


joste el 10-10-2007 a las 9:52

Hola Jaume!
Vaya, no entiendo muy bien lo que te ocurre.
Cuando hablas de mensajes, qué quieres decir? Los eventos que se lanzan a través del puerto? En principio cuando se abre un puerto, se tiene un Stream, un “chorro” de bits que no entiende de mensajes… No controlo mucho de eventos pero cuando llega uno, en tu código de recibir, si es de datos accesibles, lee los datos hasta que se terminan (supongo que todo esto es un mensaje para ti verdad?) Con qué te estas comunicando a través del puerto? con un GPS también? (es para saber el tipo de datos que utilizas)

Ok, por otro lado, sobre lo de truncado, date cuenta de que has puesto un buffer de 600bytes para leer, eso es suficiente? no se truncará porque no te entran en el buffer los mensajes? yo utilizo un StringBuffer y lo traduzco de bytes a caracteres (no se que información te llega en los mensajes)
while ((data = input.read()) > 0 && data != (char) 13 && active) {
if (data != (char) 10) { buffer.append((char)data);
}
}
siendo input el BufferedInputStream, active una variable mia para controlar que tengo o no tengo que leer y data una variable local de tipo int.

Sobre el envio, todo parece correcto, quiero decir, no se que le pasas como parametro de entrada “mensaje” al metodo envio pero parece que luego va todo bien. Mira a ver si la llamada la hacer también con un buffer limitado y por eso el parametro de entrada está truncado… En principio no entiendo que se trunque por otra cosa.

Y por si las moscas (me dio muchos problemas) cuidate de cerrar TODO muy bien. Me refiero a los inputstream y outputstream del puerto y al mismo puerto.

A ver si esto te sirve de ayuda, y si no, no dudes en volver a preguntar.
Un saludo
Joste


joste el 10-10-2007 a las 9:54

También puedes hacer un flush al final del envío por si las moscas antes de cerrar el output stream y el puerto si procede.


Jaume el 10-10-2007 a las 13:13

Gracias Joste por tu aportacion,

EL problema que he detectado es que puedo recibir los mensajes, pero algunos en vez de recibirlos enteros los recibo con dos o tres mensajes (data_avaliables).

Los mensajes me los envian desde un servidor de Televisiones PayPerView y aunque ponga el Buffer a 4096 me siguen truncando los mensajes.

Ellos me envian como primer caracter de envio un STX (02h) y al final del mensaje un ETX (03h).

Yo tambien tendria que hacer lo mismo, pero no se como ….

Mi eventListener tendria que tener un control Byte por Byte de los chars que me envian para detectar cuando empieza el mensaje y cuando acaba…..

is 02h and is 03h. Beside that you will need to send/receive (06h), (15h) or (05h).

Por otro lado yo tendria que enviar mis mensajes con STX al principio y ETX al final.

Tambien tendria que tener algo para poder sincronizar, ya que la aplicacion siempre esta activa. NO puedo enviar datos cuando los estoy recibiendo y viceversa..

Vamos que creo que de esta no salgo sin ayuda..

Saludos y gracias..


Joste el 10-10-2007 a las 14:23

Yo en mi programa si que hago un control byte a byte. Mira el comentario 6. Necesito ver cuando empieza con un byte concreto como tu, y también cuando termina. cojo un byte y lo paso a char.
Lo mismo puedes hacer al enviar…
Si quieres ayuda concreta de un trozo de código, planteamelo o me puedes dar tu email de contacto para que intentemos solucionar el problema.


Jaume el 10-10-2007 a las 17:46

Hola Joste,

Mi email es jaume_g@yahoo.com

Ya puedo enviar los mensajes correctamente. He puesto los chars correspondientes a STX y ETX al principio y final del mensaje.
static public final char STX=0×02;
static public final char ETX=0×03;

Ahora solo me queda controlar los mensajes (STX, ETX y CRC -checksum) de entrada en el eventListener.

Tendria que controlar Byte por Byte la entrada de buffer para poder saber cuando empieza el mensaje y cuando acaba..

Podemos escribirnos por messenger ? lo digo porque sera mas rapido. Mi messenger email es el mismo que te he puesto.

Esta es la codificacion actual del metodo (esta mal):
BufferedInputStream inputStream;
public void serialEvent(SerialPortEvent event) {
Rutinas ctl = new Rutinas();
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:
break;
case SerialPortEvent.DATA_AVAILABLE:
try {
Thread.sleep(1000);
} catch (Exception r) {

}

byte[] readBuffer = new byte[4096];
int available= 0;
try {

int numBytes = 0;
while (inputStream.available() > 0) {
numBytes = inputStream.read(readBuffer);
}
String result = new String(readBuffer);

mensaje = result.substring(0, numBytes);

// Monitorizo salida

System.out.println(“Received from Hits:”+mensaje);

// Aqui se Captura los envios de parametros (evenListener)

}

} catch (Exception e) {

}

break;
}
}


Jaume el 10-10-2007 a las 17:54

Los mensajes que me llegan a la entrada tienen este formato:

GI|G#*1000201*|RN*101*|GN*Mr.
> Wong*|GS*N*|GV*0*|GL*ES*|TV*TU*|VR*VA*|DA*070907*|TI*101059*|

Donde = Empieza
acaba
Checksum

Pero estos mensajes me pueden llegar en dos o tres Data_avaliables. Como si no cabiesen en el buffer. Aunque ponga el buffer a 4096 me pasa lo mismo me llegan varios mensajes… NO se si me explico…

Saludos


Jaume el 10-10-2007 a las 17:56

En el mensaje 11 faltan los STX ETX y LRC.. No se porque no han salido.

STX GI|G#*1000201*|RN*101*|GN*Mr.
> Wong*|GS*N*|GV*0*|GL*ES*|TV*TU*|VR*VA*|DA*070907*|TI*101059*|ETX LRC

Donde STX = Empieza
ETX acaba
LRC Checksum


Joste el 10-10-2007 a las 19:21

Entonces, tienes unos mensajes llamemoslos completos, que por alguna razon te llegan divididos en diferentes paquetes. Los mensajes comienzan por STX y terminan por ETX, y entre paquetes no hay ningun caracter que ayude a reconocer los datos.
Entonces, has probado a cuando te llega un STX, ir metiendo todo lo que llegue (aunque sea de diferentes paquetes) en un buffer hasta que en algún momento te llegue un ETX?
Para leer byte a byte no tienes mas que hacer un input.read() y meterlo en una variable de tipo char.
Y para enviar, sabiendo los bytes que son, envialos directamente antes y después del mensaje.
Solo necesitas una variable que almacene los datos y que no pierda el valor entre paquete y paquete, una variable no local.


Jaume el 10-10-2007 a las 11:55

Ya tengo solucionado lo del envio de mensajes. Hago los envios byte por byte.
Aqui esta el metodo:
public static void envioBytes(byte[] campo, int len,BufferedOutputStream output) throws IOException {

byte lrc = 0; // LRC seed
output.write(STX); // Empieza Mensaje
for(int i=0; i


Jaume el 10-10-2007 a las 11:57

Ostras otra vez el mensaje truncado….

Te agradeceria si me pudieras ayudar en construir el metodo loop de captura sobre el puerto byte a byte y el montaje de las variables suplementarias.

Si eres de Barcelona tienes unas copas pagadas !

Gracias de antemano..


Jaume el 10-10-2007 a las 12:06

Por cierto podrias darme tu email para enviarte todo mi codigo ?

Saludos y gracias de nuevo.


Joste el 10-10-2007 a las 14:25

No, no soy de Barcelona, pero si hace falta me acerco en un pis pas… tengo muchos amigos por allí y tengo que hacerles una visita en breve… te tomo la palabra jeje.
Esta tarde te posteo un programa que te haga ese trabajito, a ver si te funciona. Si no, ya hablaremos de los correos, pero de normal no me gusta publicar mi correo alegremente…
Hablamos esta tarde


Jaume el 10-10-2007 a las 17:14

Ok Gracias !


Cristian el 10-10-2007 a las 20:08

Hola, he estado leyendo tu blog y tus indicaciones sobre java y comunicacion serial. He estado intentando hacer funcionar la api desesperadamente y no he podido hacerlo, ya tengo dolores de cabeza, he seguido al pie de la letra las indicaciones de instalacion, copie tu codigo de ejemplo, lo compilo y todo OK, pero cuando lo ejecuto me envia el siguiente mensaje:

java.lang.UnsatisfiedLinkError: /usr/share/jdk1.5.0_14/jre/lib/i386/librxtxSerial.so: /usr/share/jdk1.5.0_14/jre/lib/i386/librxtxSerial.so: wrong ELF class: ELFCLASS64 (Possible cause: architecture word width mismatch) thrown while loading gnu.io.RXTXCommDriver

dentro del directoria de la API de comm hay subdirs que corresponden a diferentes SO, dentro del dir de linux hay 3 dirs que estan separadas por arquitectura, finalmente copio el archivo que esta en este dir: rxtx-2.1-7-bins-r2/Linux/x86_64-unknown-linux-gnu$
ese archivo lo copio dentro del dir del jre/lib/i386/
diganme que estoy haciendo mal plz.
ya he copiado la api a l dir ext del jre.

Les agredezco su ayuda.


Joste el 10-10-2007 a las 8:42

Hola Cristian
Tiene toda la pinta de que la libreria RXTXComm no esta funcionando bien.

Como verás en el manual, solo está explicado por encia y además en la versión de windows. Si te lees el fichero INSTALL que viene en el zip de la libreria, dice:
INSTALLATION:
Linux (only x86, x86_64, ia64 here but more in the ToyBox)
RXTXcomm.jar goes in /jre/lib/ext (under java)
librxtxSerial.so goes in /jre/lib/[machine type] (i386 for instance)
Make sure the user is in group lock or uucp so lockfiles work.

Supongo que con eso ya te irá. Mas que la copia de la libreria es la copia del archivo librxtxSerial.so que creo qu no has hecho lo que te falla.
Leete de todas formas el archivo de instalación a ver si te aclara algo mas. Tal vez tu versión de linux no sea compatible?
No soy un experto en linux, sorry.
Espero que te sea de ayuda.


Cristian el 10-10-2007 a las 14:42

GRacias por la respuesta, ya solucione mi problema. La solucion es la siguiente:
estaba copiando mal el archivo librxtxSerial.so, hay 3 dirs que contienen una version distinta y la que corresponde a mi caso es el que se encuentra en i686-unknown-linux-gnu, lo raro que es que el computador es una i386… pero bueno. la solucion la encontre a prueba y error.
Saludos!


Joste el 10-10-2007 a las 16:10

Ok, entonces ya está funcionando verdad? Gracias por compartir la solución a tu problema


Cristian el 10-10-2007 a las 22:09

Exactamente, funciona OK.


Lord dark sirius el 10-10-2007 a las 2:53

El problema es que tienes que poner un tiempo de espera durante la escritura yo use de 100ms, el proceso es simple

output.write(byte_a_escribir);
output.flush();
sleep(100);

De preferencia este metodo debera estar en un hilo, espero que te sirva


Ivan el 10-10-2007 a las 17:49

Hola

Yo tengo la aplicacion para enviar datos y si los envia perfectamente pero cuando cuando recibo datos los recibo incompletos es decir un ejemplo:

digamos “Hola esto es una prueba” lo que hace es, me los manda por partes:
1 mensaje:”Ho00la”,
2 mensaje:Es0000to e0000s
3 mensaje Un000000a prue0000ba

No se porque a que se deba al tamaño de mi arreglo de bytes o al momento de leer ??


Joste el 10-10-2007 a las 10:31

Supongo que tendras que tener en cuenta los separadores de mensaje y delimitadores de streams…


Ivan el 10-10-2007 a las 20:06

Hola
Bueno mi pregunta es que si en java se pueden manejar interrupciones para enviar y recibir datos atras vez del puerto de comunicacion serial??


Joste el 10-10-2007 a las 9:48

Java no es propiamente un lenguaje de programación de bajo nivel como C… No puede manejar interrupciones de la misma forma.
Lo que si se puede es manejar eventos relacionados, dormir hilos y escuchar cuando se levantan o hacen ciertas cosas… No es trivial.
Mira estos post
http://www.mitecnologico.com/Main/InterrupcionesPuertos
http://www.velocityreviews.com/forums/t151560-interrupt-handling-in-java.html
http://java-x.blogspot.com/2006/11/java-handling-interrupts.html
http://www.itee.uq.edu.au/~testcon/_papers/interrupts-apsec2005.pdf


Ivan el 10-10-2007 a las 0:36

Hola

Bueno mi problema es el siguiente cuando mando un mensaje por el puerto serial lo recibo cortado es decir tengo mu arreglo de bytes de (20).

si escribo hola esto es una prueba me lo presenta de la siguente manera.

Mensaje 1: hola esto e00000
Mensaje 2:suna Prueba000000000000000.

hay veces que hasta me revuelve las letras. yo suponia que era porque no le ponia el flush() pero ya lo puse y aun asi me los manda mal y me manda el espacio vacio del arreglo de bytes no se porque.

Gracias por su atencion.


Ivan el 10-10-2007 a las 17:58

Hola
Bueno antes que nada les comento que ya arregle el problemita de basura en los mensajes. Pero lo que pasa es que me di cuenta que cuando envio a 7 bits el mensaje no le lo da por partes, pero cuando lo pongo a 8 bits me lo da partido, cuando lo pongo a 6 y tengo como mesaje hola me da 0000 en lugar de hola.

Me podrian decir a que se debe.


Joste el 10-10-2007 a las 18:32

Vaya, pues estoy completamente perdido, no se a que se debe. Yo no controlo esto en mi programa…


Kenya el 10-10-2007 a las 21:10

Una pregunta, tengo un listener que me avisa cuando me llegan cosas al puerto serie, leo hago lo que tengo que hacer escribio, y ya, espero a que me llegue de nuevo un dato, todo esta funcionando bien, perooo, despues de muchoo tiempo, lo dejo todo un dia corriendo, y al otro dia, ya no estoy recibiendo bien, un byte lo pierdo, ejemplo siempre recibo STX 0 1 ETX, y despues de mucho tiempo empiezo a recibir STX X 1 ETX, pierdo el segundo caracter, entiendase por X cualquier cosa, y no se si tengo que limpiar el inputStream cada cierto tiempo o cerrar el puerto y volverlo a abrir o que??, sabe alguien si hay un tiempo especifico para limpiar o cerrar un puerto?.

Yo nunca cierro el puerto, porque todo el tiempo estoy esperando que el otro hardware me mande, algo.

Muchas gracias de antemano :)


Kenya el 10-10-2007 a las 21:14

….Continuacion del anterior
Me falto decir que estoy usando esto:

try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
System.out
.println(“******** No se pudo crear el input/output **********”);
System.exit(1);
}

probare hoy haciendo un flush() dspues de que escribo yo, cosa que no tenia y vi aqui, pero veo que el inputStream no tiene flush como para limpiar el stream, asi que no se si deba hacer algo diferente o que?

Estoy cansada de ver que siempre pierde el segundo caracter, y no se por que :(

Gracias de nuevo :)


Joste el 10-10-2007 a las 9:07

Hola Kenya

El flush es una forma no de limpiar sino de forzar la escritura en el buffer de salida. En el de entrada no tiene sentido.
Es raro que pierdas un byte con el tiempo… pero que siga funcionando todo. Eso significa que no te ha cerrado el puerto porque si fuese asi no recibirias nada…
No se que puede ser, no tengo ni idea… a mi lo unico que me pasaba raro era que a veces por motivos de sincronización y de que empezaba a escuchar en un punto en el que el emisor ya estaba emitiendo por bluetooth, el mensaje ya habia comenzado y tenia que desechar datos hasta que comenzase el siguiente, pero no es tu caso…
sinceramente, no se que puede ser, lo siento.


Manuel el 10-10-2007 a las 20:31

Mi problema es que al momento de correr mi aplicación me manda una excepción de que el puerto está en uso y no sé como hacer que funcione mi aplicación. Gracias


Jose el 10-10-2007 a las 17:01

Hola, quisiera pedirte que me ayudes en un proyecto para la facu que estoy haciendo… Es un soft en java (netbeans 6.1) el cual es para un hotel en donde pueda acceder al modem instalado de la pc y al apretar un boton que se llame a un nro telefonico y se reproduzca una grabacion de aviso.
Espero entiendas mi duda, y por cualquier cosa te dejo mi mail para que me agregues. (jose_pareja@msn.com)

Desde ya muchas gracias y espero alguna respuesta tuya.


Pablo el 10-10-2007 a las 13:13

Hola Buenos días.

Quería comentaros un problema por si me podéis ayudar:

He conectado un receptor GPS al puerto serie del ordenador. He hecho un programa en java uqe simplemente lee los datos del puerto serie y los saca por consola (System.out.println). Sin embargo no consigo visualizar bien las tramas NMEA. He probado con:
…..
InputStream entrada;
//entrada está saociado al puerto serie COM1….El proceso de abrir el puerto serie y demás está bien…
….
byte[] bufferLectura = new byte[1024];
try {
while( entrada.available() > 0 ) {
int nBytes = entrada.read( bufferLectura );
}
System.out.print( new String(bufferLectura) );
} catch( IOException e ) {}

….
Per no se visualizan bien las tramas NMEA.

Y también con:

..
DataInputStream flujo_lect = new DataInputStream (entrada);
try {
while( entrada.available() > 0 ) {
//int nBytes = entrada.read( bufferLectura );

System.out.print(flujo_lect.readUTF());}
} catch( IOException e ) {}
….

En este caso se visualizan varias tramas NMEA pero no se ve cómo se van refrescando continuamente.


Joste el 10-10-2007 a las 11:01

Hola Pablo

Hace tiempo que no toco este tema… A ver si puedo ayudar.
En el primer caso el problema no sera el parseo de byte a String?
En el segundo, el formato utf…
Creo recordar que yo hacia una lectura byte a byte y lo pasaba a un Buffered imput stream. Primero, tenía que sincronizar la lectura con el comienzo de un mensaje, porque entre mensaje y mensaje habia información para separar mensajes que me podían hacer un lio. Luego, ya lo iba metiendo en un stream byte a byte.
Puedes poner un trozo mas grande de codigo? así sin mas no veo ningun error gordo…lo vas leyendo y ya esta.
Buscare mi codigo a ver donde lo meti… soy un desastre XD


Fede el 10-10-2007 a las 5:41

estoy tratando de ver los puertos disponibles con el codigo pero al compilarlo la linea

String input = readFromUser();

me da un error. nu puede encontrar el metodo readFromUser(). el rento esta todo bien.
¿Porque pasa esto?


Joste el 10-10-2007 a las 13:21

El metodo readFromUser es un metodo privado que solo lee lo que el usuario escribe desde teclado. No es de java, hay que implementarlo si quieres hacerlo así. Yo lo unico que hice fue leer un numero desde teclado y chequear que es coherente con la lista.
Si quieres puedes poner un numero a pelo si sabes el puerto, y si no lo sabes pues le das a elegir al usuario.


pipinofer el 10-10-2007 a las 0:55

Hola, estoy realizando una aplicación con una comunicacion serial en lenguaje java, dicha aplicación conlleva una conexión con un modem. El problema que estoy teniendo es que no puedo controlar la linea de flujo RTS, es decir, no funciona cuando quiero demodular, solamentre funciona en la modulación.El programa en lenguaje java lo estoy desarrollando con eclipse en plataforma windows.Para poder realizar la aplicación tuve que cargar la API RXTX que es una libreria de comunicacion serie basado en codigo nativo, tuve que usar esta libreria porque para windows es la que funciona, la javaxcomm de microsum funciona para plataforma linux.
La comunicacion que estoy realizando es una comunicacion half duplex, es decir, envio y recibo no simultaneamente, siempre leyendo por el mismo puerto de comunicacion serie.. El problema esta que no puedo hacer funcionar a la linea de control de flujo del moden RTS para que demodule, en la modulacion funciona perfecto, no me cambia el estado de la linea de control cuando quiero demodular, y todo esto lo realizo sobre un mismo puerto en java, no estoy abriendo y cerrando puertos, el puerto se cierra cuando termino de recibir los datos en mi PC.
Si alguien a realizado alguna aplicación que se asemeje les agradecería se pongan en contacto conmigo, tambien si me pueden decir cual puede ser mi problema les estaría agradecido.gracias


pipinofer el 10-10-2007 a las 1:00

ah me olvidaba, la aplicacion es una implementacion de un protocolo de comunicacion industrial hart, la comunicacion es entre la PC y un transmisor inteligente hart, para ver lo que el transmisor envia necesito el moden hart RS232, el envio de la trama hacia el transmisor es correcta, pero el problema esta en que no me llegan los datos del transmisor, no puedo visualizar la trama que em envia el transmisor, ayuda por favor.


pipinofer el 10-10-2007 a las 0:00

aca les dejo el código para que me digan donde puedo tener el error del porque no puedo visualizar los datos de entrada con la demodulación, ayuda gracias

package hart;

import java.io.*;
import java.util.*;

import gnu.io.*;

public class simplewrite implements Runnable, SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream outputStream;
static boolean outputBufferEmptyFlag = false;

static InputStream inputStream;
Thread readThread;

byte[] readBuffer = new byte[40];
int numBytes;

public simplewrite(){

boolean portFound = false;
String defaultPort =”COM1″;

//devuelve un objeto Enumeration, este objeto contiene
// todos los objetos CommportIdentifier, es decir todos
//los identificadores de puertos disponibles en el sistema.

portList = CommPortIdentifier.getPortIdentifiers();

//recorre el objeto Enumeration devolviendo en cada
//iteracion el elemento comportidentifier.

while (portList.hasMoreElements()) {

portId = (CommPortIdentifier) portList.nextElement();

//si encuentra que el tipo de puerto obtenido es igual
// al identificador del puerto serie( constante=1).

if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

//una vez que encuentra si es del mismo tipo se fija
//despues si tiene el nombre correspondiente
//y asigna verdadero al puerto encontrado.

if (portId.getName().equals(defaultPort)) {
System.out.println(“Found port ” + defaultPort);

portFound = true;

try {

//abre el puerto 2000 mseg.

serialPort = (SerialPort) portId.open(“simplewrite”, 2000);

} catch (PortInUseException e) {
System.out.println(“Port in use.”);//captura la excepcion si al querer abrie el
//puerto este mismo esta siendo utilizado

continue;
}

try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {}

serialPort.notifyOnDataAvailable(true);

try {
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_OUT);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
serialPort.setRTS(true);
serialPort.setSerialPortParams(1200,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_ODD);
} catch (UnsupportedCommOperationException e) {}

try {
serialPort.notifyOnOutputEmpty(true);
} catch (Exception e) {
System.out.println(“Error setting event notification”);
System.out.println(e.toString());
System.exit(-1);
}

try {
//devuelve un output stream asociado a ese serialport, dado que
//para cada puerto existe un output stream e imput stream
outputStream = serialPort.getOutputStream();
} catch (IOException e) {}

try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {}

System.out.println(
“Writing frame to”
+serialPort.getName());

readThread = new Thread(this);
readThread.start();

}

if (!portFound) {
System.out.println(“port ” + defaultPort + ” not found.”);
}

}
}
}

public void llamadaserie_escribir(){

serialPort.setRTS(false);

try {
Thread.sleep(100); // Be sure data is xferred before closing
} catch (Exception e) {}

try {
// outputStream.write(armar.tramacompleta,0,ItenElegido.cant_bytes_trama_enviar);
byte[] tramaCorta = new byte[10];
tramaCorta[0]= (byte)255;
tramaCorta[1]= (byte)255;
tramaCorta[2]= (byte)255;
tramaCorta[3]= (byte)255;
tramaCorta[4]= (byte)255;
tramaCorta[5]= (byte)2;
tramaCorta[6]= (byte)128;
tramaCorta[7]= (byte)0;
tramaCorta[8]= (byte)0;
tramaCorta[9]= (byte)130;
outputStream.write(tramaCorta,0,10);
// System.out.println(“salio”);
} catch (IOException e) {}

// try {
// Thread.sleep(20); // Be sure data is xferred before closing
// } catch (Exception e) {}

// serialPort.setRTS(true);

// simpleRead.llamadaserie_leer();
numBytes=0;
// while (numBytes 0)) {
numBytes += inputStream.read(readBuffer,numBytes,1);
// System.out.print(new String(readBuffer));
}
/*
if (numBytes >= ItenElegido.cant_bytes_trama_recibir){

int r=0;
int i=0;
int c=0;
int t=255;
while (r!=5){
while (readBuffer[i]==(byte)t){
r++;
i++;
}
if((readBuffer[i]!=(byte)t)&&(r==5)){
armartrama.inicio=readBuffer[i];
i++;
for ( int y=0; y


Joste el 10-10-2007 a las 9:38

Dame unos días, no puedo atenderte ahora. El fin de semana lo miro.

Un saludo


Alvaro Michea el 10-10-2007 a las 21:06

Hola a todos!!!

Necesito controlar el lpt a traves de jsp, solo encender y apagar un par de leds… podria alguien ayudarme?

de antemano muchas gracias…


Ime el 10-10-2007 a las 8:40

Hola tengo conectado un GPS al puerto serie y con un simple programa leo las tramas que me envia, el problema e que me manda las tramas sin algunos datos, por ejemplo tengo $GPRMC,062159.216,A,1927.4896,N,09907.1987,W,0.00,307.15,160309,,,A*73

esto como trama enviada, que observo por medio de un listener del puerto y cuando lo veo en mi programa solo me aparece $ 00,160309,,,N*73 .
Les dejo el tramo del codigo donde hace esa parte. les agradeceria mucho su ayuda.

byte[] readBuffer = new byte[20];

try {
int numBytes=0;
while (inputStream.available() > 0)
{
numBytes = inputStream.read(readBuffer);
}
String result=new String(readBuffer);
System.out.print(result);

un saludo y muchas gracias


Joste el 10-10-2007 a las 8:38

Ime, eso tendrás que mirarlo en las instrucciones del GPS que significa y cotejarlo con el standar de comunicación GPS. No me acuerdo pero vacio supongo que significara que no hay info relevante. Si no hay, no hay, que le vamos a hacer pero el resto ya lo tienes.
Alvaro, un Jsp es analogo a java, no entiendo la dificultad de hacerlo mediante jsp si sabes hacerlo mediante java.
Pipinofer, tienes abierto el puerto en forma lectura y también en forma escritura? tienes que abrir ambas direcciones por separado por puertos diferentes, y los puertos que abras tienen que coincidir con los configurados en tu pc. Si el puerto de entrada es el COMM18 tienes que seleccionar ese en el software como puerto de entrada y lo mismo con el de salida, si es el 19, pues el 19.


Juan Ortega el 10-10-2007 a las 15:54

Hola a todos tengo un Modem AT EMII-800 y necesito crear una aplicacion Java para comunicarme con este y controlar ciertos operaciones del mismo, lo que epan por favor comuniquenmelo


juan Manuel el 10-10-2007 a las 9:21

Hola, les quisiera hacer una consulta. Yo tambien uso esta libreria pero recientemente me encontre que no me detecta los puertos disponibles trabajando bajo Windows 7. Alguien tiene experiencia en esto? Saludos.


[...] – estoy recibiendo datos de un gps con java. Esta consulta me ha hecho especialmente gracia, ya que lo primero que he pensado al verla es: “joder, eso hay que celebrarlo, porque suena a chungo que te cagas!!!”. También se me ha pasado por la cabeza: “cuidado, comprueba que el gps sea tuyo y no de un espía”. Pero volviendo a la realidad, con esta búsqueda aparecemos en segunda posición con uno de los artículos más exitosos de la isla: Librería de comunicaciones java RXTXcomm.jar. [...]


javito el 10-10-2007 a las 21:35

Hola gente, queria preguntarles si alguien sabe como conectar un modem 3G desde java. En realidad el sistema debería validar que exista una posible conexión wifi,y conectar. Y si no, conectar el modem 3G. Actualmente eso lo estamos haciendo a mano, pero debería ser automatico. Con lo que he visto acá, pude ver los puertos pero no sé si necesitaré llamar a alguna dll?.. bueno no sé.. está bastante verde esto todavía… ayuda!


Joste el 10-10-2007 a las 7:26

Hola javito

Pues así a bote pronto… ni idea. Lo malo de conectarlo a mano es que no se si luego tendrás que tener todo a mano, o inicializar algo mas para decirle al modem que ya puede “empezar” a trabajar…

Prueba a seguir los pasos de este minituto, donde en vez de conectarte a los puertos com o LPT tendrás que localizar cual es el wifi mediante el identificador correspondiente y tras ello abrir la conexión…

El problema como te comento, será luego ver como gestionas la conexión porque en el caso del GPS abrias la conexión y luego tenías que pedirle tu info, interpretar lo que te devolvia etc.


luis orihuela el 10-10-2007 a las 5:45

Hola amigos!, necesito me echen una mano por favor, me compré una impresora Bematech mp-100 para emitir las facturas en tickets por medio de un sistema que estoy realizando en JAVA, pero no tengo ideaa de como enviar por código y decirle a la impresora que me lo corte al finalizar la impresión, y tb para que luego me abra automaticamente la Gabeta de Dinero….
Si me podrían ayudar con esto por favoor!! Ciertamente ya demaaz estuve investigando y nada, creo que tengo que manejar algunos comandos de la impresora, tengo los comandos (en el manual), sinceramente ya no se que hacer, ya probé de todo, y no me sale nadaaa.. y este sábado tengo que entregar el sistema, (es viernes), hace una semana que estoy con esto y nada….. hummmmmmmmmm… Probe trabajar directamente con el puerto serial con RXTXCOMM.JAR pero te salta este error:

[b]gnu.io.PortInUseException: Unknown Application[/b]

seguí exactamente los pasos de la guia de instalación para windows (seven) y nada………

Mil gracias de antemano. Desde paraguay.
Luis Orihuela
————————————–


Joste el 10-10-2007 a las 10:05

Hombre… parece que el puerto lo están utilizando… puede que tengas el controlador ejecutandose por otro lado, o un software propio…

Si quieres controlar tu el puerto, tendrás que parar los servicios que estén activos y ocupando primero el puerto.


luis orihuela el 10-10-2007 a las 12:20

Hola Joste, gracias por tomarse el tiempo de resoponder, muchas gracias, esa contestación fue para mi cierto?? (es que me cuesta creer que en 800 foros que posteé me hayan respondido unoo! T-T jeje)..
Ahmm, y si, yo instalé un controlador a la impresora, entonces eso me lo está impidiendo el acceso??, lo voy a probar amigooo!!, y luego traigo los resultados ;) . Muchas gracias una vez más..


Joste el 10-10-2007 a las 12:22

Si claro que era para ti.

La verdad que este post es de hace ya…. mucho tiempo y no tengo el tema fresco, ya se me ha medio olvidado, pero por lo que cuentas (hay poca información en tu cometnario) parece que el peurto está ocupado.

Así que o bien fuerzas (no se como) mediante java a liberar el puerto, o intentas que el puerto esté libre antes de que tu programa se ejecute…

Esperaremos los resultados con impaciencia!

Un saludo


luis orihuela el 10-10-2007 a las 13:14

Permíteme decirle que usted es un CAPOO!! (Joste) :D (Que es muy bueno xD)Efectívamente, desinstalé el controlador de la impresora (impresora tícket), ya no me salta ese error!! Pero bueno, ya ahora el problema soy yo… :S, por que no sé como enviar comandos propios de la impresora a ella, para cortar automáticamente el tícket y abrir la gabeta de dinero.. :( . Los comandos que me dá el manual son “ESC p m t1 t2″ y “GS V m” para abrir la gabeta y cortar el papel respectivamente, los enviaba antes con write(“GS V m”) por ejemplo pero me imprimía en el ticket en vez de ejecutar el comando y cortar el papel.. hummmm, será que podría prestarme una ayudita una vez más?
Millón gracias… :$


Joste el 10-10-2007 a las 14:42

Lo siento Luis,

La verdad no se como funcionaría la impresora… la teoría es que al estar el buffe abierto se puede enviar información.

Esta información debe de ser un stream de bytes, no un string a secas, eso si. Pero no se decirte nada sobre las intrucciones de la impresora ya que eso es algo muy particular y no se como lo estás implementando. Además, tal como indicaba… ya lo tengo todo un poco olvidado.

Solo unos consejos genéricos:
- Cuidado no confundir los bufferes de entrada y salida
- No envies objetos java, transformalos a byte[] para enviar la información.
- leete el código de los comentarios. Parece que hay gente que ha tenido problemas pero no han vuelto por el blog, asi que entiendo que se les ha podido ayudar en su dia… mirate los cometnarios a ver si te da pistas.


luis orihuela el 10-10-2007 a las 16:08

Joste!
Una consulta compañero, como sería el método readFromUser(); ?

del primer código de ejemplo que se dió aqui??

Muchas gracias!!


Joste el 10-10-2007 a las 16:42

Hola otra vez Luis,

El método readFromUser() solo lee lo que el usuario escribe en el teclado, no recuerdo el código pero puedes ver un ejemplo aquí. Sería algo parecido.

http://www.roseindia.net/java/java-get-example/java-get-user-input.shtml

Un saludo


luis orihuela el 10-10-2007 a las 17:24

Entiendo.. De igual manera muchas gracias Joste, por su tiempo, seguiré investigando, probando, divagando D: jaja xD. Y cuando tenga una solución, vuelvo para comentar y que les sirva a otros también.

Mil gracias una vez más..
Luis Orihuela – PY
—————————————–


luis orihuela el 10-10-2007 a las 17:27

(#Queríadecirnomás que estaba “esperando” que usted me responda (que me llegue la notificación al correo), como nunca me llegó, pensé que ya se había ido xD)por eso respondo recién! okok, escudriño el código ahora..
Por enésima vez gracias……


luis orihuela el 10-10-2007 a las 21:13

Colega Joste!,

Creo que estoy a puuunto de descubrir como hacerlo jeje, tengo que enviar los comandos que me dan en el manual para cortar el ticket y abrir la gabeta (‘GS V m’ Y ‘ESC p m t1 t2′ respectivamente) en hexadecimal a impresora, osea “escribir” en ella, según he averiguado, este es mi código y no me imprime……………. No se que estoy haciendo mal? :s

public void cortarTicket(String puerto) {
// Corte de ticket
try{

fw = new FileWriter(puerto);
bw = new BufferedWriter (fw);
pw = new PrintWriter (bw);

}catch(Exception e){
System.out.print(e);
}

try {

pw.println(“HOLA MUNDO!!!”);
char[] ESC_CUT_PAPER = new char[]{0x1B,’m'};
pw.write(ESC_CUT_PAPER);
fw.close();

} catch (Exception e) {
JOptionPane.showMessageDialog(null,e.getMessage(),”Atención”,JOptionPane.INFORMATION_MESSAGE);
}
}

Gracias!!


Joste el 10-10-2007 a las 12:04

Yo intentaria escribir lo que quisieses y luego convertirlo a hexadecimal utilizando el método getBytes() del objeto String.

De todas formas creo que no te puedo ayudar mucho mas ya que estoy hablando de memoria…

La cuestión es que no se si es lo mismo escribir la instrucción como un string y luego hacer un getBytes o escribir el array hexadecimal.

Tal como te ponía también en los comentarios anteriores yo cogería el string “ESC p m t1 t2″ y lo pasaria a un array de bytes (no me expliqué bien la vez anterior)

write((new String(“ESC p m t1 t2″)).getBytes());

mirate los comentarios de Jaume, tuvo un problema al respecto.


luis orihuela el 10-10-2007 a las 18:49

Ahh, lo voy a probar!! Pero también el problema es que no me imprime luego :s, “pw.println(“HOLA MUNDO!!!”);” esto no me imprimee! D:, no se que estoy haciendo mal, utilizo tb otra forma de impresion con DocPrintJob, con ese metodo si me imprime las cosas en el ticket, pero cuando utilizo este metodo que puse más arriba no pasa nada…… No se si no estoy instanciando correctamente los objetos o que pasa….. Por que con pw.println(“Hola Mundo”); supuestamente tiene que imprimirme en la impre cierto?, pw.write(ESC_CUT_PAPER); yo le envio el comando, no se cual es la diferencia en estos, pero esí como encontré xD..

Miro los comentarios de Jaume..


Joste el 10-10-2007 a las 19:30

Cuando haces un pw.println(“Hola mundo”) estás escribiendo eso en el output stream. Entiendo que ese output estará orientado al puerto donde está la impresora.

Pero un println a un puerto no se va a traducir en una impresión en la impresora… cuando mandas un string a la impresora le tendrás que enviar instrucciones a la impresora, como los comandos. Si el puerto recibe la instrucción “Hola Mundo” no sabe si es un comando o un parametro o qué es. Ahí es donde tiene que entrar en juego la api para envira la info. Tendrás que decirle mediante la api de la impresora que vas a enviarle información para imprimir, luego enviar el “hola mundo” con sus saltos de pagina, cortes o lo qu epermita la impresora y por fin, cerrarlo todo.

Entiendo que ahora lo que te pasa es que el puerto de la impresora recibe unos bytes que son la codificación del “Hola mundo” pero no sabe que significa, no sabe que tiene que imprimirlo.


Carlos Yánez el 10-10-2007 a las 23:13

Saludos Joste,
Estoy haciendo una aplicación en java para leer datos de una cédula inteligente y me comunico por medio de puerto serial.

Son 17 comandos para leer la información pero no consigo realizar el envio y la recepcion de cada comando que se envia y que me retorna.

Pr favor me podrias ayudar en este dilema.


Joste el 10-10-2007 a las 9:57

Das poca información, dificil dilema.

Como a los anteriores, te recomiendo que compruebes que los puertos están libres antes de utilizarlos, a ver si por defecto va a estar ocupado por alguna aplicación que se conecta automáticamente al enchufar el dispositivo.

Por lo demás, no se como puedo ayudarte…


Efrain el 10-10-2007 a las 21:42

hola, buen dia.
bueno te escribo por q necesito hacer una interfaz para un brazo robot, estoy utilizando un arduino y pues necesito aprender a utilizar esta libreria, pero soy completamente nuevo en java, solo me gustaria ver si me puedes dar un ejemplo de un intercambio de datos [pulsar un boton en un entorno grafico y enviar informacionde maximo 8 bits al puerto(estos bits serian solo binarios, nada de caracteres), y q lea de puerto otros 4 bits de respuesta]… espero darme a entender, gracias


Envía un Comentario
Nombre:
Email:
Web:
Comentario: