Laser Game I

Después de las pruebas realizadas ya es posible emitir y recibir un haz láser modulado y portador de información, ahora hay que diseñar el juego, y los circuitos necesarios para su realización.

Después de muchas pruebas he conseguido emitir y recibir información a 4800 baudios a través del haz láser de 100 Khz, eso abre las puertas a un juego mucho más complejo. Las características básicas del juego serán:

1. Cada jugador lleva un arma que se configura al inicio, pudiendo determinar la potencia, cadencia, munición etc. El arma consta de 4 pulsadores: disparo, puntero, cerrojo y cargador. La «munición» está agrupada en «cargadores», cuando se agota uno es necesario hacer el proceso de carga: cerrojo, cargador, cerrojo. Esto proporciona más realismo y hace que tengamos que estar atentos al número de cargadores y de munición disponible.
2. Cada jugador lleva un chaleco receptor con 2 detectores: pecho, espalda y otro en la cabeza. En un principio todos van en paralelo, aunque en el futuro podrían ser distintas señales y producir distintos efectos. Al comienzo del juego se determina el nivel de «vitalidad» que se va decrementando con cada impacto, dependiendo de la «potencia» recibida.
3. El «disparo» transmite información de la potencia, número del jugador etc, para hacer estadísticas y distinguir distintos efectos.
4. Es posible intercambiar munición con los compañeros/enemigos. Poniendo el arma en posición «descarga» se transmite, por el haz láser, el código de recarga a otro jugador. Puede haber «polvorines» repartidos por el área de juego para recargar munición.
5. Es posible «curarse» recuperando parte de la vitalidad perdida recibiendo el código adecuado de los «botiquines» repartidos por el área de juego.

Posiblemente se pueda mejorar, simplificar o complicar el juego, pero esa es la idea general. La idea es fomentar el juego en equipo y la estrategia. Según se configuren las armas es posible jugar a un simple «duelo» o a una verdadera guerra de estrategas.

El dispositivo electrónico que permite intercambiar la información y llevar a cabo el juego es muy sencillo. He intentado que sea de fácil construcción, barato y con componentes de fácil localización. La parte analógica, de modulación, emisión, recepción etc. está construida en torno a un chip PLL tipo LM567, barato y fácil de encontrar. Algunos transistores NPN tipo BC548 o similar y, lo más importante, el diodo láser emisor y los fototransistores receptores, La «inteligencia» la compone un PIC16F628A, también fácil de conseguir y barato.

Este es esquema del prototipo, quizás un poco complicado, pero interesante para las pruebas y el desarrollo:

He utilizado unos displays de 7 segmentos MAN71A de ánodo común porque tengo muchos, es posible prescindir de ellos y de mucho cableado dejando solo los 8 pulsadores y los 7 LEDs informativos. También pueden utilizarse otros modelos, incluso un LCD (con la consiguiente modificación en el software, claro).

Estos son los dos prototipos con los que estoy trabajando, uno terminado con algún programa de pruebas y el otro a medias. Puede verse que no tienen mucha complicación, si se usa un circuito impreso (no como yo que he usado placa de prototipos) se puede montar en menos de una hora.

El único ajuste que hay que realizar es el del potenciómetro que regula la frecuencia de la portadora del láser. Yo uso 100Khz, pero podría trabajar con otras frecuencias más bajas que permitan transmitir los datos a 4800 Bps, o bajar la velocidad a 2400 Bps. Es importante que coincida la frecuencia de cada equipo, para que puedan detectar los disparos de los contrarios, si no cada equipo solo detectará sus propios disparos.

No he podido grabar los PIC16F628A con la pata MCLR usada como I/O ( MCLR desmarcado en el grabador) con el Pablin 2 Reloaded. Quizás sea un fallo del algoritmo. Poniendo MCLR activo se graban sin problemas, pero se inutilizan los pulsadores del display, entonces solo resetean el micro.

He actualizado el código fuente de pruebas: Fuentes CCS para LaserGame. He avanzado bastante, ahora ya «hace cosas». Esta versión de pruebas programa el arma en modo «manual» (hay que actuar el pulsador de «cerrojo» después de cada disparo para meter otra bala en la recámara), con 5 cargadores de 20 disparos y un nivel de vida de 99 créditos. La potencia del arma es 2 (descuenta dos créditos por cada disparo). Con esto estoy haciendo las pruebas. Todavía queda bastante, pero ya es operativo el disparo y la detección del mismo…

