Driver para joystick multiplexado para Raspberry PI: hasta 160 switches con 26 GPIOs

El pasado mes de Noviembre le regalé a mi hijo una consola arcade (concretamente una de estas http://arcademadrid.com/50-mando-consola-arcade-hdmi-tv-arcade-2-jugadores). Funciona mediante una Raspberry PI 2, el mueble esta bastante bien y tiene 2 joysticks y 16 pulsadores de buena calidad.
Trasteando con ella he observado que consume casi todos los GPIOs de la raspberry pi 2 para los switches de los pulsadores. Son 24 switches, conectados cada uno a un GPIO, y la raspberry PI 2 tiene 26 GPIOs.
Como me interesa añadir mandos de SNES y un volante de PS2 usando el driver “gamecon_gpio_rpi” https://github.com/RetroPie/RetroPie-Setup/wiki/GPIO-Modules he diseñado una esquema de conexionado nuevo, multiplexando la lectura de los switches, de forma que puedo conectar los 24 switches usando solo 10 GPIOs. Así puedo conectar los mandos SNES y PS2 en los pines que quedan libres
Usando este conexionado se pueden conectar los 24 switches incluso a una raspberry PI 1 que solo tiene 17 GPIOs disponibles en el conector de 26 pines.
Claro que para que esto funcione bien es necesario escribir un driver del kernel de linux que se encargue de leer el hardware y lo muestre en un dispositivo (en el arbol /dev) de forma que los programas lo puedan utilizar.

Una complicación autoimpuesta es que se pueda usar tanto para raspberry pi 1 con conector de 26 pines como con raspberry pi B+ ó 2 con conector de 40 pines intentando dejar siempre como última elección los pines de funciones especiales.
Gracias a esto es posible conectar 2 joysticks con 8 pulsadores (mas 4 de dirección) cada uno dejando libres los pines de TX y RX de UART0 y SDA1 SCL1 del I2C. En la versión 0.0.2 del driver intento también dejar libres los pines que necesita el driver “gamecon_gpio_rpi”.

El conexionado eléctrico es fácil, solo se necesita un diodo de señal (1N4148, por ejemplo) por cada pulsador para evitar interferencias al actuar varios pulsadores a la vez. El driver permite 18 tipos distintos de esquemas de conexionado dependiendo del número de switcheslos y joysticks que se deseen usar y del número de GPIOs disponibles.
Yo usaré el “type=14” que permite hasta 5 joysticks de 2 ejes y 8 botones auque el mueble solo necesita 2 de ellos.
El conexionado que he usado es este:
Esquema type=14

En el esquema solo se nombreb los switches con “swX” donde X es un número. Dependiendo del parámetro del driver “map=n” se mapean a los distintos pulsadores de los joysticks siguiendo este mapa:
Mapa SWx

El conexionado multiplexado se basa en cablear los switches en forma de filas y columnas. Las filas se conectan a SALIDAS GPIO de la raspberry y las columnas a ENTRADAS GPIO con el pullup activo. De esta forma con un único grupo de entradas GPIO se pueden leer, de forma alternativa, cada una de las filas. Para leer una fila es necesario poner a nivel BAJO el GPIO correspondiente. Entonces existe un nivel bajo en la fila que los pulsadores pueden enviar a las entradas (columnas) cuando de actuan. El resto de filas se mantienen a nivel alto que es bloqueado por los diodos y es como si no estuvieran conectadas.
Para usar el menor número de GPIOs he subdividido cada fila en dos, de forma que hay dos GPIO de salida por cada fila pero solo la mitad de GPIOs de entrada (columnas).
Con 27 GPIOS disponibles en los conectores de 40 pines de las raspberry se pueden conectar hasta 160 switches (usando el conexionado “type=11”) en una matriz de 8 x 20 (en realidad 16 x 10 por que he partido cada fila en dos, asi solo se usan 10 entradas en lugar de 20, pero se usan 16 + 10 pines de GPIO en lugar de 8 + 20).

El driver se instala desde un paquete .deb que he preparado. Se compila en la propia raspberry porque depende del hardware.
Antes de instalarlo es recomendable actualizar la raspberry con:
sudo apt-get update
sudo apt-get dist-upgrade -y
sudo reboot

Luego pueden eliminarse los paquetes fuente de la actualización para ahorrar espacio con:
sudo apt-get clean

Descargar el instalador, worpress no me permite subir .sh “por seguridad” y lo he ‘targzipeado’:
wget http://heli.xbot.es/wp-content/uploads/2016/05/install.tar.gz
tar -xzvf install.tar.gz
sudo ./install.sh

Primero descargará varios paquetes necesarios para la compilación: dkms, cpp-4.7, gcc-4.7 y joystick
Luego descargará los headers del kernel adecuado a la versión instalada, necesarios para la compilación del driver, con un “wget http://www.niksula.hut.fi/~mhiienka/Rpi/linux-headers-rpi/linux-headers-`uname -r`_`uname -r`-2_armhf.deb” y lo instalará con “sudo dpkg -i linux-headers-`uname -r`_`uname -r`-2_armhf.deb”
A continuación conectará con esta página, hará un wget del .deb heli-mpx-joystick-rpi-0.0.2.tar.gz y lo instalará con “sudo dpkg -i heli-mpx-joystick-rpi-0.0.2.deb”. Por último eliminará el paquete fuente de los headers, que ya no es necesario, pero los headers se quedan instalados la raspberry en /usr/src/linux-headers-x.x.x.

Todo esto llevará bastante tiempo y es necesario tener una conexión a internet operativa en la raspberry.

En una de mis raspberries he observado un problema en la compilación, debido a la actualización de los headers a a la versión 4.4.9+
"No rule to make target 'kernel/time/timeconst.bc'"

Lo he solucionado copiando el fichero timeconst.bc de http://mirrors.neusoft.edu.cn/rpi-kernel/kernel/time/timeconst.bc a ‘kernel/time/timeconst.bc’

Una vez instalado puede cargarse con
sudo modprobe heli_mpx_joystick_rpi map=2 devices=2 type=14
y probarse con
jstest /dev/input/js0
jstest /dev/input/js1

Jstest tiene un fallo, conocido pero no parcheado (al menos en la versión del paquete ‘joystick’ del repositorio de la raspberry). No muestra correctamente los nombres de los botones del joystick. Es debido a un array de nombres donde faltan tres elementos y eso hace que queden descolocados los demás.
Mientras preparaba esta entrada veo que han actualizado linuxconsoletools, que es el paquete de fuentes donde viene jstest, a la versión 1.5.1 (la anterior era la 1.4.9). Supongo que habrán incluido el parche.
https://sourceforge.net/projects/linuxconsole/files/

El driver puede descargarse del kernel con
sudo rmmod heli_mpx_joystick_rpi

También puede desinstalarse totalmente con
sudo apt-get remove heli-mpx-joystick-rpi-dkms

Fuentes y el resto de los los ficheros del proyecto aqui: http://heli.xbot.es/wp-content/uploads/2016/05/heli_mpx_joystick_rpi_0.0.2_src.tar.gz

Documentos y esquemas del proyecto aqui: http://heli.xbot.es/wp-content/uploads/2016/05/Docs-0.0.2.rar

Para que cargue de forma automática al arrancar la raspberry es necesario añadir en ‘/etc/modules’ una línea:
heli-mpx-joystick-rpi
y crear un fichero de configuración ‘/etc/modprobe.d/heli-mpx-joystick-rpi.conf’ con los parámetros deseados:
options heli-mpx-joystick-rpi map=2 devices=2 type=14

Una vez recableados los switches del mueble original e instalado este driver quedan 16 pines libres donde se pueden cablear los los conectores de la SNES y de la PS2 extraidos de consolas averiadas que he montado en el mueble asi:
Conectores SNES y PS2

Luego uso el driver “gamecon_gpio_rpi” según se explica en https://github.com/RetroPie/RetroPie-Setup/wiki/GPIO-Modules.

Y todo ha quedado asi:
Consola Retropie con SNES y PS2

Probando las fuentes de alimentación api3fs25 / 24R2639 12,2V 48A

Voy a probar un poquito la fuente…
Conecto dos resistencias de 1,1 Ohmios + 1,1 Ohmios en paralelo para que den 0,55 Ohmios y a su vez en paralelo de nuevo con otra igual. La resistencia total es de 0,275 Ohmios. A 12,2V circulará una corriente de unos 44A, cerca del límite de la fuente.
Uso treinta centímetros de cable de 6mm2 de sección para las conexiones de la carga.

Primera prueba, 12,09V medidos en la fuente y 43A (ó 42,9A incertidumbre de medida del amperímetro): 519,9 Watios!!!
42,9A midiendo en fuente

Segunda prueba, 11,97V medidos en la carga y 43A: 514,7 Watios en la carga. Tenemos 120mV de caida de tensión en los cables. A 43A son aproximadamente 5,2W de pérdidas que estarán usándose en calentar el cableado!!!
43A medido en carga

Ahora conecto las entradas SENSE- a GND y SENSE+ a +12V. Esto compensará los 120mV de caída y la tensión en la carga es ahora mas alta: 12,05V. Esto es importante para tener la tensión deseada justo en la carga, pero las pérdidas en el cableado continúan igual, ahora la fuente da 120mV mas que antes para compensarlas.
43A con SENSE

514 W son muchos watios, aunque las resistencias tienen circulación forzada de aire con un ventilador se calientan como una estufa: 209,9 Grados centígrados… y mas que mi termómetro no alcanza a medir:
Temperatura

También he observado que los cables estan a unos 35 grados y la temperatura ambiente es de 21 grados… ahí estan los 5,2W de pérdidas que medía.

Ahora conecto dos fuentes en paralelo y conecto el terminal CURRENT SHARE de una con el de la otra. 12,23V (se nota que trabajan mas descasadas) y 20A una de ellas, la mitad de la carga aproximadamente.
Dos fuentes A

La otra fuente entrega algo mas: 23,7A:
Dos fuentes B

Comprobado: las fuentes responden muy bien cerca del máximo de potencia. Una pena que no haya podido tenerlas unas horas probando, mi carga no soportaría disipar esa potencia durante tanto tiempo.

Usando una fuente de alimentación api3fs25 / 24R2639 12,2V 48A

Han caido en mis manos 4 fuentes de alimentación ACBEL modelo api3fs25 IBM P/N 24R2639 de 12,2V y 48A. Estas fuentes pueden proporcionar hasta 585W en una sola tensión de salida y son de calidad IBM (eran de dos servidores IBM Xseries x336). También pueden encontrarse en EBAY baratas http://www.ebay.es/sch/i.html?_from=R40&_trksid=m570.l1313&_nkw=api3fs25&_sacat=0
4 fuentes api3fs25

Para poder usarlas lo primero es analizarlas externamente… En una cara tienen un conector de aimentación para la entrada 220V con dos LED verdes AC y DC.
Parte trasera

En la otra un conector de flanco de tarjeta de doble cara con 20 contactos se señal y 6 contactos de potencia.
Parte delantera

Esta claro que será necesario buscar mas información para poder encenderlas al menos. Buscando api3fs25 y 24R2639 en google encuentro que son muy apreciadas como alimentadores para cargadores de baterías de RC:
http://www.rcgroups.com/forums/showthread.php?t=1005309&page=74

En www.rcgroups.com hay “algo” de información:
Fuente acbel

En principio la encienden conectando A8 con A10, pero otro autor usa A8 con B4: http://piercecollegefoundation.com/software/18539

¿Quien lo hace bien…? Porque yo he probado los dos métodos y funcionan!.

Vamos con un poco de ingenieria inversa, esta fuente es cambiable en caliente (HOT-SWAP) y ademas puede paralelizarse con otras (current sharing), o sea que será bastante complicadilla.
Lo primero es abrir la fuente para sacar un esquema parcial de las áreas que interesan:
Fuente abierta

El conector de flanco de tarjeta esta mayormente conectado a dos conectores J1 y J2 que unen la placa de potencia de la fuente con una pequeña placa montada perpendicularmente que contiene la elecrónica de control, regulación y protección.
Placa de regulacion

Esa placa contiene un PIC16F73, supongo que para controlar las funciones de diagnóstico. El controlador PWM es un UCC3895. También lleva un controlador para la conpartición de corriente (load share controller) uc3907.

Lo mejor es dessoldar la placa para poder hacer el esquema mas comodamente, aunque luego tenga que volverla a soldar en su lugar.
Placa dessodada

El borrador del esquema parcial de la zona digital de la placa es este (algun fallo en la polaridad de los transistores??? … es un borrador):
Zona digital

De este esquema se puede deducir que la fuente lleva varias entradas y salidas de diagnóstico y comunicaciones….
¿Era correcto conectar A8 a A10 ó B4 para encenderla? NO.
La conexión A8 es, efectivamente, la señal “Power ON”. Va conectada a una pata del PIC de uso general (Pin 28, RB7) y tiene un pullup (3K a +5V). En estas condiciones dejarla al aire introduce un 1 en el PIC y la fuente se mantiene apagada.
Introduciendo un 0 debería encenderse, comno así ocurre, pero ni A10 ni B4 son terminales de masa. B4 es SENSE- que es “casi” masa pero usarlo para encender la fuente introducirá un voltaje extraño en SENSE- y hará que varíe la regulación de tensión.
A10 es una entrada/salida de señalización, se pone a 0 cuando se enciende el LED verde DC de la trasera. Esta salida va conectada al colector de un transistor NPN y la base a la pata 17 del PIC (RB6) y un transistor NPN. Otro transistor enciende el LED verde. Para que el LED verde se encienda es necesario conectar un pullup externo, de forma que esta patilla acual como salida de señalicación y entrada para controlar el LED (si el PIC de la fuente lo permite).

La forma correcta de encender la fuente es unir A8 con B10.

B10 es GND, la misma GND que la del conector de potencia. El server identifica que la fuente esta conectada cuando ve esta conexión a masa.

B9 y B8 son salidas +5V VSB de 200mA. Estas salidas estan siempre presentes mientas este alimentada la fuente, aunque no este encendida.

A10 es la salida de la señal DC (igual que el LED trasero DC) y A9 es la salida de la señal AC (igual que el LED trasero AC)

A2 (pin 17 del PIC) y A3 (pin 16 del PIC) son ENTRADAS que indican a la fuente su posición en en server 00 la de la derecha y 01 la de la izquierda (visto desde la parte trasera del server). Sirven para seleccionar la dirección de la fuente en el bus I2C.

A4 (pin 22 del PIC) y A7 (pin 18 del PIC) son entradas /salidas de control (A4 podría ser /RESET) conectadas a la lógica del server.

A5 (pin 14 del PIC) y A6 (pin 15 del PIC) son SCL y SDA respectivamente. Posiblemente un SMBUS basado en I2C que se suele usar en el control de energía de los ordenadores. He probado a interrogarlo con el BusPirate y ha respondido a una direccion, que dependiendo del estado de A2 y A3, es: (en binario 001000A2A3) o sea e 0x20 a 0x23.
Esto solo si se mantiene A4 a 0, si se pone a 1 responde también a otra dirección: (en binario 010100A2A3) o sea e 0x50 a 0x53.
No he conseguido que esa dirección me responda a ningún comando, posiblemente el protocolo usa PEC, un chequeo de integridad de mensajes basado en CRC8 y yo no estoy enviando mensajes válidos…

B1, B2 y B3 van en paralelo en las dos fuentes que montanlos servers, son salidas de estado en colector abierto. La B1 se pone a 0 cuando la fuente arranca, y continua a 0 hasta que se quita tensión. Poniendo A4 a 0 se apaga (es A4 algún tipo de RESET?). No he investigado mas.

Este es el PINOUT del conecor de flanco de tarjeta, y del conector ICSP para programar el PIC:
Pinout API3FS25

La parte analógica es bastante compleja y solo he obtenido el esquema de la parte que me interesaba para la regulación de tensión.
Regulación de tensión

En los foros de RC he leído acerca de métodos para variar la tensión de salida (que funcionan) pero ¿son adecuados?.
Variar la tensión en www.rcgroups.com
Variando la tensión

Para aumentar la tensión de salida recomiendan conectar una resistencia de 33K entre dos puntos determinadados (color verde en la imagen).
Según mi esquema eléctrico estos puntos corresponden a los extremos de la resistencia de 6K (que puede verse en el esquema rotulada como 76b). La resistencia de 33K quedararía en paralelo con esta de 6K resultando una resistencia equivalente de 5,07K. Con el potenciómetro el mínimo (máxima tensión) la salida sería de 14,5V.
Esto es correcto, es la forma adecuada de aumentar el máximo de la tensión de salida. No se verá afectada la calidad de la regulación, aunque hay que tener en cuenta que los condensadores de la fuente son de 16V y estaríamos bastante cerca del límite de trabajo y se acortará su vida útil.
Para disminuírla recomiendan conectar una resistencia de 10K entre la pata 10 del UC3907 y un extremo del potenciómetro de regulación de tensión. Aunque funciona esto no es correcto porque la pata 10 del UC3907 es la alimentación del mismo, que viene de otra sección de la fuente de alimentación. Estamos introduciendo en el circuito de regulación de una fuente una tensión proveniente de otra fuente por lo que van a interferirse. Variará la tensión de salida al variar la tensión de la fuente interna, cuando deberían ser independientes entre si.
La forma correcta de disminuír la tensión mínima de la fuente es sustituir el potenciómetro de 500 ohmios por otro de otro valor. Por ejemplo con uno de 10K se puede conseguir que la tensión mínima baje hasta 6,5V. Por desgracia las otras tensiones internas de la fuente también bajan y la fuente se vuelve inestable en estas condiciones, llegando a no arrancar. Pero 7,2V si es una tensión bastante baja a la que la fuente funciona bien.

Regulacion
Eliminando la resistencia SMD de 6K y conectando un potenciómetro de 10K con una pareja de resistencias en serie de 2K2 y 3K3 en los puntos que se ve en la foto se consigue una variación de tensión de 6,13V a 13,57V.

A1 sirve para que las fuentes se coordinen en la corriente que entregan cuando se ponen en paralelo “current share”. Si se van a conectar varias fuentes en paralelo hay que conectar entre sí todas las trata de unir todas las conexiones A1 de todas las fuentes. De esta forma se coordinan y si una tiene algunos milivoltios mas de regulación de tensión no entrega mas corriente, sino que la demanda de corriente se balancea autmáticamente entre todas las fuentes. Este trabajo lo controla el integrado UC3907.

A4 y A7 son SENSE- y SENSE+. Si no se usan no pasa nada, estan conctadas iternamente a GND y +12V mediante series de resistencias de 10 ohmios. Pero si queremos tener un control preciso de la tensión en el punto de conumo debemos unir SENSE- con GND y SENSE+ con +12V justo en el punto de consumo (carga). Estas señales son las que realimentan al circuito de regulación de tensión y la fuente intentará mantener la tensión programada justo en el punto donde se conecten SENSE- y SENSE+ independientemente de la tensión de salida. De esta forma se compensa la caida de tensión en los cables.

He construido unos conectores de flanco de tarjeta macho con unos trozos de circuito impreso de doble cara y una fresadora de PCBs.
Conectores

Listo para probar:
Conectores listos

El esquema de prueba es este:
Esquema de prueba

Para probar la fuente “con chicha” dispongo de dos resistencias bobinadas de 2,2 Ohmios de unos cientos de watios. Conectándolas en paralelo tengo una resistencia de 1,1 Ohmios que a 12,2V son 11,09A, pero tienen que disipar 135W !!!. Con un ventilador de PC ayudaré a disipar el calor para poder probar durante unos minutos…

Listo para jugar:
Probando...

Arduino 1.6.3 y Teensyduino 1.22 en Raspberry PI

En este post anterior Raspberry Pi y arduino UNO instalaba el entorno arduino 1.0.3 en una Raspberry Pi con Raspbian (2013-02-09).
Actualmente el entorno de programación arduino va por la versión 1.6.3, que soporta muchas mas placas y tiene solucionados muchos errores de las versiones anteriores. Además yo suelo usar las placas Teensy 3.1 que llevan un procesador ARM cortex M4.

Teensy 3.1

En principio existe un paquete arduino para raspberry en el repositorio oficial, pero es la versión 1.0.1, demasiado antigua. Por suerte existe en hithub una distribución de arduino adaptada a la raspberry y no es muy dificil de instalar. Siguiendo las instrucciones de NicoHood Arduino IDE for Raspberry PI:

Yo parto de la distribución raspbian Wheezy 2015-02-16 Raspberry PI downloads en una SDHC de 32Gb y alta velocidad.

Instalar el raspbian y configurarlo según nuestras necesidades, se necesitará una conexión de internet para descargar los paquetes y actualizaciones. Yo trabajo desde el entorno X (startx) y en él un LXTerminal, asi se pueden cortar y pegar las instrucciones de esta página en el terminal.
Todo el proceso lo haremos como root, tenemos que modificar ficheros de sistema, instalar paquetes etc y asi evitamos tener que hacer su en cada comando:
sudo su

Primero actualizar el sistema usando una conexión de internet, tardará bastante:
apt-get update
apt-get upgrade
apt-get dist-upgrade

Con el editor nano abrir el fichero /etc/apt/sources.list
nano /etc/apt/sources.list

Y añadir estas dos líneas al final, para que el instalador apt-get encuentre las releases alternativas (jessie) que se van a usar:
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
deb http://archive.raspbian.org/raspbian jessie main contrib non-free rpi

De la misma forma, en el fichero /etc/apt/preferences:
nano /etc/apt/preferences

Añadir estas líneas al final para indicarle al instalador la prioridad de las distintas releases. Es posible que el fichero no exista, no importa, crearlo nuevo con este contenido:
Package: *
Pin: release n=wheezy
Pin-Priority: 900

Package: *
Pin: release n=jessie
Pin-Priority: 300

Package: *
Pin: release o=Raspbian
Pin-Priority: -10

Instalar el compilador avr-gcc:
apt-get update
apt-get -t jessie install gcc-avr

Instalar los paquetes necesarios para el funcionamiento del IDE (java y librerías). Es una sola línea, por su longitud el navegador puede mostrarla partida:
apt-get -t jessie install avrdude avr-libc libjssc-java libastylej-jni libcommons-exec-java libcommons-httpclient-java libcommons-logging-java libjmdns-java libjna-java libjsch-java

Descargar la release 1.6.3 desde github, tardará bastante:
git clone https://github.com/NicoHood/Arduino-IDE-for-Raspberry.git
cd Arduino-IDE-for-Raspberry

Desisnstalar la distrbución antigua, si estaba instalada:
apt-get remove -y arduino arduino-core

Instalar la nueva:
dpkg -i arduino-core_1.6.3_all.deb arduino_1.6.3_all.deb
cd ..

Esto habrá instalado el entorno Arduino IDE 1.6.3 bajo el directorio /usr/share/arduino y los sketches de ejemplo bajo /usr/share/doc/arduino-core/examples También habrá creado un icono en el menú de inicio menu->probramacion->arduino.

Para probarlo lo arrancamos el arduino IDE desde el menú. Conectamos el arduino, en mi caso un Arduino UNO, a un USB de la raspberry y seleccionamos el puerto nuevo que aparecerá en herramientas->puertos
Seleccionamos la placa en placa->arduino UNO. Cargamos un sketch, por ejemplo ejemplos->Blink y pulsamos la flecha del IDE “subir” que lo compilará y lo enviará a la placa. Si todo es correcto podremos ver parpadear el led de la pata 13 del arduino UNO!!!

Raspberry y Arduino UNO

Peeeeero, parece ser que existe un BUG conocido en esta versión (1.6.3) del IDE para linux. Lo comentan aqui: Arduino IDE Isssue #2892. Esto hace que no se detecten los puertos serie correctamente y que, de forma aleatoria, aparezca sombreado en gris la opción “puerto”. Sin embargo el IDE funciona correctamente y es posible cargar los sketches en la placa arduino. Para cambiar el puerto, si que no se puede hacer por el IDE, basta con editar /home/pi/.arduino15/preferences.txt y editar la línea “serial.port=” para que apunte al puerto adecuado, por ejemplo: serial.port=/dev/ttyACM0 que es el puerto que crea un arduino UNO al conectarse.

La segunda parte consiste en instalar el addon “tensyduino 1.22” el entorno arduino. Desgraciadamente tampoco hay paquete oficial para esto y el código fuente es propietario. Por suerte el autor del programa (Paul Stoffregen) ha ido liberando compilaciones para raspberry pi de algunas de las herramientas necesarias para ponerlo en funcionamiento:

La primera herramienta es el cargador de sketches para teensy: Teensy loader Raspberry Pi
Primero se descarga el .tar.gz con wget y luego se descomprime en el directorio /usr/share/arduino/hardware/tools de la raspberry:
wget http://www.pjrc.com/teensy/teensy_raspberrypi.tar.gz
tar -C /usr/share/arduino/hardware/tools -xzvf teensy_raspberrypi.tar.gz

La segunda es la toolchain ncesaria para compilar los sketches para ARM: Raspberry PI Gcc Arm Toolchain
De forma parecida se descarga el .tar.bz2 con wget y luego se descomprime en el directorio /usr/share/arduino/hardware/tools de la raspberry:
wget http://www.pjrc.com/teensy/beta/arm_toolchain_raspberrypi.tar.bz2
tar -C /usr/share/arduino/hardware/tools -xjvf arm_toolchain_raspberrypi.tar.bz2

Para que el sistema operativo reconozca correctamente la placa Teensy hay que añadir a /etc/udev/rules.d el fichero con los descriptores del USB: Teensy.Rules
wget http://www.pjrc.com/teensy/49-teensy.rules
cp 49-teensy.rules /etc/udev/rules.d

Por último son necesarios las librerías y los ejemplos específicos para teensy, pero las distribuciones de estos ficheros solo estan disponibles en forma de ejecutable autoinstalable para sistemas operativos basados en Intel. Como la Raspberry PI usa un procesador ARM no podemos ejecutar ninguno de esos ficheros, aunque esten compilados para Linux. Una solución es instalarlo en una plataforma intel con linux y luego copiar los archivos que ha añadido el instalador a nuestra Raspberry. Al tratarse de ficheros .c, -h, .ino etc no importa que se hayan obtenido de otra plataforma porque ninguno es ejecutable.
He preparado tres tar.gz conteniendo los ficheros que instala teensyduino 1.22 obtenidos de una isntalación bajo Suse Linux.
Primero instalaremos los ejemplos adicionales que incorpora Teensyduino 1.22: examples.tar.gz. Los archivos se colocarán en /usr/share/doc/arduino-core/examples y existe un enlace simbólico a este directorio desde /usr/share/arduino/examples
Los comandos son:
wget http://heli.xbot.es/wp-content/uploads/2015/04/examples.tar.gz
tar -C /usr/share/doc/arduino-core/ -xzvf examples.tar.gz

A continuación las librerías adicionales para las placas teensy, muy interesantes. Aqui incluyo también dos librerías “libarm_cortexM4l_math.a” y “libarm_cortexM0l_math.a” que faltan en la compilación arm_toolchain_raspberrypi.tar.bz2. Aunque estan sacadas de la instalación de linux pueden usarse en la raspberry pi ya que son librerías del tarjet (teensy) no del host (raspberry): hardware.tar.gz
wget http://heli.xbot.es/wp-content/uploads/2015/04/hardware.tar.gz
tar -C /usr/share/arduino/ -xzvf hardware.tar.gz

Por último las modificacines en el core del IDE arduino para incluir las nuevas placas: lib.tar.gz
wget http://heli.xbot.es/wp-content/uploads/2015/04/lib.tar.gz
tar -C /usr/share/arduino/ -xzvf lib.tar.gz

Puede ser necesario borrar el fichero de preferencias en ~/.arduino15/preferences.txt si el IDE arduino comienza a cargar y se cierra de forma inesperada:
rm .arduino15/preferences.txt

Todo listo, si conectamos la placa teensy 3.1 al USB de la raspberry aparecerá el correspondiente puerto serie en herramientas->puertos. Si no es asi podría ser algún problema con /etc/udev/rules.d
Seleccionamos la placa en placa->teensy 3.1, cargamos el sketch de prueba desde Archivo->ejemplos->Blink y lo compilamos de la misma forma que antes. Ahora deberá abrirse el downloader “teensy”. En la ventana de estado se mostrarán algunos errores de compilación pero no hay que preocuparse: posiblemente no sean errores de compilación sino errores que genera el downloader “teensy” al abrirse. Despues de revisarlos y asegurarse de que no hay problemas en la compilación el programa se cargará en la placa teensy 3.1 pulsando el botón download y luego reset.

Raspberry y Teensy 3.1

También pueden usarse las dos placas a la vez….

Raspberry PI, Arduino UNO y Teensy 3.1

Usando un display indocumentado de DealExtreme YL-3 con drivers 595

Hace una semana compré unos displays de LED de 7 segmentos, de 8 dígitos, en DealExtreme pensando en un visualizador de coordenadas para un CNC.

Display YL-3

El sdisplay se suministra sin documentación esquema ni nada. En la serigrafía de la placa solo aparece el texto “YL-3” por lo que yo llamaré a este display así. No he sido capaz de encontrar informacion acerca de su uso, esquemas, ni nada. Tendré que hacer yo mismo el esquema y el código para su uso.

Un poco de ingenieria inversa:

En primer lugar será necesario el esquema para poder empezar a escribir el código que lo haga funcionar. Lo primero es buscar la documentación de los elementos que usa el display para saber or donde empezar a trazar el esquema.
Este modelo usa drivers HC595 que son simples registros de desplazamiento con latches de salida. De esta forma los datos desplazados no aparecen en la salida hasta que se activa el latch y se evita imagen fantasma en el display. Es curioso pero el sn74hc595 común es un registro de desplazamiento con salidas TTL, no adecuadas para encender LED, pero existen versiones de alta corriente de salida que son las que se usan aquí.
Los dos displays de 4 dígitos por 7 segmentos y punto decimal estan marcados “3461BS” y tampoco he encontrado un esquema, con el SuperProbe en modo prueba de diodos voy averiguanduando su conexionado. Están conectados los ánodos en común.
Por suerte en la placa esta serigrafiada la utilidad de los terminales de conexión y es facil seguir con el tester de continuidad el esquema.

Esquema YL-3

Ademas voy a probarlo con un Teensy 3.1 en lugar de usar un arduino convencional.

Solo son necesarios 5 cables, dos de alimentación, un clock, un data y un estrobe. Este es el montaje de pruebas, con una tarjeta SD para apreciar el tamaño de los componentes:

Prueba Teensy 3.1 + YL-3

El display trabaja multiplexado ya que los LED estan conectados en forma de matriz de 8×8.
Este es el código que uso: YL-3.RAR
El .rar contiene una libreria “hc595x2” para colocar en el directorio “libraries” de arduino y un sketch “Test_hc595x2″ para compilar y probar el display (para Teensy 3.1, no lo he probado con otros arduino).
El programa acepta caracteres ASCII por el puerto serie virtual USB y los visualiza en el display, también algunos símbolos y algunos caracteres de control.
Los caractres aceptados son:
Números 0-9, letras minúsculas a-z y letras mayúsculas A-Z.
Letra ñ (ASCII 209 ó 241)
Espacio en blanco ” “, guión “-“, guión bajo “_”, barra “/”, grado “º” ASCII 186, punto “.”, coma “,” (los dos encienden el punto decimal y no avanza el cursor), comilla “‘” ASCII 39 y comillas “”” ASCII 34.

Los códigos de control son:
Retroceso (Backspace) CTRL-H ASCII 8, retorno del carro (retorno del cursor al inicio del display) CTRL-M ASCII 13, Delete ASCII 127, Limpiar el display y retorno del cursor CTRL-J ASCII 10.

Mejor revisar el código para ver las funciones…

Otro detalle, el entorno arduino 1.0.5 se cuelga si en el nombre del archivo hay un guión: “test yl-3.ino” lo cuelga, “test yl_3.ino” funciona bien…

Asi funciona:

El display es muy barato y brillante, y no es dificil usarlo aunque el micro tenga que hacer el multiplexado no es mucha carga de trabajo.
Me comentan en el foro de ARDE que se pueden encontrar unos displays muy similares en EBAY con un enlace a su esquema en PDF.

Mini curso de ingenieria inversa 1

Mientras que la ingeniería convencional nos permite diseñar un producto pasando por su un diseño práctico a partir de una idea, la ingenieria inversa (reverse engineering) sirve para realizar el trabajo a la inversa: partiendo de un producto (un chisme que tienes sobre la mesa) obtenemos su diseño práctico (el esquema eléctrico, sus especificaciones técnicas, incluso su programa interno) y podemos llegar a la idea original.
La ingeniería inversa no es una cosa que se estudie de forma reglada, pero es facil de aprender si tienes unos buenos conocimientos de ingeniería convencional. Yo voy a hablar un poquito de la ingeniería inversa de dispositivos electrónicos. Para poder entender los conceptos será necesario tener buenos conocimientos de electricidad y electrónica.

La necesidad: ¿Por que razón vamos a usar ingeniería inversa sobre un dispositivo electrónico? Hay muchas, la principal es no tener la información técnica necesaria para su uso o reparación. También podemos desear mejorarlo, copiarlo, o anular alguna función no deseada. Para realizar cualquiera de estas operaciones primero necesitamos tener el esquema eléctrico del dispositivo. Encontrar la polaridad de la clavija del gadget recién comprado para acoplarle un alimentador es ingeniería inversa básica.

Las herramientas: Para hacer un análisis pasivo (sin alimentar) solo necesitaremos una buena fuente de luz difusa para que no haga sombras, una lupa (sobre todo para circuitos SMD), un medidor de continuidad (un SuperProbe?) y un polímetro.
Por supuesto papel y lapiz. Si, lápiz, habrá que borrar mucho…
Para anlalisis activos (con el circuito alimentado) o para analizar protocolos etc serán necesarias otras herramientas mas sofisticadas, osciloscopio, analizador lógico etc…

Un caso práctico:
He comprado recientemente en DealExtreme este reloj-voltímetro-termómetro: http://dx.com/p/c-022-3-in-1-red-digital-led-voltmeter-thermometer-clock-223786 por solo 4,38€.
El chisme es interesante y barato pero, como ya avisan en DX, viene sin manual. Googleando su modelo “C-022” no aparece nada, ni por “dx clock voltmeter” etc. Estoy solo con el circuito. Conectarlo no es dificil: un + y un – serigrafiados en la PCB.
Sin embargo solo mide de 7V a 15V de la propia tensión con que se alimenta. Me gustaría medir otra tensión distinta… ¿Como lo hago?. ¿Y si quiero medir una temperatura remota?.
Necesito su esquema eléctrico. La terea no es demasiado dificil, es una pequeña PCB con un integrado TSSOP20 y otro SO8, una batería, un display de 4 dígitos y algunos componentes mas…
Reloj-voltimetro-termometro C-022
Empezamos
Primero: Identificar los componentes, si la PCB es de 2, 4 o 6 capas (cuantas mas capas mas dificil, sobre todo si tiene vias ciegas, entonces la cosa se complica muchísimo y habría que usar otras herraientas…), los conectores etc.
Segundo: hay que identificar bloques funcionales, para cada uno de ellos usaremos distintos métodos deductivos para obtener el esquema. No nos basta con el esquema simple, tenemos que identificar polaridades, tipos de señales etc.

Bloques C-022

Alimentación Es el mejor bloque funcional por el que empezar. Para ello comenzaremos por identificar el conector de alimentación… si no es fácil de identificar (por ejemplo porque se alimenta desde un conector múltiple) buscaremos un plano de masa y a partir de él identificaremos la MASA del circuito. Las pistas de alimentación suelen ser gruesas gruesas, pero pueden confundirse con señales de potencia. También suelen estar desacopladas con condensadores polarizados y filtradas con bobinas de pocos microhenrios y alta corriente. Generalmente la alimentación “bruta” suele acabar en distintos reguladores de tensión. Los condensadores polarizados suelen tener el negativo a masa (cuidado con las fuentes negativas!!). Vamos siguiendo con el medidor de continuidad desde el supuesto positivo de la alimentación (uno de los dos pines de alimentación) hasta el regulador de tensión.
Observamos que hay un par de resistencias conectadas a la alimentación sin regular. Posiblemente es el divisor resistivo para medir la alimentación en la función voltímetro.
Procesador. En este caso no tenemos identificación del procesador, nos limitamos a dibujar el cableado entre el procesador y los pulsadores, el display y el chip SO8 que hay bajo la batería que es el RTC (DS1302).
Observamos otro divisor resistivo, este usa un extraño componente en forma de gota. Se trata de una termoresistencia (al medirla da 5K a 20ºC). Posiblemente se trate del sensor de temperatura para la función termómetro.
La batería está conectada con el RTC DS1302. Podemos decargar el datasheet: DS1302.pdf El cilindro metálico de la derecha será el cristal de 32.768Khz y los dos chips SMD los condensadores del circuito oscilador.
Este es el borrador del esquema obtenido:
Borrador-Esquema C-022
Puede mejorarse un poco:
Esquema KiCad C-022
Ahora vamos a hacer un poco de magia googleiana. ¿Es posible identificar el procesador? Seria muy interesante para poder reprogramarlo…
¿Que sabemos de él? Sabemos que se alimenta por los pines 7- y 9+. También tiene unos condensadore entre los pines 4 y 8 y masa… y su encapsulado es TSSOP20. Vamos a buscar en google microcomputadores o microcontroladores en TSSOP20 a ver que sale.
Ya tengo varios candidatos: MC9S085F4, 87LPC76, PIC16F6xx, MSP430, ATTYNY87167, MSP430G2 y STM85S103F.
Comparando el cableado del borrador con las datasheets de los micros anteriores no queda duda: es un STM8S103F:
STM85S103F
Todo coincide, la alimentación, los condensadores a masa son uno para el reset y otro para el regulador interno, los dos divisores encontrados estan conectados a dos entradas analógicas…
Faltaría conectarlo a un grabador para ver si lo identifica… Desgraciadamente mi grabador, que soporta mas de 10.000 dispositivos, necesita un accesorio para este micro, que no tengo… (también es mala suerte!!).
Al menos al tener identificadas las entradas de tensión y temperatura ya podemos hacer un análisis activo para ver el escalado de estas entradas y poder usarlas de otra manera.
Eso para otro día.

PLC en Raspberry PI: classicladder

El proyecto “classicladder” consiste en un PLC (en inglés Programmable Logic Controller, autómata programable o solo autómata en español) programable en ladder (diagrama de contactos en español) o en grafcet. También integra un entorno de monitorización y comunicaciones, incluyendo MODBUS para las entradas y salidas. Esta escrito en C y usa el entorno GTK+2, puede compilarse para Windows y para Linux.
El autor de este programa es Marc Le Douarain, yo he hecho pequeñas contribuciones: https://sites.google.com/site/classicladder/
El software interpreta el programa, al contrario que otros PLCs que ejecutan código compilado en un PLC virtual, y es totalmente funcional. Es posible ejecutar el software en una máquina sin entorno gráfico y controlarlo desde otra con entorno gráfico mediante comunicaciones (tcp/ip o serie).
Compilarlo para Raspberry pi no debería ser dificil, corre un linux.

Trabajando en la propia raspberry pi con conexión a internet, primero descargamos los fuentes en C de la última versión a 18/2/2013 classicladder 0.9.6 desde el directorio de usuario PI:
“wget http://sourceforge.net/projects/classicladder/files/classicladder/classicladder-0.9.006.tar.gz”
Y lo descomprimimos con:
“tar -xvzf classicladder-0.9.006.tar.gz”
Esto crea el arbol de diecorios en ~/classicladder, ahora cambiamos los permisos de los ficheros, por seguridad.
Entrar en el directorio:
“cd “~/classicladder/projects_examples”
y hacer
“chmod 644 *”
Salir al directorio “~/classicladder”:
“cd ..”
y hacer:
“chmod 644 *”
“chmod 755 projects_examples”

Ya tenemos todos os fuentes listos.
Ahora podemos compilar el software CON o SIN entorno gráfico. Si lo hacemos sin entorno gráfico no podremos controlar el PLC classicladder si no es comunicándolo con otro classicladder que si tenga entorno gráfico.

Para compilar con entorno gráfico es necesario instalar las librerías del entorno GTK+2:
“sudo apt-get install libgtk2.0-dev”

Ya esta todo listo, compilar simplemente ejecutando make desde el directorio de los fuentes, el makefile que acompaña al royecto ya esta configurado para linux y funcionará perfectamente en la raspberry pi:
“cd “~/classicladder”
“make”
Esto habrá creado un fichero ejecutable “classicladder”. Ya podemos probarlo ejecutarlo “./classicladder”. Se desplegrán varias ventanas y podremos ver el estado del PLC…:

Escritorio de raspberry con classicladder

Podemos salvar esta versión del ejecutable con entorno gráfico con otro nombre:
“cp classicladder classicladder_gtk”

Para compilarlo SIN entorno gráfico y usarlo como aplicación embebida, mucho mas ligero (la aplicación gráfica con GTK+2 consume bastante CPU de la raspberry), hay que modificar un para de cosas en el fichero “Makefile”:

Comentar la siguiente línea:
“GTK_INTERFACE = 1” -> “#GTK_INTERFACE = 1”
Esto le dice al makefile que compile el proyecto SIN entorno gráfico.
Comentar las siguientes líneas:
“OWN_CFLAGS = -march=i486” -> “#OWN_CFLAGS= -march=i486”
“OWN_LIBS = -march=i486” -> “#OWN_LIBS = -march=i486”
Estas líneas son específicas para entornos intel x86, nosotros vamos a compilarlo para ARM.
Salvar el fichero modificado, hacer:
“make clean”
para limpiar cualquier compilación anterior y compilar de nuevo con:
“make”
Se habrá creado un nuevo ejecutable “classicladder”.

Para que funcione correctamente en modo embebido SIN entorno gráfico hay que crear un directorio donde se almacenarán los programas recibidos y donde classicladder buscará para cargar automáticamente el programa en el arranque:
“cd /usr/local”
“md classicladder”
Esto creará un directorio “/usr/local/classicladder”

Ejecutar classicladder desde el directorio donde se creó:
“cd ~/classicladder/
“./classicladder”
Podremos ver una serie de mensajes y al final “SOCKET WAITING”. Este será el PLC tarjet y ya esta funcionando y esperando órdenes. Ahora podremos comunicarnos con este PLC desde otra máquina con entorno gráfico.
Conectar la red a la raspberry y hacer “ifconfig” para ver su IP, si no la hemos anotado cuando arrancó.
En otro PC o raspberry arrancar el classicladder con entorno gráfico.
Cargar un programa con File->Load
Transferirlo al PLC tarjet con PLC->FileTransfer->Send Current Project To Tarjet y poner la IP del PLC tarjet (la raspberry pi).
Una vez que el PLC tarjet tenga el programa cargado arrancará en RUN cada vez que arranquemos classicladder en la raspberry pi.
Ahora podremos hacer PLC->Connect y poner la IP del PLC tarjet para monitorizar el estado y las variables del PLC. También podemos pararlo etc.

Podrá verse en el PLC tarjet distintos mensajes durante la recepción de datos.
Si todo va bién el programa recibido se grabará en “/usr/local/classicladder/nombredelprograma.clprjz”

CONECTANDOLO CON EL MUNDO REAL
Vale, esto es muy bonito, pero ¿y controlar directamente entradas y salidas reales desde la reaspberry pi y classicladder?. En principio basta con conectar el puerto serie de la raspberry, en el conector P1 pines 6(GND), 8(TXD) y 10(RXD) a cualquier dispositivo que use protocolo MODBUS (con el adaptador de nivel adecuado, la raspberry pi usa TTL a 3,3V).
Se puede usar un módulo IO MODBUS el propio autor del programa Marc Le Douarain: https://sites.google.com/site/classicladder/classicladder_io_module
También se pueden usar módulos ADAM de Advantech: http://www.advantech.es/producto/adquisicion-de-datos/data-acquisition-modules

Los pines tienen dos nombres: uno el original del chip (broadcom) y otro el que da el sistema operativo (raspberry pi):
Pines GPIO

¿Y por que no usar los pines GPIO directamente?. Son pocos, y puede que nos interese usarlos para mas cosas… pero como hace años ya diseñé una placa de ampliación de I/O (SIO) basada en registros de desplazamiento voy a revivirla y usarla aquí!!!!
Esta es el esquema adaptado a la raspberry pi, hay que conectar 8 hilos del conector P1 (6 señales y dos de alimentación) y listo.:

Esquema Shifted Input Output
Esquemas Eagle: http://heli.xbot.es/wp-content/uploads/2014/01/Raspberry_SIO.zip

La placa de registros de desplazamiento queda alimentada desde la raspberry pi. Ahora hay que modificar classicladder para que use este hardware. Hay varias formas de usar los GPIOs de la raspberry pi:
Mediante el sistema de archivos virtual “/sys/class/gpio”
Usando una librería como: http://www.open.com.au/mikem/bcm2835.
Accediendo directamente al hardware, esta es la que yo usaré: http://elinux.org/RPi_Low-level_peripherals#GPIO_Driving_Example_.28C.29
Despues de escribir el código mostrado y hacer unas pruebas veo que puedo escribir en los puertos sin problemas. Pero ¿y leer?. No hay ninguna función para leer los puertos en el ejemplo… Busco la datasheet del chip bcm2835 y busco el periférico GPIO. Perfecto en el apartado 6.1 (página 90), describe las direcciones de memoria donde estan mapeados los GPIOs, los pines se pueden en el offset 34h desde el inicio del mapa de GPIO. Como los accesos a memoria a 32 bit, para acceder a la dirección 34h usaré (gpio+13) porque (13*4) = 53d = 34h
Por lo tanto para leer los 32 GPIOs sería (g es el número de GPIO 0-53, gpio es la dirección base del periférico):
PINS_READ(g) *(gpio+(13+(g*3)) // Lee los 32 bits donde esta incluido el GPIO g
y para leer un pin individual:
PIN_READ(g) (((*(gpio+13)) & 1<< g)==1<< g) // Retorna el estado del GPIO g: 0 or 1 Me ha costado mucho que esto funcione, aunque hay mucha información acerca de la raspberry pi es dificil reunirla de forma consistente. Un problema que me ha hecho perder varias horas picando código y mirando con el osciloscopio es que el pin 13 de P1 (GPIO21 según Broadcom, o GPIO2 según Raspberry pi) en la versión V2 esta conectado a GPIO27 (según broadcom). El sistema operativo de la raspberry lo mapea a GPIO2 igual que en las V1, pero si se accede al hardware y no se usa el sistema operativo hay que tenerlo en cuenta!!! Ahora solo hay que incluir todo lo probado en el fichero "hardware.c" de classicladder y modificar "Makefile" para que se pueda compilar con o sin este hardware experiemental. Mis versiones de Makefile y hardware.c: http://heli.xbot.es/wp-content/uploads/2014/01/Makefile_y_hardware.zip
En Makeile ahora hay dos nuevos switches:
RASPBERRY_PI = 1
Si no se comenta con # al principio compila para raspberry pi.
MAKE_SIO_ACCESS = 1
Si no se comenta con # al principio compila con el hardware experimental SIO, esta opción puede usarse también para windows y para linux en entorno PC usando el puerto paralelo. Es similar a MAKE_IO_ACCESS.
Descargarse mi version desde la raspberry pi en el directorio “~/classicladder”:
“wget http://heli.xbot.es/wp-content/uploads/2014/01/Makefile_y_hardware.zip”
descomprimirla:
“unzip Makefile_y_hardware.zip”
Contestar “yes” cuando nos pregunte que si sobreescribe los ficheros existentes.
Compilarla:
“make”
Ahora para ejecutarla hay que hacerlo como superusuario. Esto es así porque necesita acceder a la menoria física del sistema (para leer y escribir en los GPIOs). Supongo que también funcionaría si el usuario tiene permisos de lectura y escritura sobre el dispositivo “/dev/mem”.
“sudo ./classicladder”
Si alguien esta interesado en inspeccionar el código, las modificaciones hechas en “hardware.c” estan entre las directivas
#if defined (MAKE_SIO_ACCESS) – #endif

Asi se ve la placa SIO con la raspberry pi funcionando:
Esquema Shifted Input Output

CLASSICLADDER CON SIO EN PC
También podemos compilarlo para PC, si comentamos:
#RASPBERRY_PI = 1
en makefile. Si vamos a compilar bajo windows descomentamos:
WINDOWS = 1
Si lo hacemos bajo linux es necesario dejarlo comentado:
#WINDOWS = 1
Para usar el la placa SIO conectada al puerto paralelo hay que poner en “hardware.c” la dirección física del puerto LPT del PC:
#define SIO_PORT 0x378 // Base port for PC hardware LPT1, LPT2=0x278, LPT3=0x3BC
Y usamos este cable para conectar el PC con la placa SIO:

Esquema Shifted Input Output
Esquemas Eagle: http://heli.xbot.es/wp-content/uploads/2014/01/Raspberry_SIO.zip (El fichero contiene los dos esquemas, placa SIO para raspberry pi y cable PC).

El software es experimental, los parámetros de configuración deberían poder modificarse a través de los menús de “config_gtk.c”, y estar definidos en “classicladder.h” en la estructura “infos_gene”, por ejemplo. Pero para comenzar sirve…

He comprobado que con la raspberry pi es muy estable, sin embargo bajo windows se producen glitches periódicos que desactivan las salidas… Bajo linux (suse 12) también, pero en menor medida.
En windows con mas de un procesador va francamente mal, he tenido que incluir código para forzar el proceso en una sola CPU:
SetProcessAffinityMask(GetCurrentProcess(), 1); // Ejecutar solo en la CPU #1
Supongo que estos problemas son debidos al entorno multitarea, este mismo hardware con un micro PIC, atmel o similar y las mismas rutinas funciona perfectamente.

Yo no he usado una placa completa de 32 salidas y 32 entradas, sino una mas pequeña pero con entradas optoaisladas y con relés en las salidas (16 entradas y 8 salidas).

Raspberry PI y arduino UNO

Resulta que me entero en la página de Arduino http://arduino.cc/es/Main/Buy que la tienda de un amigo aquí en Alcalá de Henares (Componentes Escobedos, http://www.electronicaalcala.net) es distribuidora de arduino y voy el martes a comprar uno…
Y no les queda ninguno… cuando me voy a ir desilusionado me dicen: si quieres tenemos una raspberry pi…
Coño!, resulta que tienen una, modelo B Versión 2 (512Mb de ram, 2 Usb, ethernet) y esta esperándome en el expositor… y ademas me prometen que al dia siguiente tendrán un arduino UNO V3 para mí.
Efectivamente, justo el día de San Valentín, tenía mi equipo completo para programar arduinos desde la raspberry pi.
Así empieza esta historia de ¿amor? entre una raspberry pi y un arduino UNO…

Para empezar a trabajar hay que conectar la raspberry e instalar el sistema operativo en la SD. Yo he usado una de 2Gb y el sistema operativo raspbian descargado de http://www.raspberrypi.org/downloads
Concretamente la versión http://downloads.raspberrypi.org/images/raspbian/2013-02-09-wheezy-raspbian/2013-02-09-wheezy-raspbian.zip
Como voy a cargar el sistema operativo en la SD desde Windows necesito el copiador de imágenes http://sourceforge.net/projects/win32diskimager/files/latest/download
Desde mi portatil Acer 5920 he tenido problemas para que me detecte la SD, he tenido que usar una versión vieja del Win32DiskImager.exe, http://learn-gdx.googlecode.com/files/win32diskimager-RELEASE-0.1-r15-win32.zip
Otras versiones pueden encontrarse aquí: http://sourceforge.net/projects/win32diskimager/files/Archive/

Descomprimir la imagen del Raspbian y copiarla a la SD mediante el Win32DiskImager.exe
Conectar la SD en la rasperry y alimentar… Aparece una pantalla de configuración del sistema operativo de la raspberry. Yo he cambiado pocas cosas:

Overscan -> no lo he tocado, disable (por defecto)
Configure_keyboard -> Cambiarlo: Generic 105 (mi caso)
Keyboard layout -> Other -> Spanish -> Spanish
Key to function as AltGr -> Right Alt (AltGr)
Compose Key -> Right Logo Key (mi caso)
Use Control+Alt+Backspace to terminate the X server -> TES
Change_pass: Las raspberry se estan haciendo muy populares y si se usa la con conexion a internet mejor cambiarlo.
Change_locale -> cambiarlo a: es_ES.UTF-8 UTF-8, por defecto viene en_GB_UTF-8 UTF-8
Default Locale for the sysstem enviroment -> es_ES.UTF-8
Change Timezone -> Geographic area -> Europe
Time Zone -> Madrid
Memory Split -> No lo he tocado, 64 (por defecto)
Overclock -> No lo he tocado.
ssh -> Enable. Opción muy interesante!!!
boot_behaviour -> no lo he tocado, por defecto: NO (Me gusta mas que arranque en linea de comandos, luego puedo arrancar el entorno gráfico con startx).
update -> Si, como ya tengo la conexión a internet lista por cable actualizo ahora el sistema…
Expand_rootfs
Finish

Se reinicia el sistema y aparecerá el prompt. Nos logeamos como usuario “pi”, el password por defecto es “raspberry”, si no lo hemos cambiado antes:
Pi puede hacer sudo sin password, es la mejor opción en vez de usar el usuario root.
El superusuario root no tiene password por defecto, mejor ponerlo con “sudo passwd root”.

También podemos actualizar ahora el sistema con “sudo apt-get update”

Este es el entorno de desarrollo minimalista para arduino, basado en raspberry pi:

Estación de trabajo para arduino raspberry con raspberry pi

Para instalar el entorno arduino basta con hacer “sudo apt-get install arduino”. Esto instalará el entorno versión 1.0.1 (a fecha 14/2/2013) y todos los paquetes necesarios, java, compilador avr-gcc etc.
También pueden instalarse los paquetes por separado, o actualizar alguno de forma independiente (con :”sudo apt-get install paquete” o “sudo apt-get update paquete”)

avr-libc
libftdi1
avrdude
openjdk-6-jre
librxtx-java

Si falla alguna instalación se puede recuperar con “sudo apt-get install paquete –fix-missing”.

Con esto basta, se crea un acceso directo en el menú de inicio llamado arduino…
Arrancar el entorno gráfico con “startx” y ejecutar arduino. También puede ejecutarse una ventana de terminal, el navegador web…

Escritorio de raspberry con arduino

He usado un viejo teclado multimedia que tiene un hub con dos USB, de forma que el teclado, el ratón y el arduino solo me consumen un puerto USB y el otro lo tengo disponible para el pendrive de intercambio de datos…

Puede verse que he instalado un par de programas adicionales, el MC (soy de la vieja escuela y para trabajar desde terminal me gusta ese gestor de ficheros):

sudo apt-get install mc

Para usarlo basta con hacer “mc” desde un terminal. Si el terminal es de putty (http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) mejor hacer “mc -a” para que muestre correctamente los caracteres gráficos que componen el dibujo de los paneles.

Otra herramiente que he instalado es un capturador de pantallas scrot:

sudo apt-get install scrot

Desde un terminal, para capturar la pantalla despues de 5 segundos teclear “scrot -d 5”.
Para capturar inmediatamente basta “scrot”

Si queremos la ultima versión del entorno arduino 1.0.3 (a fecha 14/2/2013) podemos descargarla con “wget http://arduino.googlecode.com/files/arduino-1.0.3-linux64.tgz”.
Descomprimirla en el directorio de usuario con “tar zxvf arduino-1.0.3-linux64.tgz”.
La pega es que los binarios vienen compilados para Intel x64 y estamos trabajando con ARM, no nos valen. Eliminamos la carpeta “~/arduino-1.0.3/hardware/tools” de forma que el entorno de programación trabaje con los binarios ya instalados del entorno 1.0.1.
No estan desactualizados, si havemos “avr-gcc -v” desde un terminal veremos que tenemos instalada la versión 4.7.2 que es la última disponible.
También eliminamos de la carpeta “~/arduino-1.0.3/lib” los ficheros “librxtxSerial.so” y “librxtxSerial64.so”, estan compilados también para intel x86 y el entorno 1.0.1 instalado ya nos los proporciona.
Ahora podemos arrancar el entorno 1.0.1 desde el enlace en el menú de inicio o el entorno 1.0.3 esde la carpeta “~/arduino-1.0.3/”. Podemos hacerle un enlace al escritorio llamado “arduino1.0.3” y otro al entorno antiguo “arduino1.0.1”. Es posible usar los dos indistintamente sin interferencias. Hay que tener en cuenta que el compilador y todos los binarios compilados (el entorno esta escrito en java) que se usan son los que se instalaron con la versión 1.0.1, los que hemos descargado con la versión 1.0.3 los hemos borrado anteriormente porque estan compilados para intel x86.

Al conectar el arduino, en mi caso el UNO V3, el entorno detecta automáticamente y nos añade el puerto “/dev/ttyACM0” a la lista de puertos disponibles.

Aunque el entorno arduino es un poco pesado para la raspberry pi a (ARM11 a 700Mhz, 512Mb Ram) funciona perfectamente y no es necesario un PC para programar arduinos!!

Super Probe Plus: Sencillo multitester con PIc y 20 funciones

Rebuscando por la red encontré hace tiempo el SuperProbe aquí: http://mondo-technology.com/super.html
El diseño original con firmware V38 cuenta con 18 funciones. Me pareció un proyecto muy sencillo para un aficionado, y muy completo para llevar siempre en la caja de herramientas. El coste del proyecto es de solo unos 15 Euros!!
Usando partes del código original y otras escritas por mi he creado este clon con 20 funciones.
La única diferencia con el SuperProbe original es que el SuperProbePlus lleva intercambiadas entre si las resistencias R13 y R14 de 150 Ohmios y 100K. Esto es necesario para usar el generador de tensión de referencia interno del PIC a través del pin 4 (RA2) y dejar libre el pin 17 (RC6). Este pin antes se usaba para crear un divisor resistivo y generar 2.5 V para la detección de nivel flotante en el probador lógico. Ahora se usa para detectar el estado del nuevo selector de voltaje alto (25V) – bajo (5V). Permutando estas dos resistencias puede usarse mi código en un SuperProbe original. Si no se usa el conmutador del selector de voltaje alto – bajo poner el pin 17 (RC6) a nivel bajo (masa).
Opcionalmente puede conectarse un altavoz sustitución de la resistencia de 150 Ohmios y, prescindiendo de la generación de señal NTSC que necesita esa resistencia, tener un zumbador para medir cotinuidad.

Esquema Super Probe Plus 1.1

Las mejoras sobre el SuperProbe original son muchas:

Prob: nuevos modos
Puls: nuevas frecuencias y calibración exacta.
Voll: Calibración exacta y filtrado.
Diod: Salida de 10mA al pulsar PB1 para encender LED.
Ohms: Nuevo modo.
Cap: Mejorada la precisión.
Coil: Ahora solo inicia medida al pulsar PB1 para evitar bloqueo al entrar en el modo.
Freq: Calibrado exacto, nuevo modo RPM.
Cnt: Mejorada la visualización low-all.
Sig: Calibrado exacto.
Ser: Nuevas velocidades y modo auto.
rc.ou: repetición de los pulsos exacta a 50hz.
rc.in: Nuevo modo.
[]: Nueva forma de cambiar frecuencia, calibración exacta a 1Hz.
ir.ou: Nuevas frecuencias.
stop: ahora trabaja en milisegundos y formato h:mm:ss:nnn

Además ahora el programa fuente compatible con MPLAB esta mejor comentado y es mas versatil. Usando las directivas #define puede configurarse para distintas versiones de hardware y con distintas funciones.
Los datos de calibración y escalado se guardan en EEPROM de forma que es posible cambiarlos sin reprogramar el IC, por ejemplo para usar un divisor de tensión distinto.
Usando el regulador LP2950 se mejora la precisión analógica hasta 1,5%, bastante mejor del 5% del LM28L05 o del LM2931. El consumo es de alrededor de 40mA a 9V con multiplexado 1:32 (el original) ó 75mA a 9V con multiplexado 4:32 (usando transistores, da mas brillo y menos parpadeo).

Este es el manual del Super Probe Plus V42:

A fecha 8 de Marzo de 2012 he actualizado algunos errores y POR FIN HAY PCB!!

SuperProbe2

En el siguiente RAR hay: Fuentes para MPASM, esquema con Eagle, ficheros .ps listos para imprimir y “planchar” la placa, lista de componentes con los precios y códigos de RS etc.
He ensamblado dos versiones lista para usar, sin transistores para displays de ánodo común, una con generador NTSC y otra con zumbador en medición de continuidad. Cambiando los defines adecuados en el código fuente puede compilarse con o sin transistores, para displays de ánodo o cátodo común, con generador de señal o no y con ntsc o zumbador.

Descargar todos los ficheros del proyecto.

Esquema Super Probe Plus 1.1

Galeria de fotos de SuperProbe

LaserGame V4.1 Alfa, esquemas y fuentes

Atención estos son esquemas V4.1 y fuentes V4.5 en estado ALFA, aunque son totalmente operativos quizás tengan algunos fallos no descubiertos. Todavía queda algo de trabajito…

Actualizado 27/07/2011, efectivamente, en un solo día, ANONIMO me ha comentado que tengo invertida la alimentación del PIC en los esquemas. Un error de principiante, al pasar a limpio los borradores, que ya he corregido.
El circuito principal, que va montado en el arma, lleva incluido el convertidor DC-DC. Un fallo conocido es que no puede usarse el ICSP mientras la salida del convertidor DC-DC está conectada al circuito. La solución es sacar el jumper JP1 entre la salida del convertidor DC-DC y la alimentación de circuito (+5V) para usar el ICSP.
Aunque no he diseñado todavía el circuito impreso hay que tener mucho cuidado con el diseño de pistas de la parte analógica de Q7 y los componentes asociados, ya que es muy sensible al ruido eléctrico. La conexión del fototransistor en P8 ha de ser con cable apantallado. La ganancia del circuito esta programada a 250 y es muy justo teniendo en cuenta el margen de BETA de los BC547B-BC847B. Mejor usar BC547C-BC847C que tienen mas BETA. He observado diferencias de sensibiliad entre varios prototipos y podría deberse a esto.
Esquema principal

Este es el esquema de cableado de los elementos externos del LaserGame. Las memorias I2C son opcionales, no soportadas por el firmware V4.5.
Esquema de cableado

Ese es el esquema de los sensores I2C. A cada sensor se le asigna una dirección mediante los jumper JP0-JP3. Un fallo conocido es que no puede usarse el ICSP mientras haya alguno de estos puentes instalados. Pueden usarse hasta 8 sensores simultáneos con cada arma, y cada sensor dispone de hasta 4 fototransistores para aumentar la superficie sensible al láser. Igual que en el esquema principal la parte analógica es muy delicada, hay que usar cables apantallados y un buen diseño de pistas para los fototransistores. El bloque “modulador emisor” es opcional, normalmente los sensores no lo usarán pero podría ser útil en versiones posteriores del firmware.
Esquema de los sensores

Fuentes de la versión V4.5 de firmware para hardware V4.1, para placa principal y sensores, junto con el programa para PC de configuración.

Esquemas con KiCad de la versión V4.1 del hardware (compatible con el firmware V4.5)

Como puede verse en los esquemas el conjunto es muy sencillo, teniendo en cuenta todas las funciones que realiza. Los componentes mas caros son la PCB (no diseñada todavía) el display 2,17€ en Farnell y el laser 4€ en dealextreme.
El ajuste también e sencillo: regular los potenciómetros de 2K hasta que la señal cuadrada en la pata 5 del PLL LM567 sea de 38,5Khz.