Archivo de la categoría: Electrónica

Televigilancia con un coche RC, arduino y la raspberry pi

¿Quién no ha tenido alguna vez la necesidad de poder ver nuestra casa desde otro lugar (oficina, hotel, otra casa, etc), o poder hacer inspección de tuberías, respiraderos o sitios inaccesibles? La idea que planteo en este artículo es la de un coche teledirigido al que podemos manejar remotamente mediante wifi y que veamos por donde va.

vigilancia

Principalmente está compuesto de un coche RC, una placa arduino duemilanove (o UNO) con una motorshield y una raspbery pi modelo B con dos USB (un WIFI y una webcam) y el sistema operativo Raspbian.

El funcionamiento es sencillo: Por un lado con un programa en python que se ejecuta en la raspberry pi hacemos un servidor que reciba los comandos por tcp/ip, estos son enviados mediante el puerto serie de la raspberry pi al puerto serie del arduino, que será el encargado de manejar la motorshield para mover el conjunto. Por otro lado en la propia Raspberry Pi hacemos streaming de vídeo para que podamos ver a través de su webcam remotamente.

Todo está alimentado con una batería Lipo 7,4 V. (2S)  de 1000 mAh. Por un lado está conectado directamente a arduino y por otro a un regulador UBEC para alimentar a la raspberry pi a través de los pines GPIO de 5v y GND.

La comunicación entre la rasbperry Pi y arduino se hace simplemente con un cable, ya que no es necesario ninguna protección al ser el pin TX de la raspberry pi el que se conecta al pin RX de arduino, y por tanto no hay riesgo con los voltajes diferentes (siempre y cuando no reprogrames arduino, si es así desconecta el cable de RX hasta haber terminado).

arduino_raspberry

El programa de Arduino es bastante simple, sólo comprueba si existe un byte en el puerto serie y si lo hay lo interpreta para saber qué movimiento hay que hacer con los motores. Se parte del byte 0x30 (0 en ASCII) y se comprueban sus bits:

  • Si el bit 0 está activado el coche va hacia delante.
  • Si el bit 1 está activado el coche va hacia atrás.
  • Si los bits anteriores están desactivados entonces el coche no se mueve.
  • Si el bit 2 está activado gira las ruedas a la izquierda.
  • Si el bit 3 está activado gira las ruedas a la derecha.
  • Si los bits anteriores están desactivados entonces la dirección el coche permanece recta.

En el lado de la Raspberry Pi hay que instalar primero varias cosas:

