Manejo del puerto serial (RS232) con Java
Buen día a todos!!
Acá les traigo un nuevo post, y seguro les interesará..
Se trata de utilizar el puerto serial con Java.
Se trata de un proceso muy pero muy sencillo, construí una clase para hacer este trabajo y voy a explicar el código.
En primer lugar, estoy utilizando el JDK 1.6, con netbeans 6.8.
Bueno, a trabajar.
Para poder hacer esto utilize las librerias para puerto serial GyovinetDriver, que viene siendo un Wrapper para usar el puerto serial tanto en Windows como en Linux.
Bueno, dicho esto, al codigo.
La clase se llama PuertoObj, y vamos con las declaraciones.
Objeto que hace referencia directa al puerto com.
Este objeto es el que enviara los comandos y recibirá las respuestas en el puerto
Com puerto;
Para configurar el puerto com, necesitamos establecer los parámetros de la conexión
en un objeto Parameters.
private Parameters parametros;
La variable formatoCadena y subCadena, reciben string indicando cual es el formato de la cadena recibida por el puerto después de enviar un comando y que parte de la cadena necesitamos regresar con el método LeerDatos de esta clase
Por ejemplo, si el formato que recibiremos por el puerto es SNNNNNNNSKGC puede
que solo nos interese recibir la parte SNNNNNNN que es la que representa el peso(si hablamos de una bascula) Mas adelante están los getters y setters para estas 2 variables.
private String formatoCadena; private String subCadena;
Esta variable se usa junto con las 2 variables anteriores. En el método LeerDatos
de esta clase, verán de forma mas detallada como funciona.
private int caracterIniciaLectura;
Esta variable toma un valor dependiendo de si queremos regresar todo lo recibimos del puerto o solo la parte que nos interesa. Esto si están configuradas las variables formatoCAdena y subCadena.
private boolean bRegresaCadenaCompleta = false;
Vamos con el codigo en si
Primero un constructor sin parámetros, que lo que hace es inicializar el objeto Parameters
Public PuertoObj() throws Exception { parametros = new Parameters(); }
Para poder usar esta clase, debemos pasar toda la información de conexión a ella, para eso utilizamos un método llamado ConfiguraPuerto, que recibie algunos parámetros.
Aquí esta el codigo.
public void ConfiguraPuerto(String nombrePuerto, String baudios, String paridad, String bitsPorCaracter, String bitsDeParada) throws Exception{</strong> parametros.setPort(nombrePuerto); parametros.setBaudRate(Baud.valueOf(baudios)); parametros.setParity(paridad); parametros.setByteSize(bitsPorCaracter); parametros.setStopBits(bitsDeParada); }
Como pueden ver, este metodo recibe el puerto a utilizar, los baudios, la paridad, etc.
Estos datos son pasados al objeto Parameters que fue inicializado en el constructor de esta clase.
Una vez configurado el puerto, podemos abrirlo, para esto usamos el siguiente metodo.
public void AbrirPuerto() throws Exception { //Determinal el caracter final de la lectura caracterIniciaLectura = 0; if(formatoCadena!=null){ if(subCadena==null) subCadena = formatoCadena;</strong> caracterIniciaLectura = formatoCadena.indexOf(subCadena); }else{ formatoCadena = ""; bRegresaCadenaCompleta = true; } try { if (getFormatoCadena().length()>0){ //puerto = formatoCadena.length(); } puerto = new Com(parametros); } catch (Exception ex) { throw ex; } }
Este metodo configura a este objeto para que tenga en cuenta la cadena que va a regresar con el metodo LeerDatos, presten especial atención a la linea
puerto = new Com(parametros);
Esta linea es la que realmente abre el puerto, es decir crea una instancia de la clase Com y en el constructor pasa los parámetros que definimos con el método ConfiguraPuerto.
Llegando a este punto en nuestro programa, si todo sale bien, estamos en posición de mandar comandos a nuestro dispositivo, vamos a definir el método que nos ayudara en esta tarea.
public void EscribirDatos(String comando) throws Exception { try { puerto.sendArrayChar(comando.toCharArray()); } catch (Exception ex) { //throw ex; } }
El objeto puerto, tiene algunas variantes para enviar caracteres al puerto, después de estar probando algunas el método sendArrayChar() es el que me funciono para lo que yo estaba haciendo (Que es conectar con una bascula). Uds pueden probar otros métodos, ya nos contaran qué fue lo que les funcionó.
Volviendo, el método anterior es muy sencillo, solo se le dice que escriba el comando en forma de arreglo de caracteres en el puerto. Cuidado con las excepciones, se debe atrapar o reportar las que se generen.
Ya escrito el comando en el puerto, vamos a leer la respuesta. Esta es otra cosa sencilla, acá va el método que sirve para esta tarea.
public String LeerDatos() { String dato = ""; try { String dt = puerto.receiveToString(formatoCadena.length());</strong> //System.out.println("La salida es: "+dt.length()); if (dt == null || dt.trim().compareTo("")==0) { return "No hay datos"; } if (!bRegresaCadenaCompleta) { dato = dt.substring(caracterIniciaLectura, subCadena.length()); } else { dato = dt; } } catch (Exception ex) { Logger.getLogger(PuertoObj.class.getName()).log(Level.SEVERE, null, ex); } return dato; }
La linea mas importante es:
String dt = puerto.receiveToString(formatoCadena.length());
Observen como le he pasado como parámetro la longitud de la palabra que espero recibir por el puerto. Una vez recibida la palabra, es tratada para devolver solo la parte que le interesa al usuario, ¿recuerdan el uso de las variables formatoCadena, y subCadena? Pues aquí es donde se utilizan.
Para finalizar el ciclo, se debe cerrar el puerto. Aquí esta el metodo.
public void CerrarPuerto()throws Exception{ try { puerto.close(); } catch (Exception ex) { //Logger.getLogger(PuertoObj.class.getName()).log(Level.SEVERE, null, ex); throw ex; } }
Para terminar con el código de nuestra clase, vienen los getter y setters de formatoCadena y subCadena
public String getFormatoCadena() { return formatoCadena; } public void setFormatoCadena(String formatoCadena) { this.formatoCadena = formatoCadena; } public String getSubCadena() { return subCadena; } public void setSubCadena(String subCadena) { this.subCadena = subCadena; }
Hasta aquí, tenemos nuestra clase terminada.
Sencillo no??
Para lograr que el programa funcione hay que tomar en cuenta algunos detalles.
Primero, descargar el driver para manejo del puerto serial desde java del siguiente link
http://code.google.com/p/giovynetserialport/downloads/list
Al decargar el archivos vienen una serie de carpetas, los archivos importantes son GyovinetDriver.jar y libSerialPort.dll para trabajar con windows.
Segundo, el archivo libSerialPort.dll se debe copiar a la ruta de las librerias donde esta instalado el JDK. En mi caso es C:\Archivos de programa\Java\jdk1.6.0_18\jre\lib.
Y Tercero, se debe agregar la librería GiovinetDriver.jar a nuestro proyecto.
Ahora si, ya tenemos todo listo.. para usar nuestra clase vamos a hacer lo siguiente.:
Incluir el import de nuestra clase; en mi caso queda así:
import Util.PuertoObj; public static void main(String[] args) { PuertoObj puerto = new PuertoObj(); puerto.ConfiguraPuerto(“COM1”,”_9600”,”E”,”8”,”1”); puerto.setFormatoCadena(“SNNNNNNNSKGC”); puerto.setSubCadena(“SNNNNNNN”); puerto.AbrirPuerto(); //En mi bascula, el comando P indica que me envíe el peso actual puerto.EscribirDatos(“P”); //Leemos lo recibido System.out.println(“El dato recibido es: ”+puerto.LeerDatos()); //Y cerramos el puerto puerto.close(); }
El código del método anterior lo escribí al vuelo, si usas Netbeans o cualquier otro IDE, seguro te va a indicar que debes manejar las excepciones. Ajusta el código para que funcione.
En la linea:
puerto.ConfiguraPuerto(“COM1”,”_9600”,”E”,”8”,”1”);
observa que el segundo parámetro lo mande así «_9600», eso es porque la clase Baud sabe interpretar los baudios expresados de esa manera(Lo puedes ver en el método ConfiguraPuerto de nuestra clase PuertoObj).
Como ven, manejar el puerto serial desde un programa hecho en Java es muy sencillo, utilizando la librería GyovinetDriver.
Se me olvidaba!!
En nuestra clase PuertoObj, hay un metodo estatico que nos devuelve una lista de tipo String con los puertos seriales instalados en nuestro PC, aqui va el codigo de este metodo.
public static List getPuertosLibres()throws Exception{ List puertosLibres = null;</strong> try{ SerialPort sp = new SerialPort(); puertosLibres = sp.getFreeSerialPort(); }catch(Exception ex){ throw ex; } return puertosLibres; }
Tengo un proyecto de ejemplo funcional, puedes ver más detalles aquí.
Bueno, esto es todo por hoy, espero que este post les sirva de algo y no olviden dejar sus comentarios.
Hasta la proxima.
Excelente aporte mi hermano, de verdad me sirvio de gran ayuda 🙂
Albert, revise la lista de errores que me enviaste. Ese error se produce porque no encuentra la libreria libSerialPort.dll. Copiala a la ruta de las librerias de JDK en mi caso es C:\Archivos de programa\Java\jdk1.6.0_18\jre\lib; y a system32. Con eso tu proyecto debe funcionar.
buenas compañero necesito mandar y revisar informacion atraves del RS232 pero tengo netbeans 7.0.1 ylo necesito interactuar entre dos computadores mi pregunta es si tu ejemplo tambien puede servir en mi proyecto gracias
Buenas tardes damarin.
Si tu netbeans puede trabajar con el JDK 1.6 de Java, entonces el ejemplo si te serviria.
Revisa que JDK tienes y me avisas.
Saludos.
De donde se puede bajar la libreria GyovinetDriver?
buenas dias arvinform estuve la libreria y no he podido hacer la comunicacion con el otro pc mi Netbeans trabaja con e JDK 1.7.0 o nose si descarge la libreria corresta para poder trabajar en windows
gracias
Buenos días,
Estupendo ejemplo. Me funciona bien. Pero me gustaría hacer una pregunta.
Estoy enviando una cadena hexadecimal caracter a caracter con el siguiente código :
data = hexStringToByteArray(«00ffff000b000102030405060708090a0b0c0d0e0f1»);
for (int i = 0; i < data.length; i++) {
com.sendSingleData(data[i]);
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
¿Como puedo hacer para enviar en una sola instrucció toda la cadena hexadecimal ?
Estoy monitorizando el puerto serie para ver lo que envío y el log me sale demasiado grande cuando envío caracter a caracter.
Gracias
Que tal Alejandro, me alegra que el ejemplo te sirva.
Para tratar de entender mejor tu problema, ¿porque tienes la cadena en caracteres hexadecimales???
Lo que veo en el codigo que muestras, es que tu conviertes la cadena Hexadecimal(00ffff000b000102030405060708090a0b0c0d0e0f1)
a un arreglo de bytes, y en el siguiente codigo
for (int i = 0; i < data.length; i++) {
com.sendSingleData(data[i]);
envias el valor de la posicion actual del arreglo de bytes, donde esa posicion es un valor numerico.
Posiblemente lo que necesites, es convertir cada posicion del arreglo de bytes a un valor char, para asi tener un arreglo de chars.
Una posible solucion seria:
byte[] data = hexStringToByteArray(“00ffff000b000102030405060708090a0b0c0d0e0f1″);
String str = new String(data);
com.sendArrayChar(str.toCharArray())
¿Que se hizo con el codigo anterior?,
primero se convierte la cadena de caracteres hexadecimales a un arreglo de bytes,
luego ese arreglo de bytes se utilizo para inicializar un objeto de tipo String,
y se utiliza el metodo toCharArray() del objeto de tipo string, que nos devuelve un arreglo de char para enviarlo al puerto
de un solo golpe con la invocacion del metodo sendArrayChar.
Espero que esto pueda ayudarte.
Saludos y éxitos.
nesecito cominicar modulos zigbee por puerto serial, esta libreria me sirve?, y no puedo descargar la libreria, el link no me funciona!!!!!!!!!!!!!!
Buen dia Carlos, no estoy seguro si la libreria te funcione para tu requerimiento. De cualquier forma te mando la libreria a tu correo, para que la revises y nos cuentes si te funciona. Saludos.
Mi correo es erick_arroyo@outlook.com, podrias enviarme tu proyecto, estoy tratando de comunicar java con un picaxe.
Claro erick, te envio el proyecto de ejemplo a tu correo..
Espero te sea de utilidad.
Me los puedes dar ami tambien pro favor es que lo necesito
Hola pudieras mandarmelo ami también por favor? Mi correo es yona_rca6@hotmail.com
Hola, esta muy interesante tu post, pero de java no se nada, solo javascript, y la verdad estoy vuelto loco, por que estoy tratando desesperadamente de lograr que un sistema de venta a traves de un navegador web, con php y javascript, me abra una caja registradora, leí un poco que con un activex se puede, pero no se como se hace, lo de la miniprinter ya lo solucioné ya que se instala como una impresora normal, y en el firefox viene la opcion de imprimir directamente sin abrir la ventana, pero lo que quiero es que se abra automaticamente la caja registradora al capturarse un cobron en la base de datos. Crees que puedas ayudarme con eso, según yo, solo con enviar una señal electrica se puede abrir la caja, pero no se, no tengo mucha idea sobre eso, mi correo es zharazan1@hotmail.com, muchas gracias de antemano, tu post me hizo pensar mas claramente, que si puede ser posible
buenas tardes tengo q comunicar un zigbee casero conectado con un ordenador bien sea por el puerto rs2323 o el usb…funcionara tu ejemplo con el rs232?me peudes enviar la libreria?gracias
Saludos, quisiera recibir su proyecto de ejemplo. Estoy tratando de hacer conexión entre el PIC 18F4550 y la PC por puerto serial. Mi correo es oskrleonardoq@hotmail.com. Muchas gracias.
Hola me gustaria recibir el proyecto en mi correo, te lo agradecira muchísimo, la dir es juanqui6120@gmail.com. Gracias y éxitos a todos.
Hola. Se me esta generando una excepción: The Com:COM18 is already instantiated
Tienes alguna idea ?
Honestamente no he tenido esa excepcion…
Pero por el tipo, me imagino que otra aplicacion está usando el puerto COM18 o que de alguna manera se queda colgada una instancia de la clase PuertoObj que previamente está usando el puerto.
Revisa si tienes otras aplicacion que utilicen ese puerto, y si es así, asegúrate que no esté en memoria.
Saludos.
Algun link para descargar la libreria ya que esta roto y el comprimido que encontre me pide contraseña
El link que conozco es el que está en el blog, y tienes razón, está roto.
Te mando la librería a tu correo.
Muy bueno el aporte! Necesito hacer una aplicación de este estilo. Puedes mandarme el comprimido ya que el link esta roto?
Buen día.. Te envíe el comprimido a tu correo.
Espero te sea de utilidad.
Saludos.
Muchas gracias por el post, me resultó de mucha ayuda!!!
hola amigo! muy buen trabajo, me pregunto si podrías enviarme a mi correo tu aplicación funcional y la libreria? saludos.
Buenas se ve muy bueno tu ejemplo, podrias enviarmelo a mi correo por favor.
Hola, no logro respuesta por parte del dispositivo serial, es un Termómetro digital FLUKE, el cual viene con su propia interfaz solo que es muy limitada por ello requiero comunicarme con él.
Donde creo que puede estar mi error es en las siguientes lineas:
en la línea 1 la letra N la envió ya que no maneja paridad según el manual.
La línea 2 y 3 entiendo que únicamente es para extraer la cadena que necesitamos, mi duda es el porque de las letras?
En la línea 5 envió la orden del mismo modo que con el programa de interfaz que viente con el instrumento.
1 puerto.ConfiguraPuerto(«COM1», «_9600», «N», «8», «1»);
2 puerto.setFormatoCadena(«SNNNNNNNSKGC»);
3 puerto.setSubCadena(«SNNNNNNN»);
4 puerto.AbrirPuerto();
5 puerto.EscribirDatos(«READ?»);
No se que tan probable sea que no obtengo respuesta debido a la forma de insertar la petición
puerto.sendArrayChar(comando.toCharArray());
Ya que realizando el Debug, al enviar la información no veo el campo que lleve el comando de petición, así como al devolver la información, el objeto Comm puerto, se encuentra vació.
Espero me ayudes a orientarme un poco más.
De antemano gracias.
Hola Israel..
En la clase PuertoObj tenemos una instancia de la clase Com llamada puerto.
Este objeto llamado ‘puerto’ tiene diferentes métodos para enviar los comandos hacia el dispositivo.
Según lo que me dices, el comando lo mandas usando el método sendArrayChar. Revisa qué otros métodos tiene éste objeto e intenta.
Otra cosa, seguido me ha pasado que el problema al no devolverme datos pueden ser los parámetros de conexión. Revisa en el manual del termómetro
si los datos qeu envias son correctos. Es decir, bits de parada, bits por caracter, paridad, etc.
Las líneas 2 y 3 efectivamente son para extraer los datos que necesites. Debes revisar el formato de la cadena de respuesta que te devuelve el dispositivo,
hacer un patrón genérico, y setearlo con el método setformatoCadena. y definir el patrón de la cadena que necesitas manejar.
Para hacer las cosas más fáciles utiliza un software para conexión al puerto serial. Si usas windows, puedes usar HyperTerminal. Establece la conexión y envía comandos, Una vez que a través del HyperTerminal tengas datos del dispositivo, entonces no hay razón para que no tengas datos a través de la aplicación.
Otra cosa que me ha pasado, es que por error selecciono un puerto virtual del pc y realmente no hace nada. Pasa como si hiciera la conexión pero no hay respuesta.
Una más, si usas un adaptador de puerto serial, es decir, de usb a serial, a menudo este tipo de cables dan problemas. No sé si es tu caso, pero por las dudas te dejo el comentario.
Espero que esto te dé una idea y puedas solucionar el problema. Si no es así, envíame parte del código para ver en qué puedo ayudarte.
Saludos.
Hola muchas gracias por los comentarios, me sirvieron de mucho. Probé el Hyper terminal y todo funciono bien, por lo que me enfoque en verificar mi programación en Java y por fin dí con el clavo, En la cadena de petición hacia falta enviarle un «\n»(Enter) para que el instrumento procesara la petición.
Por otro lado creo que hay un pequeño detalle en el método LeerDatos() en la línea 5
05 String dt = puerto.receiveToString(formatoCadena.length());
En mi caso no estaba utilizando ningún formato y se lo enviaba como null, por lo que no me devolvía ninguna respuesta, ya que la cadena estaba vacía. Solo es cuestión de validación.
Saludos y Gracias.
Hola Israel..
Me alegra que hayas podido resolver tu problema.
Voy a revisar tu sugerencia, y aplicar los cambios.
Saludos y éxitos.
Hola, me encanto tu ejemplo, yo estoy buscando hacer algo similar pero con puerto usb… crees q se pueda adaptar a tu ejemplo? y podrás enviarme tu ejemplo a mi correo? gra.rochio@gmail.com
Soy nueva en java y llevo tiempo lidiando con este problema 😦
Saludos!
Hola Rocío…
Me dá gusto que te haya gustado el ejemplo…
La vdd aunque por definición el puerto USB es un puerto serial, no creo que este ejemplo puedas adaptarlo.
Debe haber otras formas en Java.
De cualquier forma te lo envio y nos cuentas.
saludos.
Muy bueno tu ejemplo..y muy bien explicado! Podrias enviarme el codigo fuente?
Saludos cordiales,
Atte. R.R
Claro..te lo envio..
Saludos.
men puedes explicarme un poco mas a fondo esta linea:
puerto.ConfiguraPuerto(“COM1”,”_9600”,”E”,”8”,”1”);
comprendo hasta el segundo parametro pero los ultimos 3 no comprendo
te lo agradeceria mucho.
o alguien que me pueda explicar
Buenas tardes..
La conexión por puerto serial require una configuración dependiendo del dispositivo que quieras conectar.
Para establecer una conexión a través del puerto serial, es necesario indicar el puerto, los baudios(velocidad de transferencia), paridad, bits de datos y bis de parada.
Te dejo el siguiente link donde se explica a detalle cada uno de estos elementos.
http://digital.ni.com/public.nsf/allkb/039001258CEF8FB686256E0F005888D1
Espero esto te ayude.
Saludos.
Hola, gracias por el apoyo. Como agradecimiento te adjunto mi proyecto:
http://www.4shared.com/rar/7pXvyUJ0/RS232_-_Balanza.html
Saludos!
hola estimado
Me parece muy interesante tu aporte, estoy tratando de replicar el codigo peor obtengo el siguiente mensaje de error:
Exception in thread «main» java.lang.UnsatisfiedLinkError: C:\Users\olchese\workspaceNB\procReadSerialPorta\libSerialPort.dll: Can’t load AMD 64-bit .dll on a IA 32-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1030)
at core.SerialPort.(SerialPort.java:18)
at com.datbusiness.serialport.main.Principal2.main(Principal2.java:17)
Java Result: 1
Favor si me pudieras ayudar a que se debe esto te lo agradeceria de antemano
Buen día Aldo.
Tú problema aparece porque falta que copies el archivo libSerialPort.dll a la carpeta donde tienes instalada la máquina virtual de Java.
En el blog, está comentada esta parte. y por si las dudas, puedes copiarla también a la carpeta System32.
Con esto debería funcionar.
Saludos.
Hola, está muy interesante tu programa, podrías porfavor enviarme el código fuente? mi correo es jhrm92@hotmail.com. Gracias
Buenas compañero, estoy revisando tu ejemplo pero tengo ciertas dudas, sera que puedes mandarme algun ejemplo completo para poder guiarme? Estoy usando eclipse. Mi correo es crsa1899@gmail.com gracias de ante mano. Saludos.
Buenas Carlos.
Si, envío el código de ejemplo a tu correo.
Saludos.
Saludos Rene, estoy iniciandome en la programacion de JAVA y estoy tratando de implementar un programa que visualice el peso de una bascula, he estudiado tu codificacion y me ha ayudado bastante. Lo que he notado es que trabajas la lectura por demanda es decir envias un caracter a la balanza para que esta a su vez envie la informacion en una sola linea. Yo estoy tratando de trabajar el equipo en modo continuo, es decir que la balanza esta enviando en forma constante informacion al PC sin necesidad de que este le envie comandos de impresion, ¿Que quiero lograr con esto? Quiero que mi aplicacion muestre el peso reflejado de la balanza como si fuera un display remoto. No he encontrado mucha informacion que me ayude, por eso te pido un poco de ayuda en esta aplicacion. Ademas si fueras tan amable me pudieras enviar el programa que comentas… ? Gracias de antemano por la atencion prestada.
Saludos Marco.
He trabajado con básculas que trabajan en modo continuo, en ese caso, lo único que tengo hacer es iniciar un temporizador y leer los datos del búffer cada cierto tiempo, sin necesidad de enviar un comando para lectura.
Envío el código de ejemplo a tu correo, para que puedas adaptarlo.
Saludos.
Super, gracias por la ayuda, voy a revisar lo que me enviaste y despues te comento cualquier novedad de como me fue en el proyecto
Gracias nuevamente…
Hola, mi proyecto consiste en detectar humo con un sensor, enviar los datos por el puerto rs232 utilizando un cable adaptador usb-rs232, si se detecta presencia de humo se debe encender una alarma, la señal para encender la alarma también se envía por el puerto rs232. Crees que este proyecto se pueda adaptar de alguna manera para este propósito. Mi correo es alejo2k_pm@hotmail.com para que por favor me envíes tu proyecto. Gracias por las respuestas.
Claro, este proyecto es justo para eso.
Envío el código del proyecto a tu correo.
Espero lo adaptes.
Saludos
Buenas q tal me parecio muy interesante tu ejemplo y quisiera q me nevies xfavor el codigo del proyecto mi correo es danijokira@hotmail.com gracias
Hola buenas tardes.. Me parece muy interesante tu proyecto, y estoy realizando una aplicacion similar! Si pudieras enviarme el codigo del proyecto y la libreria que necesito! carlosarenas14@gmail.com Muchisimas gracias de antemano
Estimado, excelente tu sitio web, y excelente tu proyecto, te agradezco y felicito a la vez. Por favor si puedes ayudarme enviandome a mi correo el ejemplo de la aplicación, tengo el caso similar al del Sr. Marco Quinde, en el que requiero leer información del peso de una báscula que está enviando en forma constante informacion al PC sin necesidad de que este le envie comandos de impresión. Porfavor ayudame con el proyecto que incluya esta adaptación, y de ser posible también las librerías que trabajen en Windows 7 en 64 bits.
Saludos y muchas gracias por su gentileza.
Mi correo: antoniobrionesnav@gmail.com
René:
MUCHISIMAS GRACIAS!! por todo, especialmente por tu atención.
Te mandé un mail sin saber en verdad si responderias.
La facu, con los finales, trabajos y cuestionarios ocupan todo mi tiempo libre. Te aviso cuando pueda retomar Java, si?
Saludos!!
De nada, ya sabes, estamos para ayudar..
Espero que todo salga bien en tus finales.
Saludos.
Buenas me pudes pasar el codigo al siguiente mail: net889@hotmail.com
Muchas gracias por el aporte!
Excelente documento te Felicito, estoy trabajando en un proyecto similar, si talvez pudieramos ayudarme con el ejemplo que tienes te agradeceria infinatemnte te deje mi correo cesarin976@gmail.com
saludos. Es bueno saber algo: no nada hay sencillo en las cosas; es decir hay cosas menos complicadas.Las personas que realmente saben cosas, nunca usan dicha palabra.
saludo. A los demas estudien y no se conformen con copy paste»enviame el codigo……».Es una mediocridad.
ts
Muy buena tu explicación, me podrías enviar el código, estoy tratando de manejar una base de datos hecha en Postgresql con datos que provienen de un microntrolador a través de rs232.
Muy agradecido con tu aporte, como dicen por ahí el conocimiento se comparte. Y apropósito de compartir por favor hazme llegar tu ejemplo al correo teocage@gmail.com
fe de erratas mi correo es teocafe@gmail.com
Como se haria para eniar un voltaje(1v) a un puerto USB de la pc?
que buen tema, pudieras enviarmelo por fa a mi correo ya que me gustaria implementarlo con un pic, te lo agradeceria mucho. saludos mi correo es juan_ochoa13@yahoo.com.mx
oye amigo podrías pasarme tu código completo es que ya lo he tratado de hacer
o modificando lo publicado pero me marca un error en la linea.
puerto.ConfiguraPuerto(“COM1”,”_9600”,”E”,”8”,”1”);
en donde se da el nombre del puerto te agradecería tu ayudar con el codigo
o diciendome que puedo hacer con ese error
Excelente documento Muchas Gracias, estoy trabajando en un proyecto similar, podrias ayudarme con el ejemplo que tienes ?
Gerardo_solis_h@hotmail.com
pana me sale un error: java.lang.UnsatisfiedLinkError: C:\Users\AleX\Documents\NetBeansProjects\Puertos\libSerialPort.dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1957)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1882)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1872)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1087)
at giovynet.nativelink.SerialPort.(SerialPort.java:23)
at ejemploBascula.PuertoObj.AbrirPuerto(PuertoObj.java:54)
at puertos.Puertos.main(Puertos.java:29)
Exception in thread «main» java.lang.UnsatisfiedLinkError: giovynet.nativelink.SerialPort.openPortC(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
at giovynet.nativelink.SerialPort.openPortC(Native Method)
at giovynet.serial.Com.(Com.java:40)
at ejemploBascula.PuertoObj.AbrirPuerto(PuertoObj.java:54)
at puertos.Puertos.main(Puertos.java:29)
Java Result: 1
Hola, excelente post. Estoy necesitando hacer exactamente lo mismo que tu hiciste. Podrias enviarme el codigo funcional al correo nelson.murstein@gmail.com ? Muchisimas gracias y excelente aporte!
Hola René desde hace días estoy buscando información sobre trabajos en java utilizando la conexión con el puerto COM y voila encontre este articulo que considero uno de los mas completos que he encontrado hasta ahora. Yo estoy intentando hacer algo parecido a lo de Marco Quinde, es un software en java que me lea el peso de un indicador Toledo 9091, con pesaje continuo. Por favor te pido me envies algún ejemplo que tengas comentariado mi correo es barbarafv88@gmx.es. Saludos y sigue así.
Amigo se te agradece la información que nos proporcionas, me podrías mandar tu código mi correo es marinhelan@hotmail.com
Gracias por tu aporte!!!! esta muy completo!!! me puedes pasar el codigo al correo abcapsys@gmail.com gracias
Te agradezco por compartir tu conocimiento es posible que me compartas tu proyecto muchas gracias. oliver_rubio@hotmail.com
HOLA RENE QUINTERO ME PARECE MUY INTERESANTE EL APORTE QUE BRINDAS ME PODRIAS ENVIAR A MI CORREO EL CODIGO YO ESTOY TRATANDO DE AUTOMATIZAR CON JAVA NETBEANS LUCES Y PUERTAS DE MI CASA INTRODUCIENDOME EN EL MUNDO DE LA INFORMATICA Y ELECTRONICA POR MEDIO DE UN ADAPTADOR USB A RS232, TE AGRADECERIA SI ME ENVIAS TU CODIGO POR FAVOR MI CORREO ES alex_lv75@hotmail.com
Me parece muy bien tu trabajo, te lo agradezco, tenia unas dudas con el codigo, crees que me lo podrias enviar a mi correo? este es: aldo.g@hotmail.es muchas gracias de antemano
hola amigo! muy buen trabajo, me pregunto si podrías enviarme a mi correo tu aplicación funcional ? muchas gracias este es mi correo mulloluis@gmail.com saludos.
Claro, ya te envié el código de ejemplo.
Saludos.
Amigo René me parece interesante tu trabajo. El link de la descarga de las librerias esta defectuoso, podrias enviar las librerias y el código completo a este correo por favor mosarc@hotmail.com.
Una pregunta más, ¿cúal es el requerimiento mínimo de la jdk para que funcione el código?
Si, te envié el código de ejemplo.
Saludos
Muy bien explicado, pero tengo una consulta, el Control de Flujo o Flow Control se puede configurar??? Yo preciso ponerlo en Ninguno… ni hadware ni Xon/Xoff pero en los set… del objeto parámetros no encontré ningún método que me suene a setFlowControl
Buena pregunta. Tengo este mismo proyecto desarrollado en C# y en VB6, y en ambos asos si puedo configurar el control de flujo, pero en el proyecto de Java tampoco encontré la forma de configurar ese parámetro.
Aún así, he probado la conexión de la báscula en los 3 proyectos, y en los tres funciona perfectamente.
Saludos.
buen dia, vi tu post y está muy bueno, al final ofreces un programa funcional es posible que me lo puedas enviar yo necesito recibir datos de un encoder y un lector de codigo de barras, es muy facil hacerlo con arduino pero necesito utilizar una interfaz hecha en netbeans agradecería mucho tu ayuda buen día.
Correo: rodasr55@gmail.com
Hola muy buenas tardes. Primero que nada muchisimas gracias por tan buena información que compartes, es un gran aporte para muchos de nosotros. Actualmente me encuentro trabajando con este tema y es por eso que quisiera preguntarte si ¿podrias mandarme tu aplicacion? Mi correo es: crys.anaya@gmail.com
Hola buenas noches, cuando uso com.receiveToString() me llegan unos caracteres asiaticos, no se si sea la codificacion del hyperterminal o quizas en java, pero cuando uso receiveSingleString pasa todo perfectamente, tienen alguna idea.?
Qué tal Carl.
Te comento, a mi en lo personal nunca me ha pasado eso que comentas, pero hay un caso de una persona que le pasó lo mismo.
Lo que tuvieron que hacer ellos fue reinstalar el JDK, la JVM y funcionó.
En realidad desconozco cuál fue la solución concreta, pero hicieron varias pruebas hasta que les funcionó. Pienso (pero no estoy seguro) que puede tener que ver algo en la instalación del sistema operativo como alguna librería de windows que esté en otro idioma.
Saludos.
tengo una duda cuando ya tengo toda la clase completa al correr el programa me dice que el puerto no existe cuando el puerto = new Com(parametros);
me dice eso y entonces no puedo enviar ni recibir los datos podrias ayudarme estoy en ubuntu y el puerto ya lo puse como es esta es mi configuracion si alguien peude ayudarme se lo agradeceria mucho puerto.ConfiguraPuerto(«/dev/ttyS0», «9600», «NONE», «8», «0»);
Qué tal Carlos..
Verifica si el usuario con el que ejecutas el programa tiene permisos para acceder al puerto /dev/ttyS0. Creo que por ahí puede haber un problema.
Saludos.
si tiene privilegios, de echo cuando le pongo COM0 me detecta bien el puerto pero al momento de escribir en el me dice que no puedo
hola que tal, estoy trabajando en algo parecido ya puedo leer los datos, pero no me aparecen completos,si quiero pesar 1.24 me sale de la siguiente forma:
dato: = 0001
dato: = 0001.
y asi varios casos
si los meto a un hilo para que los lea infinitamente me salen los datos completospero, como en desorden, por ejemplo
dato: = 0001
dato: .24 =
dato: 0001.24
dato: = 0001
y asi hasta que se detiene el hilo, nunca me sale el valor completo, me podrias ayudar para saber que es por favor
Qué tal Emiliano.
El problema es porque al parecer no estás leyendo la cadena completa del búfer. Si estás usando el código publicado aquí en el blog, prueba a modificar el valor de «Formato Cadena» para que se ajuste correctamente al valor devuelto. Por ejemplo, tu puedes haber configurado «SNNNNNNNKGST», prueba a agregar más «Ns» para dejarlo así «SNNNNNNNNNNNNNNKGST». Haz lo mismo con el valor subcadena para tomar sólo la parte de «Formato Cadena» que necesites. Este problema lo resolverás jugando con estos valores hasta que se ajusten al formato del valor que te regresa tu dispositivo.
y que significa cada S N K G S T????
En mi caso, les tengo los siguientes significados:
S = Signo. El signo del peso mostrado, puede ser + o –
N = Número. Un número del peso mostrado. Desde 0 a 9, tantos como números espere recibir en la salida del búffer.
KG = Unidad de medida. Puede ser KG, LB, etc.
ST = Estatus de la báscula. Podría indicar «báscula en movimiento», «báscula estable», etc.
Pero ojo, estos valores aplican sólo para el dispositivo que yo utilizo regularmente. Yo definí un patrón de caracteres de acuerdo a la salida real que me regresa la báscula que yo utilizo. Tú debes mirar el manual de tu dispositivo para saber en qué formato será la salida real e inventar un patrón que se ajuste a ese formato.
Saludos.
como puedo indicar que no tenga pardidad??? ya encontre las especificaciones y en paridad dice ninguna y tambien encontre el formato de datos = SO X6 X5 X4 X3 X2 X1
En el objeto de tipo «Parameters» le indicas la paridad «Ninguna» invocando el método setParity(«N»);
Saludos.
= Encabezado
X1…..X6 Dato de peso incluye punto decimal
SP Fin de la cadena
X6 digito mas significativo
X1 digito menos significativo
Tu sabes que significa Adr?? el manual dice que el parametro Adr debe estar Adr 99 no se si sea de la bascula o de mi programa
Despues de buscar tanto, por fin un articulo util!. Muy buena explicacion.
Podrias compartirme las librerias y el código, al correo marthel_24@hotmail.com, por favor? Sera de gran utilidad.
Gracias de antemano!.
Buenas… esto serviría para obtener el código del producto, el peso … en si para leer datos desde una balanza. ..
Buenas Tardes Doctor, una consulta, primero quiero felicitarte por el aporte, Mira estoy probando y estoy simulando con el HyperTerminal, cuando ejecuto mi código veo que en la pantalla me escribe el valor pero cuando lee me sale esto como salida: 翿翿翿翿翿翿翿翿 , gracias
Qué tal Euclides, buenas tardes.
Estás usando las librerías Gyovinet? Eso me ha pasado con estas librerías cuando utilizo la versión de las librerías para una plataforma incorrecta. Es decir, si mi plataforma es x86 e intento usar las librerías para x64, me pasa lo que comentas. ¿Es este tu caso?
Saludos.
oye podrias decir cual fue tu solucion. que hiciste anmi tambien me sale lo mismo.
Buenas tardes a los dos, arvininform disculpa yo tambien tengo ese error, ya cheque que las librerias sean compatibles con mi plataforma en mi caso es x64 y me da como respuesta esos caracteres tambien, intente hacerlo con las librerias de x86 por si las dudas aun sabiendo que es x64, la respuesta fue la esperada, no resultó, ahí si me marcaba error, ¿tiene alguna idea de que otra cosa puede ser?, saludos.
Qué tal Salvador, buenas tardes..
En realidad no se me ocurre otra razón.. Yo he tenido algunos inconvenientes con esta librería (Giovynet). Hice un ejemplo con la librería JSSC (Java Simple Serial Connector) y han funcionado bien. Puedes intentar utilizar esta librería. El ajuste en código no es mucho, para ve si te funciona.
Saludos.
hola buenos dias podrias pasarme la libreria por favor es que el link esta caido
gracias ….
pd. muy buen rtrabajo
Claro etziel, te mando las librerías a tu correo.
Saludos.
Buenas tardes amigos, excelente post, necesito controlar un pin específico del puerto serial para poder prender y apagar un led con una rutina, se puede hacer con esta librería? alguien sabe como?
me estoy conectando a una balanza electronica, el manual me dice que esta es la cadena de caracteres.
C1,C2,+WWWWWWW,SPgCRLF
C1 es si esta estable o inestable
C2 neto
, ASCII 44 (coma)
+ o – signo peso
WWWWWWW es peso en gramos
SP espacio
g letra g de gramos
CR caracter de control
LF avance de linea.
mi pregunta es en esta parte:
puerto.setFormatoCadena(«SNNNNNNNSKGC»);(C1,C2,+WWWWWWW,SPgCLF)
puerto.setSubCadena(«SNNNNNNN»);
tengo que ponerlo asi
puerto.setFormatoCadena(«C1,C2,+WWWWWWW,SPgCLF»);
puerto.setSubCadena(«WWWWWWW»);
WWWWWWW : que es solo lo que quiero mostrar que es el valor en gramos …
esta bien asi ?? porque lo que me preocupa son la comas y eso …
espero tu respuesta gracias
Qué tal Angélica, buenos días.
Si, es correcto como lo mencionas.. Otra forma de hacerlo es poner en «FormatoCadena» y «FormatoSubCadena» el valor «C1,C2,+WWWWWWW,SPgCLF», y al resultado le das el tratamiento que necesitas.. esto puede ser útil para que evalúes si el peso está inestable o estable, o para que puedas saber si es peso neto o no.
Saludos.
hola perdon la molestia, resulta que al copiar el código siguiendo las instrucciones y al cambiar el formato de cadena por el que me llegaba, al poner 8 en donde se debe poner el tipo de caracter, me saca el resultado en chino.
mi pregunta es
1) porque pasa eso (ya mire lo de las librerias y es para 64x lo que usa mi computador))
2)siempre hay que enviar algo a la balanza para que el me traiga el dato , pues por eso puse en EscribirDatos(Stb);
porque segun el manual los modos de comunicacion son
Stb :significa balanza tranmite solo cuando su peso es estable
Etb :significa que la balanza solo tranmite cuando se presiona una tecla
Ser :que su modo de tranmicion es continuo…
aqui esta el manual punto 6. http://bci.co/manual/Manual-fenix-maxi.pdf , pero segunn el manual esto se le configura a la balanza pero en la balanza esta como continuo y no me deja cambiarlo
o mi pregunta es sii quito lo de enviarle datos porque eso no es, o que pongo ahi ?. esto no lo eh ensayado poniendole el Stb.
en todo caso ensaye quitandole el metodo EscribirDatos pero igual no funciona … cual sera mi problema.
ConfiguraPuerto(«COM1″,»_9600″,»N»,»8″,»1″);//cambiar esto dependiendo como estaba «COM1″,»9600″,»E»,»8″,»1″
String cad=»C1,C2,+WWWWWWW,SPgCRLF»;
String cad2=»WWWWWWW»;
setFormatoCadena(cad);//(C1,C2,+WWWWWWW,SPgCLF)
setSubCadena(cad2);//(“WWWWWWW”);
AbrirPuerto();
//En mi bascula, el comando P indica que me envíe el peso actual
EscribirDatos(«Stb»);//yo creo que aqui es est que es cuando este estable y todo eso
//Leemos lo recibido
System.out.println(«El dato recibido es: «+LeerDatos());//este hay que pasarlo al JText
peso.setText(LeerDatos());
Espero alguien me ayude.. tengo dolor de cabeza de que a todos les funciona menos a mi. gracias
Qué tal Angélica, buen día!
Mira, lo de los caracteres chinos es un problema que he tenido recurrentemente con las librerías Gyovinet. Te seré sincero, no se porqué ocurre! Debido a esto hice un ajuste al programa para utilizar las librerías JSSC (Java Simple Serial Connector) y con este no he tenido ningún problema, siempre funciona y funciona bien. Puedes descargar esta librería e integrarla a tu código (el cambio entre gyovinet y JSSC es muy sencillo) y ya no tendrás problemas con los caracteres chinos.
Por otra parte, sobre la configuración «Stb», «Etb» y «Ser», son configuraciones que se le hacen a la báscula desde su menú de configuración, y no creo que se puedan cambiar vía comandos por el puerto serial. Pero, como tu báscula está configurada como «Ser», entonces no es necesario que utilices la instrucción «EscribirDatos()», ya que la báscula siempre está transmitiendo el peso capturado por el puerto serial. Lo que debes hacer es usar el método «LeerDatos()» dentro de un temporizador, y si encuentras algo, pues entonces lo procesas.
Espero haberte ayudado, pero si tienes problemas no dudes en escribir y con gusto lo revisamos.
Saludos.
muchas gracias @arvininform, de verdad gracias por responder. ya descargue la libreria JSSC-2.7.0, quite los import que habia echo de giovynet ahora sale error en Com, Parameters y en SerialPort, si no es mucha ,olestia ahora que hago de verdad estoy muy ancionsa porque funcione. puede que le sirva a otra persona, que ultimamenten tenga ese problema . por favor
gracias
Qué tal Angélica.. Si ya descargaste las librerías y las integraste a tu proyecto, ahora debes usar los métodos propios de dicha librería. Los nombre de los métodos cambian entre gyovinet y JSSC, pero son muy similares.
Aquí puedes ver un ejemplo sencillo del uso de JSSC.
https://www.codeproject.com/Tips/801262/Sending-and-receiving-strings-from-COM-port-via-jS
Tendrías que hacer lo mismo en tu proyecto.
Saludos.
uyyy de verdad te agradezco un monton. aqui dejo prueba de que me funciono con JSSC. mil gracias no tengo palabras… 😀
Hola,
Muy interesante, lo he implementado en un ratito, gracias a tus indicaciones.
Pero, la verdad, es que el post ya ha quedado completamente obsoleto, te sugiero que lo revises y cambies gyovinet por JSSC, dado que, como dices, los nombres de los métodos diferen.
De todos los post que he leido sobre este tema concreto, el tuyo es el más claro y mejor explicado, simplemente te pido que lo actualices a los nuevos tiempos.
UN 10!
Qué tal Jörj, muchas gracias por tus comentarios.. de verdad los aprecio.
Y si, tienes razón, no me he dado tiempo de actualizar el post, pero lo voy a tomar en cuenta y voy a agendar su actualización.
Me da mucho gusto que te haya servido y lo hayas podido implementar.
Saludos.!
Hola amigo, que configuración ocupaste en tu cable serial?
Ocupa un null modem
Hola amigo, tengo un problema, mi programa ya muestra el peso, pero no como debe, implementarse un hilo o un timer? Si es el caso del timer, que milisegundos le ajustaste y que retraso de recepción le pusiste? Gracias amigo por resolver las dudas, saludos
Qué tal Jhonatan..
Si, así es.. implementé un Timer que siempre está leyendo el búffer del puerto serial.
Sólo si hay algún dato, entonces se muestra en pantalla.
El tiempo que normalmente utilizo es 500 milisegundos y funciona bien.
Saludos.
Muchas gracias por responder, otra preguntita, a que velocidad de baudios le configuras ,con la actualización de 500 milisegundos?
Qué tal Jhonatan.
La velocidad de baudíos es independiente del tiempo de lectura del timer, es decir, tu dispositivo serial está configurado internamente para poder ser «accesado» a él utilizando ciertos parámetros de conexión. Esos parámetros los puedes encontrar en el manual del propio dispositivo. Si utilizas una configuración de conexión diferente a la indicada en tu manual, no podrás establecer comunicación con el dispositivo. Espero haberme explicado.
Saludos.