How to: Bootloader para PIC16F876A

Después del éxito del «Pablin 2 reloaded» había pensado en diseñar un programador propio con ICSP, porque algunos detalles del diseño del programador Pablin 2 siguen sin gustarme. Pero he oído hablar del Bootloader y me he decidido por él, para micros con bastante memoria es mucho más cómodo.

¿Que es un Bootloader? Es un programa muy pequeño (256 bytes en este caso) que permite descargar programas al PIC usando únicamente el puerto serie, sin ningún hardware adicional.
¿Que ventajas tiene? Solo es necesario utilizar un grabador de PIC una vez, para grabar el programa Bootloader. Podemos hacerlo con un grabador prestado. Una vez cargado el Bootloader en el PIC ya podemos descargar en él nuestros programas vía serie, sin necesidad de grabador, todas las veces que queramos. Si nuestro hardware incorpora puerto serie no es necesario quitar el PIC de su zócalo: usando el puerto serie de nuestro proyecto hacemos la descarga.
¿Como funciona? El Bootloader se carga en el final de la flash de programa del PIC y coloca el vector de interrupción de arranque apuntandolo. Arranca cuando alimentamos el procesador y espera un comando por el puerto serie. Si no lo recibe continua con la ejecución normal de nuestro programa. Si lo recibe comienza a recibir un programa por el puerto serie y a grabarlo en la flash de programa del PIC.
¿Que necesito? Es necesario tener el Bootloader configurado para nuestro hardware y cargado en el PIC, una conexión serie con el PC y el programa descargador (por ejemplo PICbootPlus).
¿Tiene algún inconveniente? Si. Es necesario modificar nuestros programas para que puedan trabajar con el Bootloader. Según el entorno de desarrollo Mplab, CCS, Hitech-C etc es más o menos complejo, pero la modificaciones suelen ser incluir unas pocas líneas de código. Además no podemos usar los últimos 256 bytes de memoria (en un PIC16F876 de 8K de memoria es el 3,1 % inutilizable)

Cómo se hace:

Yo he usado el Bootloader de Microchipc: http://www.microchipc.com/PIC16bootload/index.php, he descargado la última versión: Download Shane Tolmie PIC bootloader v9-50.

Alternativamente pueden descargarse los archivos de mi servidor: Shane Tolmie PIC bootloader v9-50. Una modificación del software de comunicación, con mini terminal y alguna opción para depuración de protocolo serie (incluye fuentes en Builder 6): picbootplus2.rar

Una vez descomprimido el archivo vemos que contiene muchos ficheros. En la carpeta «bootloader hex files for 16F87xA compatible bootloader» hay Bootloaders ya ensamblados y configurados para distintos cristales y velocidades de comunicación, para el PIC 16F876A, y para el PIC 16F876 en «bootloader hex files for 16F87x compatible bootloader». Sin embargo nos advierten que son versiones antiguas y que es mejor compilar nosotros mismos la última con los parámetros adecuados.

En «assembly source for 16F87xA compatible bootloader» tenemos un proyecto para MPLAB con un fuente en ensamblador (bootldra.asm) que tenemos que modificar según nuestras necesidades. Esta es la zona a modificar:

;================== User setting section ======================================

