Controle "cualquier cosa" desde el puerto serie de su PC

Este proyecto utiliza un microntrolador PIC de Microchip Technology para activar cuatro relays y leer cuatro interruptores (push buttons). El microntrolador se conecta al puerto serie de un PC, los push buttons permiten enviar comandos al PC y los relays se conectan a ... "cualquier cosa".




Armando Acosta  (06-23-2003)

Antes de comenzar, quiero aclarar que este proyecto está en desarrollo.... A medida que vaya teniendo progreso, iré reemplazando este mismo artículo por su versión más actualizada.

El estatus actual del proyecto es como sigue: La circuitería funciona perfectamente, es decir, no hay ningún error de "pin-out". En cuanto a software, está desarrollada la rutina que recibe un byte desde el PC, no asi la que trasmite hacia el PC. La idea de cómo estructurar el software para permitir half duplex está pensada, pero no madura. Cualquier sugerencia, será bien apreciada.

Aclarado todo esto, podemos comenzar.

Una forma sencilla y a la vez elegante de usar una computadora personal (PC) para labores de control automático, es a través de uno de sus puertos serie. La norma RS232 es relativamente simple y está ampliamente documentada; si usted es nuevo en RS-232, lo remito a la internet, visite su motor de búsqueda favorito (el mio es Yahoo) y pregunte por "RS-232".

Este proyecto es más bien una especie de "laboratorio", una oportunidad para explorar el terreno del control automatico via RS232. Es por eso que la labor a realizar es tan elemental como activar un relay. Tomando este proyecto como base, usted estará listo para controlar cualquier otra cosa desde un PC... esa es la idea.

Hardware

Los parámetros de comunicación utilizados en este proyecto son los siguientes:

  • Transmisión asincrónica
  • half dupplex
  • 1 start bit
  • 8 data bits
  • 1 stop bit
  • no parity
  • no handshaking, no flow control
  • LSB first (El primer data bit es el menos significativo)
  • 9600 bps (bits por segundo)

El circuito es extremadamente simple, como puede apreciarse en la figura 1, porque toda la lógica está implementada por software. Utiliza un microcontrolador PIC16C55 para comunicarse con el puerto serie del PC, no directamente, sino a través de un driver MAX233. Como usted recordará, la norma RS232 no utiliza los tradicionales 5V y 0V para representar unos y ceros respectivamente, sino voltajes de entre 3 y 25V, negativo para el "uno" y positivo para el "cero". De ahi que necesitemos un driver.

Solo se usan dos conductores del cable RS232: RXD y TXD, o sea, por uno se recibe la informacion desde el PC, por el otro se transmite informacion hacia el PC; de modo que no se utiliza ninguna señal de "handshaking", asi como tampoco se usa ningún "flow control" por software (Xon/Xoff). Una posible modificación a este proyecto es implementar flow control ya sea por hardware o por software... ahi se lo dejo de tarea; para mis propósitos, esto no es necesario.

Consecuentemente, solo se utilizan dos de los cuatro drivers que vienen en el MAX233. Los otros dos quedan libres para "handshaking" en caso de que se anime.


La figura 2 muestra el aspecto que tiene el prototipo en estos momentos. Como puede verse, no hay ningún relay (todavia) sino solo LEDs. Esto se debe a que en estos momentos estoy desarrollando el software, para lo cual me basta con ver alguna lucesita; reemplazar los LEDs por relays es muy simple, por eso no constituye una prioridad en estos momentos.

Asi mismo, solo he colocado un push button (al lado del cristal de cuarzo), suficiente por el momento, pero obviamente, en el prototipo definitivo serán cuatro.

Por último, la alimentación la provee una batería de 9V. En un futuro es muy probable que reemplace esta batería por una fuente de alimentación decente.

Software

El comportamiento que se desea lograr es el siguiente:

Si el usuario presiona una tecla, el sistema trasmite un byte que representa el código de esa tecla. En estos momentos, esa parte del programa se encuentra en desarrollo.

Si el sistema recibe un byte via RS232, simplemente coloca los cuatro bits menos significativos de ese byte, en el puerto PB, los otros bits son ignorados. Un programa que pretenda activar uno o más relays, solo tiene que transmitir un byte cuyos cuatro bits menos significativos constituyan un "bit map" de los relays a activar (1 activado, 0 desactivado).

El programa fuente consta de tres ficheros:

El primero contiene las definiciones generales para los microcontroladores PIC16C54 y PIC16C55.

El segundo contiene las definiciones específicas de este proyecto.

El tercero contiene el código fuente del programa en sí.

Le invito a que echarle un vistazo a los dos ".h" para que se familiarice con las definiciones utilizadas.

Ahora vamos a concentrarnos en proto232.asm.

El primer bloque (entre los labels "start" y "main_loop") inicializa el microcontrolador, configurando los puertos adecuadamente.