Editado 17/04/2014: Desactivar la consola serie que viene por defecto activada:
En el fichero /etc/inittab poner una almohadilla (#) al principio en la línea:
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
En el fichero /boot/cmdline.txt sustituir la línea:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
por
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Finalmente hay que reiniciar la Raspberry Pi para que coja los cambios.

Después hay que dar permisos de lectura y escritura al puerto serie:

A continuación creamos un fichero llamado servidor.py:

Este programa python se encarga de crear un socket tcp/ip que escucha por el puerto 1976 , cuando alguien se conecta a este puerto entonces permanece a la espera de recibir los bytes que posteriormente enviará a Arduino a través del puerto serie.

Finalmente crearemos un fichero llamado webcam.sh con el siguiente contenido (cambiar 192.168.1.133 por la ip que tenga vuestra raspberry pi):

Este programa shell arrancará un servidor de streaming con GStreamer. De momento GStreamer es el software que conozco que funciona más rápido enviando imágenes con un retardo de 2 segundos, ffmpeg tenía un retardo de hasta ¡¡¡ 10 segundos !!!. La idea la cogí de aquí.

Ahora que ya tenemos lo necesario en nuestra parte del coche, necesitamos configurar el router para redirigir los puertos 22, 1976 y 5000 hacía la ip que tenga la Raspberry Pi.

Desde el ordenador remoto necesitaremos tener el programa VLC para el recibir el streaming, un cliente de ssh  (en windows el mejor es el putty) y Processing para enviar los comandos.

Los pasos para hacer que nuestro sistema de televigilancia son los siguientes:

Conectar mediante ssh a la raspberry pi y ejecutar el comando:

Abrir otra sesión de ssh y ejecutar el comando:

Arrancar VLC y abrir una ubicación de red poniendo la siguiente línea, con esto podremos ver lo que hay frente a la webcam (cambiar 192.168.1.133 por la ip que tenga vuestra raspberry pi):

Arrancar el Processing con el siguiente programa y ejecutarlo (cambiar 192.168.1.133 por la ip que tenga vuestra raspberry pi):

Si todo ha ido bien, ponemos la ventana de processing que nos ha abierto como activa cuando hemos lanzado el programa y pulsamos los botones de los cursores del teclado, momento en el cual veremos a través de la webcam (o en local si lo tenemos enfrente) cómo nos desplazamos.

Y finalmente un vídeo de cómo funciona:

Cuentavueltas y cronómetro para robots velocistas

Cuando has fabricado un robot velocista y has hecho una pista para probarlo siempre es necesario medir los tiempos que emplea en dar una vuelta a la pista. Así podrás comprobar en cuantas décimas de segundo has mejorado tu robot. Ya sea porque le has cambiado el código de control, has ajustado alguna constante o porque hayas modificado algo de la mecánica; esas décimas que ahorres en dar una vuelta son cruciales para mejorar su rendimiento de cara a las competiciones. Puedes medirlo a mano con un cronómetro, pero nunca tendrás la precisión suficiente y el margen de error cuando quieres medir las mejoras en décimas de segundo es grande. En este artículo voy a explicar cómo fabricar un medidor de vueltas o cuentavueltas sencillo.

IMGP2895

El cuentavueltas se compone de dos módulos. El módulo principal contiene los siguientes materiales:

  • Un microcontrolador PIC16F628A.
  • Un display HD44780.
  • Un módulo bluetooth HC06.
  • Un regulador de tensión 7805.
  • Un LDR.
  • Un botón.
  • Un diodo led.
  • Un buzzer.
  • Un cristal de cuarzo de 20Mhz.
  • Dos condensadores de 22pF.
  • Un condensador de 0,1uF.
  • Un condensador de 0,22uF.
  • Una resistencia variable de 10K Ω.
  • Una resistencia de 220 Ω.
  • Una batería Lipo de 7,4V o 5 pilas de 1,5V o una pila de 9V.

cronometro

El módulo secundario en un puntero laser de 0,5mW. Es importante que su potencia sea de 0,5mW (NO 5mW como muchos) ya que valores mayores son peligrosos para la vista si por algún casual el haz de láser hace contacto con la retina de tus ojos (directamente o por reflejo especular). Úsalo bajo tu responsabilidad y con las medidas de seguridad adecuadas.

La idea es sencilla: el láser está apuntando constantemente hacia el LDR a pie de pista. Cuando el robot velocista pasa por delante corta el haz de láser y se registra en el sistema una vuelta. El sistema puede estar monitorizado tanto desde el propio display del módulo principal como remotamente desde un ordenador a través de bluetooth.

El LDR tiene un caperuzón negro hecho con cartulina negra para que no le afecte la luz de ambiente. El conjunto está pegado a una base de cartón para apoyarlo en el suelo y evitar que se mueva.

IMGP2902

El puntero láser tiene otro caperuzón negro hecho con la misma cartulina, pero está completamente tapado excepto por un agujero donde saldrá un haz de laser muy pequeño, pudiendo así ser cortado más fácilmente por el robot cuando pase por delante. El conjunto está igualmente pegado a una base de cartón para apoyarlo en el suelo y evitar que se mueva.

IMGP2904

Al principio hay que apuntar el láser hacia el LDR moviendo el puntero. Cada vez que el haz de láser incida sobre el LDR el diodo led se encenderá y se oirá un pitido en el buzzer. Así sabremos que está apuntando correctamente.

IMGP2900

Se pulsa el botón, se apaga el led y a continuación muestra los datos de la última carrera que ha grabado en la eeprom del microcontrolador.

IMGP2901

De izquierda a derecha y de arriba a abajo:

  • Tiempo de la vuelta actual (a 0 por que ahora no está corriendo).
  • Tiempo de la última vuelta dada.
  • Número de vueltas hechas.
  • Tiempo total de la carrera.

Se vuelve a pulsar de nuevo el botón, se enciende el led y se ponen los contadores a 0, esperando a que el robot corte por primera vez el haz del láser para empezar la cuenta.

IMGP2905

Cuando el robot pasa a través del haz de láser, se apaga el led y empieza a contar automáticamente.

IMGP2903

Cada vez que el robot corta el haz de láser, suena un pitido, se pone a 0 el contador de la vuelta actual, se actualiza el valor de la vuelta anterior y se suma 1 al número de vueltas. Así hasta que se pulse el botón o se llegue a la vuelta 10, momento en el que el cronómetro se parará para poder visualizar los resultados y guardarlos en la eeprom del microcontrolador.

Si se quiere volver a medir sólo hay que pulsar el botón de nuevo, se enciende el led, se ponen los contadores a 0 y se espera a que el robot corte el haz de láser de nuevo.

Todos los datos son enviados por bluetooth a 115200 bps, por lo que se puede hacer un seguimiento desde un ordenador usando Processing sin tener que estar cerca del display o para visualizarlo en una pantalla panorámica en un evento con espectadores.

cuantavueltas

El sketch de processing: Cuentavueltas_Processing

El código fuente y el .hex del programa del microcontrolador PIC. Está hecho en PCW CCS: Cronometro_PIC

Programar un microcontrolador AVR remotamente mediante bluetooth

Los que llevamos un tiempo en esto de la robótica para concursos nos vamos dando cuenta que se pierde mucho tiempo en muchas cosas para hacer las pruebas a nuestros robots y dejarlos configurados correctamente. Una de las cosas que lleva más tiempo es reprogramar el robot cada vez que queremos cambiar algo en el firmware que no funciona: tienes que ir a por el robot, cogerlo, pararlo, llevarlo hasta el ordenador, quitarle la batería, ponerle el cable ICSP, seleccionar el fichero .hex, programarlo, ponerle la batería de nuevo, llevarlo a la pista, dejarlo en ella y activarlo.

Con este artículo nos vamos a ahorrar todos los pasos mencionados simplemente programando el firmware del robot mediante bluetooth gracias a un bootloader.

Aunque este artículo esté enfocado a la baby orangutan (atmel328P) y el módulo bluetooth CSR, podría funcionar con otros microcontroladores AVR (incluido Arduino) y otros módulos bluetooth.

Como comentaba antes, la posibilidad de programar el firmware de nuestro microcontrolador AVR mediante bluetooth se basa en un bootloader. Los bootloader permiten reprogramar el microcontrolador sin necesidad de tener que usar siempre un programador ICSP. En realidad no es más que un programa que se carga en la zona alta de la memoria y que cambiando los fuse bits del microcontrolador hacemos que sea el primero que se ejecute. Esta gran ventaja nos permite que el bootloader esté comprobando durante unos segundos si se envía información desde el puerto serie del microcontrolador, si es así, reprograma el microcontolador (excepto la zona de memoria del bootloader) con el código enviado y lo ejecuta, si no es así, entonces pasado un tiempo ejecuta el código que hubiese anteriormente. Como el puerto serie ya ha sido configurado por el bootloader, en nuestro programa ya podremos usar las rutinas de envío y recepción por el puerto serie sin la necesidad de tenerlo que configurar de nuevo.

El objetivo de este artículo no es explicar cómo hacer un bootloader, sino utilizarlo directamente. Por eso voy a usar uno ya hecho: KAVR. Este bootloader espera por el puerto serie que se le envíe el fichero .hex del código a programar, por lo que podríamos usar cualquier programa como Minicom (linux), Hyperterminal (windows xp) o, como en mi caso, Tera Term (windows 7).

Antes de usarlo hay que retocar los fuentes, por lo que debemos bajarnos el código fuente, descomprimirlo, entrar en el directorio bootloaderskavr-0.2_328P-14s y editar el fichero Makefile. Dentro de este hay 3 valores que cambiar dependiendo de nuestro sistema:

  • F_CPU: La velocidad de nuestro microncontrolador en hertzios, en el caso de la Baby Orangutan es 20000000.
  • BAUD: La velocidad del puerto serie en bps, en mi caso el bluetooth está configurado a 115200.
  • TIMEOUT: El tiempo que esperará el bootloader a posibles datos en el puerto serie antes de ejecutar el firmware anterior, en mi caso le he puesto 5000 (5 segundos).

Dentro de la misma carpeta tenemos que editar el fichero kavr.c y añadir a la lista de cabeceras la siguiente:

y justo antes de la línea

añadir las siguientes dos líneas que desactivan el watchdog (que explicaré más adelante) en el bootloader:

Después hay que recompilarlo para que nos genere el fichero kavr.hex Para ello usaremos el toolchain de AVR, que en mi caso está en directorio C:Program Files (x86)AtmelAVR ToolsAVR Toolchainbin:

A continuación debéis activar en el microcontrolador los fuse bits BOOTSZ y BOOTRST para indicarle que va a tener un bootloader, el BOOTSZ debe ser de 512 palabras para que quepa el KAVR:

Finalmente enviamos el fichero kavr.hex mediante ICSP al microcontrolador, esta será la última vez que tengáis que hacerlo 😉 .

Ya tenemos nuestro bootloader activo. Ahora hay que hacer nuestro programa, compilarlo y enviárselo mediante bluetooth a nuestro microcontrolador. Para ello previamente deberemos haber vinculado nuestro dispositivo bluetooth a nuestro PC. Después abriremos el puerto serie que se ha creado en la vinculación con los siguientes parámetros 115200,8N1,XON/XOFF:

Debido a la alta velocidad de transmisión he necesitado poner un retardo en el envío de cada línea de 1 ms, pero este ha sido mi caso y no se si os pasará igual si usáis otro módulo bluetooth (si ponéis todo el conjunto a una velocidad menor, por ejemplo 19200, no será necesario ese retardo en el envío con el módulo CSR). Lo del control de errores XON/XOFF lo implementa el bootloader, permite que el microcontrolador le diga al software de control de puerto serie que pare el flujo de datos mientras escribe en la memoria flash, así no se pierdan bytes por el camino al no poder procesarlos a tiempo.

Una vez abierto el canal de comunicación el bootloader nos enviará el texto KAVR indicando que está esperando a que le enviemos un fichero .hex:

Si no le enviamos el fichero en 5 segundos lanzará el programa que esté en la posición cero de la memoria flash, pero si no existiese tal programa, volvería el bootloader a ejecutarse. El fichero debe enviarse como fichero de texto, en Tera Term se hace en el menú FileSend File…

Si la programación ha ido mal, el bootloader enviará el símbolo ?. Si ha ido bien enviará el carácter S e inmediatamente se ejecutará el código.

Ahora sólo queda conseguir que cuando queramos programar otro firmware no tengamos la necesidad de acercarnos al robot y pulsar el botón de reset para que se resetee el microcontrolador y arranque el bootloader de nuevo. Por desgracia en los AVR no hay posibilidad de resetear mediante software, sin embargo hay un truco para lograrlo: El watchdog es un temporizador que si llega al final de su cuenta resetea el micro, por lo tanto para que no ocurra esto se debe poner a 0 el contador cada poco tiempo. El truco consiste en que cuando el microcontrolador reciba una orden a través del puerto serie, este lance un bucle infinito que no actualice el contador del watchdog, provocando su reseteo y en consecuencia ejecutando el bootloader.

A continuación pongo un ejemplo de código muy sencillo: Lo que hace el programa es activar la interrupción de recepción de carácteres. Después apaga y enciende un led en el pin PD7 cada 500 ms. indefinidatmente, pero cuando recibe una R por el puerto serie, cambia el valor de una variable a 1. Dentro del bucle principal se comprueba si esa variable está a 1, y si es así, envía OK por el puerto serie, activa el watchdog y se mete en un bucle infinito para provocar el reseteo.

En la siguiente imagen podemos ver cómo arranca el bootloader con el texto KAVR, como no hay nada que programar no sale nada más y arranca el programa principal, pero al cabo de poco se le ha enviado al programa una R y este ha respondido con un OK, a continuación el microcontrolador se ha reseteado arrancando de nuevo el bootloader y mostrando otra vez KAVR, se le ha enviado un fichero .hex y el bootloader ha respondido con una S indicando que todo ha ido bien y procediendo a ejecutar el programa principal:

Y aquí una demostración en vídeo:

L.I.O.S.: El robot de 10$

English version

Introducción:

Hace algún tiempo leí un artículo sobre un concurso para crear un robot con un coste de 10$ para el aprendizaje de robótica en escuelas con un coste admisible. Este concurso es el reto AFRON.

Así que me pareció una buena idea participar. Se me ocurrió que un robot  muy simple de hacer pero que es un buen punto de partida para aprender es un seguidor de luz, donde los sensores del robot están buscando si hay un foco luz y cuando lo encuentran se dirigen hacia el. Me puse a buscar los componentes, a construir el robot y al final he terminado a L.I.O.S. (Light input output system):

Como se puede ver en el vídeo, las ruedas y el chasis son de cartón de una caja reciclada. Aunque no se aprecie, los sensores son LDR, los motores son dos servos trucados para rotación continua, el cerebro es un microcontrolador PIC 12F683, tiene dos diodos led para indicar el estado y una batería lipo de 3,7V. y 130 mAh para alimentar el sistema.

Funcionamiento:

Nada más enchufar la batería los leds parpadean varias veces. Hay dos LDR que el microcontrolador está comprobando constantemente; si este detecta que en uno de ellos  hay una intensidad de luz grande, entonces enciende el led del lado del LDR y activa el servo del lado contrario (si la luz está a la derecha, entonces es la rueda izquierda la que tiene que moverse y viceversa); si ambos sensores detectan luz entonces los dos led se encienden y los dos motores se activan para ir recto; si no detecta suficiente luz entonces permanece parado y los leds apagados.

Consumo

En resposo consume 23 mA.
Cuando sigue una luz puede consumir hasta 300 mA.

Velocidad

8,7 cm/s. cuando la batería está a 3,7V.

Construcción:

Componentes

Nombre Descripción Precio unitario (enlace) Cantidad Total
PIC12F683 El cerebro 1,78$ 1 1,78$
  Zócalo DIP Para meter o sacar el PIC 0,18$ 1 0,18$
  Batería Lipo Para alimentar el circuito 1,33$ 1 1,33$
  Conector hembra Para enchufar la batería 0,47$ 1 0,47$
  LDR Para detectar la luz 0,32$ 2 0,64$
  Servo Para mover el robot 2,69$ 2 5,38$
  diodo led Para mostrar estado 0,13$ 2 0,26$
  Resistencia 180Ω Para los led 0,08$ 2 0,16$
  Resistencia 10KΩ Para los LDR y los servos 0,08$ 6 0,48$
Otros Cartón (reciclable de cualquier caja), cables (usar los del propio servo), estaño, pegamento y tubo termoretráctil 0,05$ (por reciclaje o mínimas cantidades) 0,05$

Total

10,73$

Herramientas

Nombre Uso Precio aproximado
Cutter Cortar el cartón  4$
  Pegamento Pegar cartón, brazos de servos y servos  3$
  Cinta adhesiva Pegar la plantilla y la batería al cartón  1,50$
Aguja Agujerear el cartón 0,02$
  Pistola de termocola Pegar LDR, leds, resistencias y zócalo al cartón  15$
  Pelacables Pelar todos los cables  10$
  Mechero Reducir los tubos termoretráctiles  2$
  Corta cables Cortar topes de los servos, cables y tubos termoretráctiles  5$
  Destornillador PH0 Apretar o aflojar los tornillos de los servos  1$
  Soldador Soldar cables con LDR, leds, resistencias, enchufe y zócalo  10$ – 25$
  Estaño Para soldar 5$
  Programador Programar el PIC 14$ – 45$
Cargador de baterías Cargar la batería Lipo 15$ – 75$
Multímetro Medir la carga de la batería Lipo 5$ – 30$

Precauciones

  • La hoja del cutter es afilada, tener cuidado de no cortarse.
  • La aguja es muy fina, tener cuidado de no pincharse.
  • El pegamento es muy fuerte, tener cuidado de que no entre en contacto con los ojos y/o la piel.
  • La termocola está muy caliente, tener cuidado de no tocarla.
  • El soldador está muy caliente, tener cuidado de no tocarlo, de no ponerlo en contacto con el cartón y de evitar respirar el humo de la soldadura.
  • La batería lipo no debe cortocircuitarse, ni sobrecargarse por encima de 4,2V. ni descargarse por debajo de 3V.

Servos

Los servos contienen electrónica para manejar su sentido de rotación y tienen engranajes para aumentar su fuerza de tracción, sin embargo sólo pueden rotar 180º, por lo que vamos a modificarlos para que su rotación sea continua como la de cualquier motor.

Lo primero es desmontarlos extrayendo los 4 tornillos de su base y separar las tapas inferior y superior:

Después hay que extraer los engranajes. Uno de ellos contiene una pestaña para que haga de tope y no avance más (marcado con un circulo rojo):

Así es como queda al cortarla:

Por otro lado tenemos el potenciómetro. Aquí debemos desoldar los cables (las flechas verdes) y romper la pared que contiene las dos pestañas que también hacen tope (las fechas rojas):

Así es como quedaría la pared que comentaba:

A continuación debemos soldar las dos resistencias de 10KΩ formando un divisor resistivo en los cables que habíamos desoldado antes (el cable blanco entre las dos resistencias). Para aislar los contactos poner tubo termoretráctil:

También aislar el extremo con tubo termoretráctil:

Finalmente unir todos los engranajes de nuevo, meter la electrónica, poner las tapas y atornillarlas:

Chásis y ruedas

Imprimir en papel esta plantilla en DXF a escala 1:1 (yo he usado el programa de software libre LibreCad):

Pegar el papel con cinta adhesiva al cartón. Agujerear los círculos pequeños con una aguja y cortar las líneas con un cutter:

A continuación poner la aguja en el agujero de una rueda, poner pegamento en el brazo alargado de un servo e introducir el agujero central de este por la aguja hasta pegarlo a la rueda. Repetir el proceso con la otra rueda:

Quitar la pegatina del lateral del servo, poner pegamento en ese lateral y pegarlo en el extremo superior izquierdo de la superficie grande de cartón. Repetir el proceso en el otro lado con el otro servo:

Cortar levemente la superficie pequeña de cartón por el primer tercio, poner pegamento y adherirla a la incisión hecha anteriormente en la superficie grande de cartón (según la plantilla). Colocar las dos ruedas en los ejes del servo:

Agujerear 4 orificios entre los servos, introducir desde abajo los LDR, girarlos 30 grados desde el centro y pegarlos con termocola. Hacer dos orificios a cada lado, introducir desde abajo los diodos led y pegarlos con termocola:

Electrónica

Este es el esquema electrónico:

LDR

  • Soldar una de las patillas de cada LDR a VCC.
  • Soldar la otra patilla de cada LDR a un extremo de una resistencia de 10KΩ
  • Desde la anterior unión izquierda soldar un cable hasta el pin 7 del zócalo y poner tubo termoretráctil.
  • Desde la anterior unión derecha soldar un cable en hasta el pin 6 del zócalo y poner tubo termoretráctil.
  • Soldar el otro extremo de cada resistencia a GND.
  • Pegar las resistencias a la base con termocola.

SERVO

  • Pelar los cables y soldar el rojo a VCC y el marrón a GND de cada servo.
  • Soldar el cable naranja del servo izquierdo al pin 3 del zócalo y poner tubo termoretráctil.
  • Soldar el cable naranja del servo derecho al pin 2 del zócalo y poner tubo termoretráctil.

LED

  • Soldar un extremo de una resistencia de 180Ω a VCC.
  • Soldar el otro extremo al de otra resistencia de 180Ω.
  • Desde la anterior unión soldar un cable hacia la patilla del ánodo del led derecho.
  • Desde la anterior unión soldar un cable hacia la patilla del cátodo del led izquierdo.
  • Soldar el extremo restante de la segunda resistencia a GND.
  • Pegar las resistencias a la base con termocola.
  • Desde el cátodo del led derecho soldar un cable hacia el ánodo del led izquierdo.
  • Desde la anterior unión soldar un cable hacia el pin 5 del zócalo y poner tubo termoretráctil.

PIC

  • Soldar el pin 1 del zócalo a VCC y poner tubo termoretráctil.
  • Soldar el pin 8 del zócalo a GND y poner tubo termoretráctil.
  • Pegar el zócalo a la base con termocola.

Batería

  • Enchufar el conector a la batería y comprobar cual es VCC y cual GND con un polímetro.
  • Soldar un cable a VCC y otro a GND y juntarlos con el resto del circuito. Poner tubo termoretráctil.
  • Enrollar un trozo de cinta adhesiva y ponerla en la zona trasera de la base.
  • Poner la batería encima de la cinta adhesiva y enchufar esta al conector.

Programación:

Desde aquí se puede descargar el código fuente para el firmware del PIC. Para entender el funcionamiento de los registros del PIC 12F683 lo mejor es leerse el datasheet.

Desde aquí se puede descargar el fichero .hex para programar el PIC.

El compilador que se ha usado es el SDCC, que es software libre. Para compilarlo he usado el siguiente comando:

Para subir el fichero .hex al PIC hay que tener un programador de PICs y un software que maneje el programador. Hay mucha variedad. Yo he usado el pickit3 de Microchip y su software para windows, pero hay otras alternativas más baratas que se pueden usar con software libre o gratuitas para linux, mac y windows.

Explicación

A grandes rasgos el funcionamiento es el siguiente:

Al enchufar la batería los leds parpadean 10 veces rápidamente. Los leds están en una configuración determinada para que si el pin del PIC está configurado como salida y la pone en alto luzca un led, si la pone en bajo luce el otro led; si está configurado como entrada (alta impedancia) los leds permanecen apagados.

Se activan las interrupciones del timer0 y del ADC. La interrupción del timer0 está configurada para que salte cada 0,1 ms. y sirve para contabilizar los tiempos en los servos. La interrupción del ADC salta cada vez que un valor ha sido leído en un LDR para activar el led asociado (si se traspasa cierto umbral), poner un valor en una variable de estado, cambiar el canal de ADC y leer el siguiente LDR.

En el bucle principal del programa se comprueba la variable de estado para saber qué servos deben activarse. La activación de los servos es distinta ya que estos están enfrentados y la rotación para ir hacia delante es diferente en cada uno. Para uno supone una señal alta de 1 ms y otra baja de 19 ms., mientras que para el otro supone una señal alta de 2 ms y otra baja de 18 ms.

Modificaciones:

Los sensores del robot son LDR, pero podrían haberse cambiado por dos CNY70 para hacer un robot seguidor de línea con el siguiente esquema:

O dos interruptores de acción rápida para hacer un robot que detectase colisiones con el siguiente esquema:

Probando el marco digital Parrot DF3120 (parte 3 y final)

Con este artículo termino de explicar cómo explotar todas las características de este marco digital. Este artículo lo dividiré en 3 partes debido a su extensión.

La primera parte consiste en explicar cómo usar la librería SDL (Simple Directmedia Layer) para dibujar en la pantalla. Lo bueno de esta librería es que es muy sencilla de usar y te facilita bastante el dibujar gráficos en la pantalla mediante programación.

La segunda parte trata sobre usar las entradas de información del marco. Se va a leer el estado de los 3 botones, del inclinómetro y la cantidad de luz que hay en el ambiente .

La tercera parte la he reservado para las comunicaciones. Dado que el marco tiene bluetooth y una tarjeta de red configurada voy a explicar cómo intercambiar información entre el marco y otros dispositivos.

1- Librería SDL

Antes de empezar a explicar, lo mejor será que ponga un vídeo, después el código fuente, a continuación cómo compilarlo, ejecutarlo y finalmente explicar su funcionamiento.

[VÍDEO]

[CÓDIGO]

[COMPILACIÓN]

Para compilar el programa, copiad el código fuente y guardarlo en la carpeta minifs con el nombre pruebasdl.c, después desde ese mismo directorio ejecutad el comando:

[EJECUCIÓN]

Una vez se haya creado el fichero pruebasdl, descargarlo en el marco junto con las siguientes imágenes:

tal y como explicaba en el anterior artículo y ejecutarlo. Si todo ha ido bien veréis lo mismo que en el vídeo. Para salir del programa simplemente pulsar las teclas CONTROL y C simultáneamente.

[EXPLICACIÓN]

Explicaré cómo funciona el programa. Un buen tutorial de SDL en español lo podéis descargar de aquí.

  • Se declaran los punteros SDL_Surface, que son los que contendrán las imágenes y el buffer de la pantalla.
  • La función SDL_Init se llama con el parámetro SDL_INIT_VIDEO para inicializar la librería SDL internamente.
  • La función SDL_GetError devuelve una cadena con el último error ocurrido en la librería SDL.
  • La función atexit con el puntero a la función SDL_Quit se llama para que, cuando la aplicación termine, se llame a la función SDL_Quit y libere todos los recursos usados por la librería.
  • La función SDL_SetVideoMode se llama para inicializar el buffer de la pantalla con los parámetros de anchura, altura, profundidad de color y que use la memoria de vídeo con la técnica de doble buffer (haciendo un OR de los valores SDL_HWSURFACE y SDL_DOUBLEBUF). Esta función nos devuelve la estructura SDL_Surface de ese buffer de pantalla.
  • La función SDL_ShowCursor se llama con el parámetro SDL_DISABLE para ocultar el puntero del ratón en la pantalla.
  • La función IMG_Load se llama con la ruta de una imagen como parámetro para cargar la imagen. Esta función nos devuelve la estructura SDL_Surface de la imagen.
  • La función signal se llama con el parámetro SIGINT y un puntero a una función para que se capture la pulsación de las teclas CTRL y C. Cuando se pulsen se llamará a la función salida que simplemente cambiará el valor de la variable salir. Esto se usa para poder salir del bucle principal y terminar el programa de una forma limpia.
  • La función SDL_BlitSurface se llama con una imagen, un valor nulo, el buffer de la pantalla y una estructura SDL_Rect como parámetros. Esto copia la imagen en el buffer de la pantalla en el lugar indicado por la estructura SDL_Rect.
  • La función SDL_SetAlpha se llama con una imagen, con los valores SDL_SRCALPHA y SDL_RLEACCEL y un número como parámetros. Esto modifica la transparencia de una imagen (valor 0 para transparente y valor 255 para opaca). No funciona bien con los PNG, por eso la imagen del sol es un GIF.
  • La función SDL_Flip se llama con el parámetro del buffer de pantalla para traspasar todos los pixels del buffer de pantalla a la tarjeta de vídeo y así mostrarlos.
  • La función SDL_Delay se llama con un número como parámetro para parar la ejecución del programa durante un tiempo especificado en milisegundos.
  • La función SDL_FillRect se llama con el buffer de pantalla, una estructura SDL_Rect y un color como parámetros para que dibuje en la zona determinada por la estructura SDL_Rect un rectángulo con el color especificado. En las animaciones se usa para eliminar el dibujo anterior al que se va a pintar y así dar un efecto de movimiento.
  • La función SDL_MapRGB se llama con el formato del buffer de la pantalla y 3 números como parámetros. Sirve para mapear un color RGB al formato del buffer de la pantalla y así adaptarlo a su profundidad de color.
  • La función SDL_FreeSurface se llama con una estructura SDL_Rect como parámetro para liberar todos los recursos utilizados por esta.

Con todo esto hemos logrado dibujar en la pantalla imágenes png y gif, además de animar dos de ellas en un bucle (una haciendo círculos gracias a las funciones trigonométricas de seno y coseno y la otra a fundirse mediante transparencia) a la espera de que el usuario pulse la combinación de teclas CTRL+C para salir del programa.

2- Entradas de información

Al igual que antes pongo un vídeo, después el código fuente, a continuación cómo compilarlo, ejecutarlo y finalmente explicar su funcionamiento.

[VÍDEO]

[CÓDIGO]

[COMPILACIÓN]

Hay que hacer lo mismo que en la COMPILACIÓN del apartado Librería SDL. Sólo que esta vez el fichero de salida se llama pruebaentradas y el del código fuente pruebaentradas.c.

[EJECUCIÓN]

Hay que hacer lo mismo que en la EJECUCIÓN del apartado Librería SDL, incluidas las imágenes si no las tenéis ya. Sólo que esta vez el fichero se llama pruebaentradas.

[EXPLICACIÓN]

En esta ocasión he aprovechado el código del anterior apartado y le he modificado para que responda a eventos. Ahora cada vez que se pulse un botón saldrá en la pantalla el icono correspondiente, se mostrará hacia que lado del marco está la gravedad y cuanta luz llega al sensor trasero.

Me centraré en explicar cómo he recuperado la información de las entradas de las que dispone el marco (botones, inclinómetro y fotoresistencia).

Si os acordáis en el primer artículo explicaba cómo acceder a la memoria del vídeo para escribir los píxeles de la imagen directamente en ella. Aquí lo que vamos a hacer es abrir el fichero /dev/mem ya que desde él podemos acceder a los registros del microprocesador que contienen la información de las entradas y poder configurarlas. Si queréis saber a fondo cómo funciona el microprocesador s3c2412 que gobierna el marco os podéis bajar su datasheet. Las entradas de los botones se pueden leer desde los pines 2, 3 y 4 del puerto F y las del inclinómetro desde los pines 9 y 10 del puerto G, en ambos casos son GPIO y los leeremos mediante polling. El valor de la fotoresistencia se puede leer del pin ADC0 y como indica el nombre es un ADC que leeremos igualmente mediante polling.

En la función inicializa_entradas inicializaremos los registros:

  • Con la función open abrimos el fichero /dev/mem como lectura y escritura.
  • Con la función mmap abrimos las posición de memoria 0x56000000 para poder acceder desde el espacio de usuario a los registros de configuración y de datos de los puertos GPIO y la posición de memoria 0x58000000 para leer los canales ADC. Estos números se pueden encontrar en las páginas 68 y 69 del datasheet que he puesto antes.
  • Para leer los puertos F y G debemos configurarlos antes. Para esto debemos acceder a las direcciones de memoria de configuración del puerto F (GPFCON 0x56000050) y del puerto G (GPGCON 0x56000060) e indicar qué bits serán de lectura. En el puerto F serán los bits 2, 3 y 4 por lo que el valor de configuración para este registro (según las página 275 del datasheet) será xxxxxx000000xxxx, o lo que es lo mismo, para dejar el resto de bits a su valor original y sólo cambiar los 6 bits de los botones hay que hacer una operación AND del valor 0xFC0F. En el puerto G serán los bits 9 y 10 por lo que el valor de configuración para este registro (según la página 276 del datasheet) será xxxxxxxxxx0000xxxxxxxxxxxxxxxxxx, o lo que es lo mismo, para dejar el resto de bits a su valor original y sólo cambiar los 4 bits del inclinómetro hay que hacer una operación AND del valor 0xFFC3FFFF.
  • Para leer continuamente el valor del canal 0 del ADC donde se encuentra conectada la fotoresistencia debemos configurar el registro ADCCON situado en la dirección de memoria 0x58000000.  Lo inicializaremos asignándole el valor 0x7FC2 (según la página 420 del datasheet). Finalmente leemos el valor del ADC para activarlo.

En la función lee_entradas leeremos el valor de las entradas y los guardaremos en una estructura llamada ENTRADAS:

  • Accedemos a las direcciones de memoria de datos del puerto F (GPFDAT 0x56000054) y G (GPGDAT 0x56000064), extraemos uno por uno los valores de los pines con una operación AND, desplazamos esos valores mediante shifting hasta dejarlos en el primer bit  y los vamos guardando en la variable correspondiente de la estructura. Los botones cuando están libres tienen un valor de 1, pero cuando están pulsados tienen un valor de 0. El botón izquierdo corresponde al pin 3, el botón central corresponde al pin 4 y el botón derecho al pin 2. El inclinómetro tiene un valor de 3 cuando el marco reposa sobre su base , un valor de 2 si reposa sobre el lado derecho y un valor de 1 si reposa sobre el lado izquierdo. No detecta cuando el marco reposa por el lado contrario a la base (que sería un valor de 0).
  • Para el ADC0 accedemos a su dirección de memoria de configuración (ADCCON 0x58000000), leemos su valor y comprobamos que el último bit está a 1 para saber si podemos leer el resultado de la conversión o todavía la está haciendo, si está a 1 leemos la dirección de memoria de datos (ADCDAT0 0x5800000C), nos quedamos con los primeros 10 bits y hacemos una conversión a 8 bits para que se pueda usar directamente en la función  SDL_SetAlpha.

Con todo esto hemos modificado el programa del apartado Librería SDL para que ahora sólo represente las imágenes dependiendo del estado de las distintas entradas que componen el marco digital.

3- Comunicaciones

Como en los casos anteriores pongo un vídeo, después el código fuente, a continuación cómo compilarlo, ejecutarlo y finalmente explicar su funcionamiento.

[VÍDEO]

[CÓDIGO]

[COMPILACIÓN]

Hay que hacer lo mismo que en la COMPILACIÓN del apartado Librería SDL. Sólo que esta vez el fichero de salida se llama pruebacomunicaciones y el del código fuente pruebacomunicaciones.c.

[EJECUCIÓN]

En el ordenador debéis tener bluetooth ya sea incorporado o mediante un usb y conexión a internet.

En el ordenador activar el ruteo de paquetes tcp/ip para la interfaz de red del marco (ejecutarlo todo como usuario root, en ubuntu con sudo -s)

En el marco activar la ruta por defecto de los paquetes tcp/ip

En el marco dejar visible a todos el bluetooth y permitir conexiones al marco

En el marco mostrar la MAC ADDRESS del bluetooth (para saber a donde se debe conectar el ordenador por rfcomm)

En el marco dejar en modo de escucha para rfcomm

En el ordenador conectarse al marco mediante rfcomm

En el ordenador descargarse el programa screen (si no se tenía antes)

En el ordenador conectarse al dispositivo rfcomm0 con el programa screen

En el marco ejecutar el programa

En el ordenador desde el programa screen escribir caracteres. ENTER para hacer salir el programa del marco.

Anotaciones

Tendreis que abrir una consola nueva tanto en el ordenador como en el marco después de ejecutar el comando rfcomm puesto que se queda permanentemente conectado hasta que se pulse CTRL + C.

Para salir del programa screen simplemente pulsad CTRL y A a la vez y después de soltarlos pulsad la tecla K.

[EXPLICACIÓN]

Por un lado se pretende conectar mediante bluetooth al marco usando las utilidades BlueZ mediante RFCOMM. Así conseguimos que desde nuestro ordenador podamos enviarle datos al marco.

Por otro lado pretendemos conectarnos a una página de Internet para recuperar una imagen y mostrarla en el marco.

La unión de ambas cosas es lo que habéis visto en el vídeo. Mientras escribo en el programa screen caracteres, estos se envían al marco mediante bluetooth. Despueś el marco los va concatenando y va llamando a una página web que he hecho a tal efecto para que vaya generando la cadena de texto en una imagen PNG. Esta imagen se la descarga el marco y posteriormente la muestra.

Gracias a las utilidades de BlueZ la conexión bluetooth ya se establece mediante comandos y nosotros nos tenemos que dedicar simplemente a abrir el fichero /dev/rfcomm0 y desde este escribir o leer con las funciones básicas que proporciona C para manejo de ficheros.

Las conexiones a Internet se consiguen mediante programación de sockets y esto nos da mucho juego para poder pedir información (descargar una imagen, llamar a un servicio web, etc.) y luego mostrarla en nuestro marco. En el ejemplo cuando se llama a la función carga_imagen hacemos una conexión http a https://www.sistemasorp.es/blog/imagen.php con la cadena pasada como parámetro y guardamos en el fichero texto.png la imagen PNG que se ha generado. No voy a explicar qué hace cada función de los sockets, pero si os recomiendo leer el mejor manual que hay en internet para saber cómo programarlos: Beej’s Guide to Network Programming.

Y aquí acaban esta serie de artículos esperando que os haya servido de ayuda para que podáis empezar a juguetear con el marco y sacarle muchas utilidades. Me gustaría que si hicieseis algo con el lo pusierais en los comentarios, además de vuestras dudas o lo que sea.

1º artículo

2º artículo

Recuperar una cámara Zaapa CIP-RW después de un fallo de actualización

Hace tiempo que mi amigo Roberto quiso actualizar su cámara IP (la cual compró por recomendación mía). El caso es que al actualizar el firmware el proceso falló y la cámara quedó inutilizada. Así han pasado ya muchos meses hasta que hace unos días me encontré con esta página que hablaba de cómo recuperar una cámara Foscam FI8908W cuando el proceso de actualización de firmware ha fallado.

Lo bueno de esta página es que habla de que las cámaras foscam (y la zaapa ciprw es una de ellas con el modelo FI8901W) no mueren del todo, sino que tienen un puerto serie escondido al que se puede acceder y comunicarse con una consola para cargar un firmware. Yo me he comunicado con la cámara con un conversor serie TTL a USB:

La solución ya estaba, sólo tenía que conseguir el firmware de la zaapa (ya que otros no valen) y decirle a mi amigo que me dejase su cámara para arreglársela. Pero no ha sido así de fácil y he tenido que pelearme con varios frentes.

El primero es el servicio técnico de Foscam. En el comentario 101 del anterior enlace un tal David comentaba que Doris de Foscam había sido muy amable y que le había dado los ficheros de recuperación. Yo probé la misma suerte con el servicio técnico de Foscam y esta fué la primera respuesta que obtuve:

Hi,

We do not have a model No. FI8901W camera, could you please double check the model No.?

Es decir, que no saben ni los modelos que han fabricado. Le dije que si existía ese modelo de cámara en su marca y me contesto esto otro:

Hi,

Sorry for my mistake. We have stopped produce this product for a long time. We do not have the firmware now. Sorry for this.

Vamos que no querían ayudarme en nada (David, que suerte tuviste…).

Buscando por Internet unos ficheros de recupercación para la zaapa o para la FOSCAM FI8901W no encontré nada. Pero por suerte encontré esto otro. Una forma de extraer de una cámara que funcionase su firmware a través de la consola serie oculta. El proceso fue pesado: me tuve que bajar el kermit 95 y buscar cómo demonios abrir una consola serie, después esperé un rato largo a que se ejecutara el script, convertir con el jedit una salida en otro fichero y finalmente pasar el convertidor de hexadecimal a binario, el cual tuve que compilar, modificar y compilar de nuevo para que funcionase. Todo esto para que al final no se hubiera decargado correctamente el firmware linux.bin y romfs.img necesarios para reprogramar la cámara estropeada, dando esta errores nada más arrancar.

Parecía que no iba a dar con la solución, pero encontré un programa que te descargaba automáticamente los ficheros necesarios del firmware. Lo ejecuté y parecía que había hecho bien su trabajo, pero pasó lo mismo que en el anterior párrafo aunque esta vez sólo con el fichero linux.bin. Sin embargo gracias a esta otra página descubro que el fichero linux.bin es en realidad un archivo .zip y que lo que había hecho está aplicación es comerse los últimos 168 bytes, asi que leyendo la memoria de  la cámara que funcionaba recuperé esos 168 bytes.

Finalmente seguí paso por paso el proceso de nuevo pero cambiando los comandos fx por estos:

Para Windows 7 como no existe el Hyperterminal, he usado el Tera Term.

Finalmente la cámara de mi amigo ha dejado de ser un pisapapeles y ha vuelto a funcionar, pudiéndola manejar ahora con Firefox, con su IPhone, etc.

Para evitaros las incomodidades por las que yo he pasado os dejo los enlaces de los ficheros de recuperación de la versión que le instalé a mi amigo y que es la última que proporciona Zaapa:

romfs.img

linux.bin

Embeded Web UI 2.0.0.16.bin

 

Probando el marco digital Parrot DF3120 (parte 1)

He adquirido el marco digital de fotos Parrot DF3120. Es un marco que por menos de 20€ puede representar fotografías en una pantalla de 320×240 (3.5″). Sus puntos fuertes es que tiene bluetooth para poder subir las imagenes desde, por ejemplo, un móvil y una entrada para tarjetas SD con la misma función.

Este marco ha sido hackeado y se le puede instalar un linux, con las ventajas que ello representa. El objetivo de este primer artículo es mostrar el proceso de instalación de linux y cómo acceder a este de una forma sencilla.

Lo primero es hacer un duplicado de disco del siguiente fichero: minifs-full-ext.img. Esto en linux, siendo root, se consigue con el siguiente comando (disco SD es el nombre que le haya asignado el sistema):

Lo siguiente es actualizar el firmware del marco. Para ello hay que encender el marco sin ninguna tarjeta SD insertada y enchufar el cable usb. Cuando podamos acceder al contenido del disco, crear una carpeta llamada update y dentro de esta copiar el fichero parrotDF3120.plf. Después sacar el usb de forma segura y veremos que aparecen 4 cuadros en la pantalla (uno azul y el resto verde), momento en el cual ya se ha actualizado el firmware.

Ahora tenemos un modo de arranque dual. Por un lado si encendemos el marco sin más veremos su funcionalidad de siempre, es decir, se visualizarán las imágenes que tengamos almacenadas una detrás de otra. Pero si metemos la tarjeta SD y antes de encenderlo pulsamos los botones izquierdo y central de la parte de atrás y, sin soltarlos, encendemos el marco, se arrancará  linux y busybox.

Finalmente para acceder a la consola en el modo linux podemos hacerlo de dos formas (la dificil y la fácil):

La dificil es sacar todos los tornillos para quedarnos con la placa y la pantalla. A continuación soldamos en los agujeros del J4 (la consola serie) los tres pines (1: GND, 2: RX, 3: TX) y nos buscamos un conversor TTL a puerto serie o a usb para poder comunicarnos con el dispositivo usando los siguientes parámetros de conexión: 115200 8,N,1 (recomiendo screen en linux o mac y putty en windows). Esta es la consola serie donde se ven los mensajes de estado del arranque y luego se obtiene una shell donde interactuar con linux:

La fácil es simplemente conectar el cable usb al marco y a nuestro ordenador, lo que nos configurará una conexión ethernet por usb llamada Ethernet Gadget, la cual será una tarjeta de red que debemos configurar con la IP 172.16.61.2 y la máscara de red 255.255.255.0. Si todo ha ido bien y hacemos un ping a la dirección 172.16.61.1 el marco nos debería responder. Finalmente para acceder a una shell sólo hay que hacer un telnet a la IP comentada.

Edición 22/01/2011:
En el marco vienen unos programas para probar la pantalla gráfica. Podeis ejecutar cualquiera de ellos:
/usr/bin/plasma: Una bonita demo sobre el efecto plasma.
/usr/bin/newvox: Un paisaje que si tuvieramos teclado podríamos recorrerlo.

Edición 12/02/2011:

2º artículo

3º artículo

Leer múltiples sensores de infrarrojos con un sólo pin analógico / Read several infrared sensors with an unique analogic pin

Cuando queremos crear un robot que distinga el blanco del negro de una superficie tenemos que leer la posición en la que se encuentra con varios sensores infrarrojos.

To make a robot that distinguishes a black area between a white one, we need to know the position of the robot by reading the information of several infrared sensors.

Muchas veces los microcontroladores que usamos para estos robots tienen un número muy ajustado de pines de entrada y salida, y si tenemos que usar uno de estos por cada sensor infrarrojo que utilicemos vamos a tener problemas para añadirle funcionalidades a nuestro robot: Comunicaciones serie, acelerómetros, giroscopios, i2c, sensores de distancia, bumpers, botones, motores, leds, etc.

Many times the microcontrollers used for these robots have a very limited number of in/out pins, so if we have to use one of those for each infrared sensor, we will find problems to add functionalities to our robot as Serial Communications, accelerometers, gyroscopes, i2c, distance sensors, bumpers, buttons, motors, LEDs, etc..

En los robots rastreadores se usan dos sensores infrarrojos como mínimo, en los de sumo se usan 4, en los velocistas suelen ser 6 sensores o más. Todo esto provoca que tengamos que “desaprovechar” pines de nuestro micro para leer los sensores. Sin embargo hay una forma de leer varios sensores de infrarrojos usando sólo un pin analógico del microcontrolador.

Tracker robots at least use two infrared sensors; sumo robot 4 and line follower robot tend to have 6 or more sensors. All this causes the “waste” of the pins of our micro to read sensors. However, there is a way of reading several infrared sensors using only one analog pin microcontroller.

La idea proviene de este artículo, donde se explica cómo se puede leer un teclado matricial de 4 filas x 3 columnas con un sólo pin analógico de un microcontrolador PIC.  El objetivo es usar varias resistencias para que, dependiendo de la tecla que se pulse, el pin del micro reciba una tensión distinta y poder discernir cuál es la que se ha pulsado. Aquí tendremos un inversor Schmitt trigger en cuyas salidas pondremos resistencias en serie de distintos valores unidas a un punto en común. Desde ese punto se medirá el valor de la tensión, que será distinto dependiendo del sensor activo, pudiendo conocer así la posición del robot.

The idea comes from this article, which explains how to read a keypad matrix of 4 rows x 3 columns with only one analog pin of the PIC microcontroller. The objective is to use several resistors for, depending on which key is pressed, the micro pin receives a different voltage discerning this way which key has been pressed. At this point, we will have a Schmitt trigger inverter whose output have resistors connected in series of different values attached to a common point. From this point the voltage value is measured, which will be different depending on the active sensor, being able to know the position of the robot.

Primera ventaja: Tener varios sensores CNY70 o un array QTR-8A ya no es un problema porque podemos leer todos los valores  con un sólo pin de nuestro microcontrolador y dejar el resto para otras tareas.

First advantage: Having multiple CNY70 sensors or a QTR-8A array is no longer a problem because we can read the values with a single pin of our microcontroller and leave the rest for other tasks.

Segunda ventaja: Por cada sensor que se leía con un pin analógico se provocaba una pausa, ya que la lectura de un ADC tarda un tiempo en hacerse, multiplicado por el número de sensores. Con esta solución sólo se hace una lectura.

Second advantage: Each sensor read with an analog pin causes a pause, since the reading of an ADC takes a while to execute, and this pause must be multiplied by the number of sensors. Using this solution takes only one reading.

Tercera ventaja: Como vamos a usar un inversor schmitt trigger y este sólo nos da una señal alta (5 v.) o baja (0 v.) en sus salidas, con las resistencias siempre vamos a obtener los mismos resultados de tensión aunque cambiemos de entorno (pistas de competición o caseras con distinta iluminación), por tanto no hay que calibrar.

Third advantage: As it is use a Schmitt trigger inverter which only gives a high level (5 V) or low one (0 V) in their outputs, the resistors are always going to get the same voltage if you change the environment (race tracks with different lighting or home), so there is no need to calibrate.

Cuarta ventaja: Con las resistencias correctas sólo es necesario tener un ADC de 8 bits (0-255) para medir el voltaje (en tramos de 0,02 V. aproximadamente) con una referencia de 5 V.

Fourth advantage: With the proper resistors it is only necessary an ADC of 8 bits (0-255) to measure the voltage (0.02 V steps approximately) with a 5 V reference.

Voy a poner como ejemplo 8 sensores infrarrojos que leen una hoja que tiene fondo blanco (devuelven valor cercano a 0) y la línea de color negro (devuelven un voltaje mayor). Como inversor schmitt trigger podemos usar un 40106 o un 74HCT14 que tienen 6 entradas/salidas. Como se necesitan 2 entradas más para alcanzar las 8 hay que poner otro chip inversor (recomiendo distribuirlos en 4 + 4 en vez de 6 + 2). También necesitaremos 8 diodos y 9 resistencias.

Let me give an example of 8 infrared sensors that distinguish a white background (return value close to 0) and the black line on it (that return a higher voltage). As the Schmitt trigger inverter it can be used a 40106 or 74HCT14 which has 6 inputs / outputs. Since it takes 2 more entries to reach the 8 sensor, another chip inverter is necessary (I recommend distribute 4 + 4 instead of 6 + 2). We also need 8 diodes and 9 resistors.


La salida de cada CNY70 o de cada elemento del array QTR-8A va dirigido a una de las entradas de uno de los inversores.

The output of each CNY70 or each element of the QTR-8A array is routed to one input of one of the inverters.

La salida correspondiente de ese inversor va a un diodo enfrentado. Esto es necesario ya que al juntar al final todas las salidas evitamos que si una salida esta a 5 v. y otra a 0 v. se derive la corriente entre ellas.

The corresponding output of each inverter is routed to a faced diode. This is necessary since it prevents the pass of current among outputs in different states (one output in 5V and another at 0V).

Después del diodo viene la resistencia, que dependiendo del valor que tenga hará que la tensión caiga más o menos. El valor de la resistencia debe ser único con respecto al de las otras para que la caida de tensión sea diferente.

After the diode, it is placed the resistor, which depending on its value, the voltage will decrease more or less. Each resistor value must be unique in the set so the final voltage was different.

Finalmente se unen todas las salidas en otra resistencia para crear lo que se denomina un divisor de tensión. En ese punto se debe poner la línea que une al pin analógico del microcontrolador para que este pueda medir el voltaje total y diferenciar qué sensor o sensores están activos. Esta resistencia final que une al resto va a alimentación (Vcc). Esta configuración esta diseñada para poder leer el fondo blanco con una línea negra siempre y cuando los sensores nos den un valor cercano a 0 para cuando leen el fondo blanco y un valor mucho mayor para cuando leen la línea negra. Si se necesita cambiar este comportamiento, se puede conectar la resistencia final a masa e invertir los diodos.

Finally, all outputs are joined together in another resistor to create what is called a voltage divider. In that point you may put the line connected to the microcontroller’s analog pin so the total voltage can be measured and distinguish which sensor or sensors are active. This final resistor that joins the other ones must be connected to Vcc. This configuration is designed to read a black line on the white background as long as the sensors give us a value close to 0 when reading the white background and a much greater value when reading the black line. If you need to change this behavior, you can connect the ending resistor to ground and reverse the diodes.

Ahora que ya recibimos distintas tensiones en el pin analógico de nuestro microcontrolador dependiendo de los sensores que estén activos o no, debemos plantearnos cuántas medidas posibles podemos tener. Como he puesto un ejemplo de un velocista podemos tener los siguientes casos:

  • Todos los sensores leen el fondo blanco.
  • Un sensor lee la línea negra y el resto el fondo blanco.
  • Dos sensores leen la línea negra y el resto el fondo blanco.

Now that we got different voltages in the analog pin of our microcontroller depending on the sensors that are active or not, we must consider how many possible measures can we have. As continuing with the example of the line follower, we have the following cases:

  • All sensors read white background.
  • One sensor reads the black line and the rest, white background.
  • Two sensors read the black line and the rest, white background.

Así pues según la combinatoria, debemos multiplicar el número de sensores por 2. En total tenemos 16 medidas posibles (y diferentes) para todos los estados que pueden tener nuestros sensores. Pongo un esquema con los distintos estados, el voltaje resultante según una simulación y su valor de ADC de 8 bits:

Using Combinatory, we must multiply the number of sensors by 2. In total there are 16 possible (and different) measures for all states which can have in our sensors. I put a scheme with the states, the resulting voltage according to a simulation and its value in 8-bit ADC:

Aquí dejo un vídeo de una simulación en proteus sobre la activación de varios sensores (verlo en HD y a pantalla completa):

Here I show a video of a simulation in proteus on the activation of multiple sensors (see this in HD and full screen):

Para uno de sumo ya no valdría el cálculo anterior ya que habría 7 combinaciones posibles con sus 4 sensores y el fondo es negro con una línea blanca:

For a sumo robot the previous situation is no longer valid as it would be 7 combinations with 4 sensors and the background is black with a white line:

Ahora sólo quedaría medir una primera vez los distintos valores de los sensores y luego programar en nuestro microcontrolador una tabla con esos valores que nos servirá para siempre. Por supuesto como los valores de las resistencias tienen un margen de error y la caída de tensión de los diodos no suele ser siempre el mismo, sólo podremos hablar de valores orientativos y únicamente podemos sacar los valores correctos midiéndolos directamente con un polímetro o que el microcontrolador nos lo diga a través del puerto serie. Yo he probado con valores consecutivos de resistencias comerciales y me ha funcionado bien.

Last action to take is to measure the different sensor values and then program a table in our microcontroller with those values that will be correct for us forever. Of course, the values of the resistors have a margin of error and the voltage drop across the diodes is not usually the same: we are talking only about approximate values and we can only get the correct values by measuring directly with a multimeter or with the microcontroller and sending it trough the serial port. I’ve tried commercial consecutive values of resistors and it has worked well.

Finalmente comentar que si nuestro micro no tiene pin analógico pero si tres pines digitales libres podemos usar un ADC0831.

Finally, I would like to remark that if our micro does not have an analog pin but three digital pins, we can use an ADC0831.

Gracias a Maiki por la traducción / Thanks to Maiki for translation

Mi charla de telemetría

Ya han publicado el vídeo de la charla de telemetría que di en la OSHWCON 2011.

Toda la documentación de mi charla (presentación, código fuente, esquemáticos, etc.) lo podeis descargar aquí.

Agradecer a los organizadores su tiempo, esfuerzo y ganas por sacar adelante algo tan novedoso y pionero. También dignos de mención son los ponentes que de forma altruista hemos hecho realidad este fantástico evento. Por supuesto no nos olvidemos de los patrocinadores que han permitido que este evento tuviese un nivel alto y de calidad.

A todos, nos vemos en la OSHWCON 2012.

Calcular la resistencia para un transistor accionado por un microcontrolador

Muchas veces he querido usar un transistor NPN para actuar como interruptor y poder des/activar otras partes del circuito que con las patas de un microcontrolador no se puede hacer directamente (un relé, una bombilla de 12 voltios, otro circuito, etc).

Un transistor puede ser activado (saturación) o desactivado (corte) desde un microcontrolador, pero es necesario poner una resistencia entre la pata del micro y la base del transistor. En este artículo explicaré como se puede calcular de una forma sencilla.

Dependiendo de la carga que queramos manejar debemos seleccionar un transistor NPN u otro. No es lo mismo usar un BC107 que permite tensiones de hasta 45 V. y corrientes de hasta 100 mA. que un 2N3055 que permite tensiones de hasta 60 V. y corrientes de hasta 15 A. Aquí podemos ver unos cuantos para ver cuál se adapta mejor a nuestras necesidades. Por eso debemos saber qué corriente pasa por el punto donde queremos poner el transistor para que actúe como interruptor.

Una vez que hemos seleccionado el transistor , debemos calcular qué resistencia debemos poner entre la patilla del microcontrolador que elijamos y la patilla base del transistor. Para eso primero debemos saber qué hFe (ganancia de corriente) mínima tiene nuestro transistor y nada mejor que consultar el datasheet para saber ese dato.

Después con la siguiente fórmula ya podemos calcular qué resistencia necesitamos:

  • Voltaje: Es la tensión que proporciona la pata del microcontrolador, normalmente 5 o 3,3 V. Se resta 0,7 V. porque es la caída de tensión típica entre la base y el emisor de un transistor, aunque lo puedes mirar en el datasheet del transistor como Vbe.
  • Corriente: Es la corriente que consume el circuito que queremos encender o apagar.
  • hFe: Es la ganancia de corriente (current gain) que tiene el transistor (si hay varios valores elegir el más pequeño).

El resultado es el valor en ohmnios de la resistencia que necesitamos poner.

Así por ejemplo vamos a calcular la resistencia que usaremos para manejar un circuito que consume 500 mA. funcionando a 12 V. y gestionado por un microcontrolador PIC cuya patilla da una tensión de 5 voltios.  Lo primero es buscar un transistor que se adapte a nuestras necesidades, mirando la lista anterior el 2N3053 nos viene bien ya que permite tensiones de hasta 40V. y corrientes de hasta 700 mA. Podemos ver que su hFe es de 50, por tanto la fórmula aplicada sería:

Una resistencia de 430 ohm. no es una resistencia común, por lo que buscaremos el valor más aproximado de las resistencias comerciales, que en este caso podríamos elegir entre una de 390 ohm. o una de 470 ohm.