list p=16f877a ; <<< ajusta el tipo de PIC ( por defecto 16F877a, ponerlo a 16F876a ) ; poner el mismo PIC en las opciones del proyecto de MPLAB #define ICD_DEBUG 0 ; <<< si se usa el depurador MPLAB ICD, bajar el downloader 256 bytes para hacerle sitio [0|1] #define FOSC D'20000000' ; <<< Poner la frecuencia de nuestro cristal [Hz], max. 20 MHz ;#define BAUD D'38400' ; <<< poner la velocidad de comunicación con el PC: baud rate [bit/sec] #define BAUD D'19200' ; <<< set baud rate [bit/sec] #define BAUD_ERROR D'4' ; <<< Poner el error de velocidad de comunicación [%] NO LO HE TOCADO #define TIME ; <<< Poner el método de arranque del bootloadert PIN/TIME ; PIN : arranca al poner el pin de aranque a cero ; TIME: arranca si se recibe el comando IDENT dentro de un tiempo definido por TIMEOUT #define TRIGGER PORTB,7 ; <<< solo si se usa PIN - poner el puerto y el bit: PORT_X,PIN_NR #define TIMEOUT D'2' ; <<< solo si se usa TIME - poner el tiempo [0.1s], max. 25 sec #define WATCHDOGTIMER 0 ; <<< Watchdog timer por defecto a OFF/ON [0|1] Una vez modificado ensamblamos nuestro proyecto (yo he usado el MPLAB 7.01) y obtenemos un " bootldra.hex" que es lo que tenemos que grabar en el PIC, usando un grabador convencional. En las carpetas "Downloader.... " hay varios descargadores para diverss sistemas operativos, según nuestras necesidades. En "Downloader Windows in BC++ plus terminal" tenemos el "PICbootPlus.exe" que es el descargador que he usado yo. En la sección de Microchipc Frequently Asked Questions (FAQ) encontramos preguntas y respuestas a problemas comunes con el Bootloader. Yo uso el compilador CCS 3.236, y me informa que para adecuar mis programas al uso del Bootloader tengo que incluir esta línea en mi fuente en C:

#org 0x1F00, 0x1FFF void loader16F876(void) {} //protect bootloader code for the 8k 16F876/7

Que sirve para que el compilador reserve memoria para el Bootloader e informe si mi programa lo va a machacar.

Una vez que hemos grabado el PIC con el Bootloader y pinchado en nuestro hardware, con su puerto serie conectado al PC, y hemos compilado nuestro programa con la modificación correspondiente podemos descargarlo en el PIC. Ejecutamos el «PICbootPlus.exe» y con el botón «search» buscamos el fichero .hex que queremos descargar. El nombre aparecerá en la ventana a la izquierda de «search». Ajustamos el puerto COM1 o el que usemos en el apartado Port y la velocidad igual a la que hayamos configurado en el Bootloader en el apartado BaudRate. MArcando EEPROM descargamos también en el PIC la eeprom de datos. Estos datos son memorizados en un fichero .ini para la próxima vez que usemos el «PICbootPlus.exe».

Pulsamos el botón «Write» y en la ventana «info» aparecerá «Reset» ya al momento «Searching for Bootloader». El «PICbootPlus.exe» está enviando el comando IDENT al PIC, y espera contestación. En este momento alimentamos nuestro PIC y, si la comunicación es correcta, aparecerá «Writing, please wait» y una barra de progreso comenzará a avanzar de izquierda a derecha. Cuando haya terminado aparecerá «ALL OK!» y ya está grabado. Cada vez que recompilemos nuestro programa solo tenemos que repetir este proceso y ya estará grabado el PIC de nuevo.

En la parte inferior del «PICbootPlus.exe» tenemos un mini terminal serie con el que podemos comunicarnos con nuestro programa una vez que ha sido cargado en el PIC. Solo tenemos que ajustar la velocidad acorde con la que hayamos puesto en nuestro programa (que no tiene nada que ver con la que tenía el Bootloader).

IMPORTANTE:

Desde que arranca el programa Bootloader hasta que le transfiere el control a nuestro programa, TIMEOUT segundos que por defecto son 0,2 segundos, las patas del PIC están todas como ENTRADAS lo que significa que, las que tengan que ser salidas, serán vistas por los chips auxiliares como a 1. Durante la carga del programa esta situación se prolonga TODO EL TIEMPO que dura la carga (varios segundos). En mi caso el L293D que controla los motores «ve» las salidas PWM a 1 durante este tiempo y se conectan los dos motores a la vez, hasta que arranca mi programa y controla las patas del PIC. Hay que tenerlo en cuenta y usar lógica negativa en las salidas (que activen las cosas con un 0), si es posible, o poner un interruptor de corte de potencia para evitar movimientos incontrolados durante este tiempo.

Si se coloca un inversor en las salidas PWM para que sean activas a 0 en vez de a 1 en el programa escribir un valor 0 en el PWM dará la máxima salida y un valor 255 (para 8 bit) dará la mínima salida. En C de CCS se puede escribir:

unsigned int ciclo;

set_pwm1_duty (ciclo): // Para lógica positiva de las salidas

set_pwm1_duty(255-ciclo); // Para lógica negativa de las salidas

Laser Game 0: Preliminar

Estamos estudiando en http://www.webdearde.com el diseño de la electrónica para un juego tipo «laser game» de pistolas láser y chalecos detectores. Una de las características del diseño es que ha de ser de fácil construcción por uno mismo para hacerlo en un taller en la Campus Party 2007 (http://web6.campus-party.org)

En principio hay que probar como de fácil es detectar el láser con fiabilidad. Por precio y disponibilidad voy a usar un láser de llavero de los «chinos», pero modulado para evitar interferencias y falsas detecciones. Tanto el emisor modulado como el receptor están basados en este diseño:
http://www.mondotronics.com/PDFs/3-337_Mod_IR_v22.pdf

Este es láser de juguete usado, que emite luz roja de 680 nm, ya desmontado:

Puntero láser desmontado

Puede observarse:

1. Conexión del polo negativo de las baterías
2. Pulsador de encendido
3. Resistencia limitadora de corriente de 47 Ohmios
4. Carcasa del diodo láser
5. Muelle de ajuste de la lente
6. Lente de convergencia del haz
7. Tornillo de ajuste de la lente

El diodo láser usado tiene una caída de tensión de 2,3 V, y una resistencia limitadora de 47 Ohmios. Al estar alimentado con 3 pilas de botón LR44 de 1,5 V (4,5 V en total) circula una corriente de 47 mA en continuo.

Yo alimento el láser a 66 mA más o menos, despreciando la Vce de saturación del BC337, y alimentándolo a 4,5 V obtengo una resistencia limitadora de 33 Ohmios. Sin embargo al usar una con onda cuadrada con un ciclo de trabajo del 50% la corriente media queda en 33 mA. Alimentándolo a 5V serían 81 mA instantáneos, 40,5 mA medios. También he variado algunos valores para conseguir 3,3 Khz, que es la frecuencia que he usado, y he incluido un inversor con BC 177 para encender un LED verde cuando detecto la señal, luego me he dado cuenta de que es innecesario pero ya lo había montado. En general lo he montado adaptándolo a lo que tenía a mano.

Esquema 1

Estos son los dos prototipos idénticos de emisor/receptor. En el de la izquierda solo uso la parte receptora y en la derecha solo la parte emisora. Puede verse el diodo láser con su carcasa pero sin la resistencia limitadora ni el pulsador. Esas funciones las hace el emisor. En el receptor he usado un fototransistor de desguace de una disquetera de 5 y 1/4 pulgadas, no conozco sus características pero responde muy bien al láser.

Prototipos

Los elementos que se ven en la imagen son:

1. Led verde, testigo de recepción de la señal.
2. Fototransistor del eceptor.
3. Diodo láser del emisor.
4. Receptor, el zócalo vaccío es para pruebas.
5. Emisor, al ir separado lo puedo alejar mucho del receptor. Lo alimento con una pila de 4,5V.

He regulado el potenciómetro de 50K multivuelta del emisor para que el oscilador del PLL trabaje a 3,3 Khz, porque me ha parecido una buena frecuencia. Luego he encarando emisor y receptor y regulando el potenciómetro del receptor hasta que ha detectado la señal con seguridad. En las pruebas realizadas con este montaje detecta con mucha fiabilidad, y el PLL engancha en ms, hasta más de 10 metros de distancia. No es muy crítico el enfoque, el láser es malucho y tiene bastante divergencia, con muy poco láser que vea el fotodiodo ya detecta. Es totalmente inmune a la luz ambiente, o a la luz sin modular. Solo responde a la luz de la frecuencia ajustada en el PLL.

Para ampliar el área de detección habría que poner algún tipo de difusor o reflector para capturar la luz láser y que la reciba el fototransistor. En esta prueba uso un difusor de un sensor PIR, puede verse el punto rojo del láser emitido desde 5 metros. Aunque el fototransistor no está mirando al punto detecta perfectamente la señal. Con este difusor se detecta el láser en un área de 50 x 50 mm desde 10 metros (para probar a más distancia tengo que salirme a la calle…). El led verde encendido indica que el PLL ha enganchado y que la señal recibida es estable.

