La comunicación con un dispositivo de hardware externo al PC es un tema apasionante y que puede dar mucho juego.
Nota del autor: Estepost puede resultar demasiado "técnico". Lo que intentaré explicar de la mejor forma posible se estudia en algunas carreras de ingeniería y/o ciclos superiores. De todos modos esto no tiene porque haceros tener "miedo", más bien al contrario. 🙂
Dicho esto, imaginaos poder controlar una estación meteorológica, un termómetro, una báscula, un automáta programable, un motor paso a paso, un brazo robotizado, un semáforo, una foto-célula, una barrera, una alarma…
En muchos de los ejemplos anteriores (por no decir todos) se puede utilizar el puerto serie del PC.
En la "informática doméstica" este puerto prácticamente ya no se utiliza. Es algo parecido a las diqueteras de 3.5». Prácticamente todoslos PCs que podemos comprar hoy en día ya no disponen de este tipo de disquetera.
Esto no ocurre en el "ámbito industrial" ya que este tipo de comunicación (así como la comunicación 422, 485) se siguen usando con muchísima frecuencia .
De todos modos, existen adaptadores "USB" a "Serie". Ya que el puerto USB (Universal Serial Bus)no es mas que un puerto "serie de más velocidad" (muy muy muy a groso modo, que no se me enfade nadie eh!) . Suelen tener este aspecto:
Donde como veís, por un extremo es "usb" y por el otro es "serie" (típico conector macho de 9 pines o también conocido como DB9)
El conector DB9 será el que usaremos para "comunicarnos" con el hardaware.
Todos los puertos serie se muestran en el Administrador de dispositivos de Windows en la sección "Puertos (COM y LPT)":
Se enumerán COM1, COM2, COM3,… El máximo numero de puertos que puede gestionar Windows (ahora no recuerdo si Linux y otros S.O, también) es de 256.
En algunos portátiles, se reserva en "COM3" para el modem interno del portátil.
El puerto serie dispone de dos "pines" (patillas) "interesantes" para nuestros propositos:
- El pin 2 es el de la recepción (RxD)
- El pin 3 es el de la transmisión (TxD)
Un esquema típico de interconexión es el siguiente:
Que quiere decir este esquema:
Lo que "envía" el dispositivo hacia el PC "entra" por la "recepción" del PC
Lo que "envía" el PC hacía el dispositivo "entra" por la "recepción" del dispositivo.
Existen más señales que se pueden interconectar. Este "tipo" de cables se llaman Null modem
Desgraciadamente para nosotros, la parte del "dispositivo" no siempre tiene porque ser así. Lo que está claro es que la parte del "PC" si que será siempre así.
Para hacer pruebas son realmente útiles los softwares que "virtualizan" un puerto serie:
Estos programas crean "pares interconectados" de puertos
Existen programas de pago (como el mostrado arriba) y tambien gratuitos como el com0com (http://com0com.sourceforge.net)
Estos programas hacen dos cosas:
- Crean puertos "virtuales" en el PC
- Por defecto, interconexionan dichos puertos como si de un Null modem se trata
Para poder ver el resultado del código de este tutorial tenéis estas posibilidades:
- Usar un software para "virtualizar" puertos
- Usar 2 PCs. En uno se ejecuta el hyperterminal (lo veremos a continuación). En el otro PC se ejecuta el código del tutorial. La conexión entre los dos PCs se hace con un cable "Null modem" (con cruzar los pines 2 y 3 respectivamente más la tierra (GND) es suficiente para las pruebas)
Antes de entrar en el ejemplo comentar algo sobre los caracteres ASCII.
Como bien sabéis, los 31 primeros códigos ASCII son caracteres "de control". Tabla ASCII
Estos carácteres son muy habituales en estas comunicaciones. Normalmentehablamos de "datagramas" o "tramas de comunicación". Una trama típica podría ser:
<STX>HOLA<ETX><CR><LF>
Ahí se transmiten 8 bytes:
- 1: Carácter ASCII 2 (<STX> o tambien llamado Start of Text)
- 2: Carácter ASCII "H"
- 3: Carácter ASCII "O"
- 4: Carácter ASCII "L"
- 5: Carácter ASCII "A"
- 6: Carácter ASCII 3 (<ETX> o tambien llamado End of Text)
- 7: Carácter ASCII 13 (0x0D en hexadecimal) (<CR> o lo que se conoce como Carry Return o Retorno de carro)
- 8: Carácter ACII 10 (0x0A en hexadecimal) (<LF> o lo que se conoce como Line Feed o Salto de línea)
La trama de comunicación depende exclusivamente del dispositivo, pudiendo ser mas o menos compleja.
Por último, los dispositivos tienen básicamente dos formas de funcionar:
- El dispositivo, cada cierto intervalo de tiempo envía la trama de comunicación hacia el PC. Esto suele conocerse como envío continuo
- El dispositivo únicamente envía la trama de comunicación hacía el PC cuando ha recibido una "petición". En este caso el PC envía "algo" al dispositivo, el dispositivo lo procesa y "contesta". Esto suele conocerse como envío por petición o por "polling"
En los ejemplos que acompañan el tutorial encontraréis dos ejemplos, precisamente uno de envío en "continuo" y otro de envío por "petición".
Bueno, al lio 🙂
Para menejar los puertos series desde .NET tendremos que importar el siguiente Namespace:
Imports System.IO.Ports
Este Namespace incorpora una serie de objetos y clases para el manejo de los puertos serie.
Lo que haremos será "simular" un dispositivo, en este caso en particularuna báscula. Si alguien conoce el protocolo empleado le regalo un gallifante 🙂
Para la "rececpción" usaremos el programa hyperterminal de Windows.
Nota: El hyperterminal de Windows está disponible en Windows XP en el apartado de Accesorios -> Comunicaciones. En Vista / 7 no está disponible (sic). Si este es vuestro caso teneis dos opciones:
- Esperar a la siguiente entrega (Parte II) donde construiremos en "receptor"
- Utilizar cualquier otro software "terminal" (Google it 🙂
Los ejemplos utilizan el COM9, que está "interconectado" con un softwarede virtualización con el COM8, que es el que usaremos en el hyperterminal.
Pues bien, lo primero que hacemos es abrir el hyperterminal y seleccionar el COM8:
A continuación establecemos las propiedades del puerto así:
Al aceptar vemos la "consola" del hyperterminal:
Como véis, no se está recibiendo "nada". Ahora ejecutamos el Tutorial31_Continuo y pulsamos en el botón "Abrir":
A partir de ese momento, se empiezan a recibir datos en el hyperterminal.
Al variar los datos, se envía la trama con dichas variaciones:
Y aquí más variaciones:
En función del los valores de "BRUTO" y "TARA" podéis observar que la trama es distinta.
De todos modos, la idea es observar que las tramas se envían de forma "continua"
Para el envío a petición procedemos así:
En nuestro caso en particular, nuestro simulador Tutorial31_Peticion debe recibir la trama <SOH><CR><LF> para enviar los datos.
El "problema" está en que el carácter <SOH> no es imprimible (ver lo comentado antes)
Para solucionarlo nos generamos un fichero de texto con el bloc de notasdonde escibimos la letra "a" y a continuación pulsamos la tecla ENTER
La tecla ENTER introduce los caracteres <CR><LF>.
Salvamos el documento y lo llamamos, por ejemplo peticion.txt
Ahora necesitamos abrir dicho fichero pero con un edito hexadecimal, por ejemplo, el HxD (http://mh-nexus.de/en/hxd) que es bueno, bonito y barato (freeware):
(Haz click para ampliar)
Lo que haremos es cambiar el byte 0x61H que corresponde al caracter ASCII a por el valor 01, que corresponde al caracter ASCII <SOH> (Start of heading):
Nota sabionda: el carácter <SOH> se puede "simular" como un CTRl+A
Guardamos los cambios y ahora abrimos el hyperterminal.
En la configuración del hyperterminal hay que cambiar la configuración y ponerla tal que así:
Si ahora pulsamos CTRL+A y pulsamos ENTER vemos lo siguiente:
La diferencia con el caso "continuo" es que ahora nuestro "simulador" solo envía la trama de comunicación cuando éste recibe <SOH><CR><LF> y no de forma continua como ocurría con el ejemplo anterior.
Vamos a enviarle el fichero que modificamos en el editor hexadecimal:
Y este es el resultado:
Bueno, hasta aquí esta entrada.
En este caso comprenderé perfectamente que no comentéis nada, ya que es muy posible que todo este "rollo" os suene a "chino" a la mayoría 🙂
Tampoco he querido entrar a "fondo" por el mismo motivo. De todas formas, si tenéis dudas o queréis profundizar más en el tema, podéis mandarme un MP para comentar cualquier cosa.
Saludos.
mov eax,ollydbg; Int 13h
Descargar código fuente del .NET Tutorial 31
(32 KB. Visual Studio 2008)