El bloque "main_loop" implementa una vigilia. Solo se sale del lazo si se presiona una tecla o se recibe un byte via RS232.

En caso de tecla presionada, se salta a la rutina "key_pressed", que en estos momentos no hace nada en realidad, sino que retorna rapidamente al lazo principal.

Acto seguido, se llama a la subrutina "read_rs232" para ver si hay algún dato entrando via RS232. Esta subrutina trata de detectar un start bit y si no lo encuentra, retorna rapidamente con el registro W en cero. En ese caso el lazo principal continua en su vigilia por tiempo indefinido.

Cuando el PC comienza a transmitir un byte, la llamada a "read_rs232" desde el lazo principal alcanza a detectar el start bit y en lugar de regresar rapidamente con un 0 en el registro W, se detiene a recibir todos los data bits, uno por uno, leyéndolos en la variable "byte_read". Cuando todos los bits han sido leidos, la subrutina retorna al lazo principal colocando un 1 en el registro W.

El lazo principal siempre consulta la bandera Z del registro de STATUS para saber cual fue el resultado de la llamada a "read_rs232". En caso de ser 1, significa que se ha leido un byte y salta entonces a tomar la acción pertinente, en este caso, sacar dicho byte por el puerto PB (4 bits menos significativos solamente, puesto que los otros están configurados como entradas).

La subrutina "read_rs232" se explica con más detalle en el epígrafe siguiente.

Lectura de un byte via RS232


La figura 3 nos va a ayudar a comprender qué se quiere lograr con la rutina "read_rs232".

Como la vigilancia del puerto PA0 es constante, es de esperar que el start bit se detecte muy temprano, es decir, bien pegado al flanco izquierdo del mismo.

Una vez detectado, el programa tiene que generar un delay antes de leer el proximo bit. Este delay debería ser de justamente la duración de un bit, en este caso 104 microsegundos. Antes de leer el primer data bit, sin embargo, el programa introduce "pre-delay" igual a la mitad de la duracion de un bit, esto es, 52 microsegundos. El propósito de este pre-delay es ubicar las lecturas subsiguientes más próximas al centro del bit, con lo cual se logra mayor fiabilidad. En efecto, al ser esta una transmisión asincrónica, es de desperar algún desplazamiento en la frecuencia del reloj del receptor respecto al reloj del transmisor; leer cerca del centro del bit es una manera de protegerse contra estos pequeños desplazamientos.

Los parametros del delay y el pre-delay empleados están definidos en proto232.h como "TIME_OUT" y "TIME_OUT_HALF" respectivamente.

La manera de provocar estos delays es mediante lazos de espera. El valor de las constantes TIME_OUT y TIME_OUT_HALF fueron calculadas multiplicando la cantidad de ciclos de instrucción del lazo de espera, por la duración de un ciclo de instrucción, que para XTAL = 4 MHz, es 1 microsegundo.

Ahora vamos a concentrarnos en la subrutina "read_rs232" (fichero proto232.asm).

Las dos primeras instrucciones hacen una lectura rapida del puerto PA0. Si encuentran un 1 logico significa que no hay start bit, por lo que retorna de inmediato colocando FALSE (0) en el registro W para indicar que no entró ningun dato.

En caso contrario, se está en presencia de un start bit y por tanto hay que disponerse a recibir la transmisión.

Despues del bloque de inicialización que sigue, se cae en un lazo de espera (etiqueta "delay_1") para colocarse en el centro del start bit. Transcurrido este delay, el sistema se dispone a leer los 8 data bits que siguen (etiqueta "read_next_bit").

Aqui se utiliza un delay cuyo tiempo es igual a la duración de un bit. Los bits son leidos uno por uno y acomodados convenientemente en la variable "byte_read". La variable "bit_counter" se utiliza para contar los bits leidos. Cuando todos han sido leidos, la rutina returna colocando TRUE (1) en el registro W. El dato leido queda en la variable "byte_read".

Probando el sistema

El fichero proto232_test.txt es un programa de prueba escrito en QBASIC para transmitir un byte hacia el puerto serie del PC. Este sencillo programa me ha servido para probar la rutina de recepción.

La razón para usar QBASIC es que todo este desarrollo lo estoy haciendo utilizando una máquina DOS. Como parte de este proyecto, tengo en mente desarrollar un programa genérico para Windows, y por supuesto, aqui publicaré tanto el código fuente (Visual Basic) como el programa de instalación.

Conclusiones preliminares

Como dije al principio, este es un proyecto en desarrollo. Lo que tenemos hasta ahora es un prototipo casi terminado en lo que a hardware se refiere. El software está a mitad de camino, pero lo que falta (la rutina de transmisión) es mucho más sencillo que lo que ya tenemos.

Algunas sorpresas pueden estarme asechando por el camino... os mantendré informados de mis experiencias con ellas también.

Manténgase al tanto.


                                                

Miami / USAmail@armandoacosta.comInicio