Funcionando 1

Este otro difusor es fácil de construir, se trata de una lámina de metacrilato roja de 3 mm de grueso. Mediante una lima la he mecanizado con forma de cuña, y la he lijado para hacerla translúcida. La idea es que conduzca la luz desde el ángulo de la cuña al fototransistor.

Difusor 1

En este caso la superficie de detección es de 25 x 25 mm pero con la ventaja de que el fototransistor no se coloca detrás del difusor, sino en un lado, con lo que el grueso del conjunto es de sólo 3 mm. En esta foto recibe el láser en el difusor muy lejos del fotodiodo, emitido desde 4 metros. El difusor conduce suficiente luz como para que el fototransistor lo detecte.

Difusor 2

Esto es un éxito, funciona sin necesidad de lentes, tubos ni elementos complejos o voluminosos. Creo que esto ya es un punto de partida, ahora solo falta el micro, la emisión y detección ya tienen una solución.

Mejoras: no usar PLL, hacer la emisión y la recepción con el PIC, por software. Tiene la ventaja de que es mucho más estable por el cristal del PIC. El inconveniente es que se complica el programa. No emitir onda cuadrada al 50%, sino al 10% ON, 90% OFF, y aumentar la corriente instantánea en el láser. Se consigue más alcance al haber más potencia instantánea, con la misma potencia media.
Más cosas…

He como el punto láser es muy pequeño es importante aumentar la superficie de detección con algún elemento transmisor de luz de gran superficie que la concentre en el fototransistor. Anteriormente me he referido a «difusor» o «reflector», creo que la palabra correcta para designarlo es transflector porque el elemento ha de reflejar y transmitir la luz hacia una zona determinada.

Este modelo hecho con metacrilato de 6 milímetros de grueso permite un área de detección de 50 x 50 mm, bastante grande. Se construye en unos minutos con una sierra de metal (para un material tan blando mejor de 18 dientes por pulgada) y una cartulina blanca que yo he sujetado con un clip de papelería, pero convendría pegarla.

Difusor 3

En la foto puede apreciarse también el fototransistor que he usado, era de un detector de herradura de una HP690, da una sensibilidad muy buena. Aquí abajo el detector funcionando, he dirigido el punto láser a una esquina para ver que detecta bien en la periferia del transflector.

Difusor 4

Como no tengo las características técnicas del fototransistor que he usado en las pruebas es difícil que otros realicen el mismo montaje con los mismos resultados. He probado todos los fototransistores que tenía y el que mejor resultados ha producido es el BPW77, aunque no es el más apropiado.

De estas pruebas he sacado las siguientes conclusiones:

* NO usar fototransistores «oscuros», llevan filtro de luz visible y solo responden a longitudes de onda de infrarrojo (normalmente más de 800 nm) . El láser emite un espectro muy estrecho de luz roja en 680 nm y no lo ven.
* NO usar fotodiodos. La corriente de polarización del fototransistor es bastante alta, un fotodiodo no funcionará.
* NO usar el fototransistor del CNY70, trabaja en 950 nm, ya lo he probado y da una respuesta muy mala.
* PROBAR los fototransistores de los detectores de herradura. Normalmente no llevan filtro de luz visible y dan una respuesta muy buena, mucho mejor que con el BPW77. He probado con un HA21A1, un P802, uno de una HP690C (con el que he hecho las fotos) y un OPB1740. Todos estos me han dado un resultado estupendo, similar al fototransistor de disquetera.

En el mi esquema es posible eliminar el transistor PNP BC177 y la resistencia de 10K que lleva en la base y conectar directamente el LED verde y su resistencia de 330 Ohmios entre la pata 8 del LM567 y el positivo de la alimentación. No me había dado cuenta de que es una salida en colector abierto que soporta hasta 100 mA. Como el LED verde tiene más caída de tensión que uno rojo (alrededor de 2,V) con una resistencia limitadora de 330 Ohmios queda poca corriente (5V – 2,14V) / 330 Ohmios = 8,6 mA, se puede poner una de 220 Ohmios para darle más brillo (5V – 2,14V) / 220 Ohmios) = 13 mA.