26 abril 2017

Raspberry PI + Arduino = TwichDrone

Introducción

English readers note: This blog entry in written in spanish, but I provide a "README_ENGLISH.txt" with the installation procedure in english. Also see the section "For the Impatient" to learn how to boot the Raspberry with the custom image. For any question, feel free of contact me.  See the video of the drone working at the bottom of the page.

Si quieres saltarte todo el rollo y tener el drone funcionando lo antes posible vete a la sección "For the Impatient" está en inglés, pero se entiende bien. Aunque recomiendo que te leas todo y hagas una instalación desde cero. Puedes ver el video del drone funcionando al final de la entrada.

Pues llevaba un tiempo intentando integrar una raspberry pi, con un arduino... y dado que llevo un tiempo jugando a RainbowSix, pues pensé ... y por qué no hacemos un drone de esos que usan los personajes para buscar la posición ? así que decidí empezar el proyecto ... TwichDrone!. Para los que no hayan jugado a RainbowSix, lo explico brevemente: los jugadores cuando atacan tienen una fase inicial para localizar el objetivo, y utilizan unos coches radiocontrol para localizarlo. Para manejarlo unan un dispositivo móvil que bien podría ser un teléfono o un tablet. Twich (uno de los personajes) tiene uno un poco especial que lanza descargas con un taser.  Esta es la pinta que tiene en el juego:



Evidentemente, el drone no va a dar descargas (porque tampoco me he puesto, las cosas como son, jeje). La pinta que tiene  físicamente es esta, para que os hagáis una idea de lo que quiero implementar:

El Drone de Twich "de verdad"

Como veis en el modelo, el drone se impulsa con dos motores y tiene ruedas que le permiten desplazarse lateralmente. También tiene unos leds "infrarrojos" y un sistema de cámaras. En mi implementación no voy a usar este tipo de ruedas, porque son muy caras y la idea es que sea barato de construir. Por otro lado, no vamos a usar tampoco los iluminadores infrarrojos (aunque hubiera sido sencillo meter unos leds). Y por supuesto, no da descargas eléctricas.

Nuestro TwichDrone. Close enough!

For the Impatient

This section explains you how to get your TwichDrone up and running quickly. I recommend you that read all the documentation, if you're english reader, start with README_ENGLISH.txt file. If you're brave enough, let's start. Remember you need: Arduino UNO, Raspberry Pi 3 Model B, 2 DC motors, and a battery. Optional a GoPro3.

1. Configure ARDUINO.

You need to install Nanpy Firmware in your arduino. Follow these steps:

  1. Download ARDUINO IDE for your platform. Install it.
  2. Download the Nanpy code and prepare the sketch. Issue these commands.
  3. git clone https://github.com/nanpy/nanpy-firmware.git
    cd nanpy-firmware
    cp sample_cfg.h Nanpy/cfg.sh
  4. Connect the Arduino UNO via USB to your computer. If using a "clone" with a CH340/CH341 usb2serial, see the blog for the required drivers for your platform (Linux works, mac & windows need drivers).
  5. Copy Nanpy directory under your "sketchbook" Arduino IDE directory, start your Arduino IDE, open Sketchbook/Nanpy, select the right board (Arduino UNO) and "Upload". Done.
2. Mount the hardware.
  1. See below "Diagrama de Bloques"
  2. See below "Parte III. Montaje Hardware"
You should mount the motors with the right polarity (see photos) and build a custom wiring to power the raspberry. Then, mount everything into the desired platform, connect all the things.

3. Download raspberry image.

I prepare a ready to run image for the raspberry, with everything working. Just download the TwichDrone_Raspberry_Image to your disk, and burn it into the SD. Yo will ned at least 4.4 GB free, so a 8GB card will do the trick.

Run the following command (check directories and sd device)

gzip -dc TwichDrone_Raspberry.img.gz | dd of=/dev/yoursdcardhere


4. Configure your GOPRO (if you're planning to use it)

The image comes with the following settings:

AP_SSID: TwichDrone01
AP_IP: 192.168.2.1
AP_PASSWD: rainbow6
GOPROWIFI_SSID: GOPROR6
GOPROWIFI_PASSWD: rainbow6


You need to configure the GOPRO3. Go Here and choose a method (via Capture APP or via Web Update). if you don't set the SSID and PASSWD to the given values, the GOPRO3 won't work.

5. Start & Enjoy

Start the raspberry PI3, wait 15-35 seconds to load, and then look for the wifi TwichDrone01 with your portable device (phone/tablet). Login with the given password, and point your browser to the 192.168.2.1. You should be there. Enjoy.

Análisis y Objetivos

Bueno, pues vamos a construir un chisme de estos, a ver si somos capaces. Antes de ponernos a comprar cosas y programar como un loco, lo mejor es definir unos objetivos y establecer un plan de acción, para tener las cosas mas o menos claras. El objetivo de este proyecto de ciencias es construir un drone que cumpla lo siguiente:
  • Barato de implementar
  • Reutilizar al máximo posible lo que tengamos por casa
  • Que se controle mediante un teléfono móvil / tablet
  • Que tenga visión en tiempo real desde el drone (para que se vea como el del juego).
  • Que sea sencillo de realizar.
  • Implementar todo.
Bueno, pues tampoco son tantas cosas. Ahora iremos abordando cada una de ellas, para ver como lo resolvemos. La idea es no gastar mucha pasta en el proyecto, así que vamos a tirar de una plataforma sencilla (nada de comprar un kit rc) y adaptarla para nuestras necesidades. Lo de reutilizar viene al hilo de que tengo una raspberry pi y algún arduino, y me apetece integrarlos juntos. Además tengo una motor shield, así que miel sobre hojuelas. A la hora de controlar el dispositivo me apetece probar a realizar un interface HTML para el control, así de este modo podremos controlar el drone desde casi cualquier dispositivo. Lo que nos lleva a que el enlace tiene que ser WIFI (podría ser bluetooth, pero así es mas sencillo). Para tener una vista en tiempo real, vamos a usar la cámara de la raspberry, y como bonus pack, vamos a montar una gopro  con la que hacer grabaciones chulas. Que sea sencillo. Si tenemos que hacer un desarrollo complejísimo esto pierde gracia. Así que vamos a intentar programar todo en python y HTML (con algo de JS). Y naturalmente, hacerlo todo desde cero teniendo que implementarlo, nada de comprar un kit.

Manos a la obra. Diagramas HW & SW.

A grandes rasgos, voy a usar lo siguiente: una raspberry pi 3 que se encargará del control y del interface de la cámara. Un arduino con un motor shield para encargarse de los motores. Una bateria de lipo de 7.4v (2S) junto con un BEC para sacar 5V limpios (alimentación principal), un kit de motores de amazon para arduino de los baratos, y un desarrollo custom en Python para el control de los motores (backend), y otro en HTML + JS para el interface gráfico de control (frontend). Para probarlo todo desarrollaré un simulador en python para ajustar algunas cosillas.


Diagrama de bloques
En la imagen anterior tenemos el diagrama de bloques hardware del Drone. Como podemos ver, la alimentación la tomamos de una batería LIPO 2S, que nos facilita 7.4V. Como este voltaje es muy alto para alimentar la Raspberry, que además es muy sensible, utilizamos un BEC (uBEC) para transformar esos 7.4V en 5V. Estos dispositivos se usan mucho en RC y admiten un rango de entrada de voltaje bastante alto (además con bastante intensidad).  En nuestro caso, hemos utilizado una batería Zippy  Flightmax 1600mAh (2S1P 20C). El BEC usado es un X5Pro de 5V con una carga de salida de 5A (suficiente para esto). Para encender/apagar hemos usado un switch que conmuta la linea positiva. De aqui se saca una linea directa a la alimentación del motorshield (para mover los motores). La salida de 5V alimenta la Raspberry, que a su vez alimentará al arduino (5V) por USB. Es necesario CORTAR el puente "Vin Connect" de la placa motorshield (ver este enlace). De este modo, la alimentación del arduino es independiente de la del motor shield (5V vs 7.4V).

Finalmente, los motores se conectan al motor shield usando los pines correspondientes, como veremos más adelante. La cámara de la raspberry se conecta utilizando la faja nativa al puerto CSI, como veremos. La GoPro se controla mediante Wifi, por eso aparece sin ningún cableado.

Diagrama de bloques de software
Por otro lado está claro que tenemos que meter algo de software para que todo esto funcione. La idea es sencilla; utilizar la Raspberry PI 3 como ordenador principal, y el arduino para el control de motores. Para conectarnos vamos a utilizar WiFi, aprovechando una característica que tiene la Raspberry, y es actuar como AP (Access Point).

Eligiendo el Access Point del TwichDrone


Así que para conectarnos a ella, basta con buscar la WiFi del Drone (TwichDrone01) en nuestro tablet/teléfono y conectarnos. Esto nos asignará una IP dinámica (DHCP) y nos permitirá conectarnos al drone mediante la IP configurada (192.168.2.1). No os pongáis nerviosos que luego vendrá un documento detallado sobre como montar todo esto paso a paso.

Metiendo la ip del drone en el navegador del movil


Bien, una vez conectados a la red del Drone, basta con apuntar el navegador al servidor web (192.168.2.1) desde el cual se cargará el interface HTML que nos permite controlar al drone.

El interface web cargado y funcionando. Si, ese soy yo.

Este interface es bastante sencillo, por un lado, tiene un joystick en la parte inferior derecha que nos permite manejar el drone (adelante, atrás, girar). Un botón en la parte inferior izquierda nos permite activar/desactivar la grabación de la goPro. En la parte superior izquierda tenemos una "consola" que nos muestra el estado del drone (consumo de los motores, estado de la batería de la gopro y si está grabando o no) y finalmente, a pantalla completa se ve la imagen de la cámara de la raspberry, actualizada en tiempo real.

Detalle del log de consola


El interface realiza la comunicación por dos puertos. Por un lado, el estándar HTTP (80) por el que recibe la página web, el "stream" de la imagen y el JavaScript. Por otro lado, usamos el puerto 8000 para abrir una conexión webSocket al servidor de control (controlserver.py) que es el encargado de controlar el drone (a través de controlar el arduino para los motores, y la gopro para activar/desactivar la grabación). Este servidor está implementado en Python, y utiliza un par de librerías, como veremos posteriormente.


Parte I. Configuración de la Raspberry

Lo primero que tenemos que realizar es configurar la Raspberry. Para los más prisillas he generado una imagen de la raspberry del drone que tengo actualmente funcionando, por lo que debería de valer para arrancar y jugar con el drone. Pero para documentarlo todo, lo mejor es realizar la configuración paso por paso para entender como funciona el asunto. Para encontrar los productos necesarios ver la Lista de la Compra más abajo

Lo primero que necesitamos es una Raspberry Pi 3 Model B, con una tarjeta SD con al menos 8 GB.
para instalarla y configurarla, necesitas estas cosillas además:

  • Ratón y teclado USB
  • Un Adaptador de Corriente MiniUSB bueno
  • Un cable HDMI y un monitor.
  • Un cable de red / Wifi (mejor cable de red). 

Si piensas hacerlo todo de golpe y le quieres pinchar ya la cámara, necesitas la Raspberry PI CAM 2.1 (necesaria la segunda versión, porque tiene otro sensor (Soy IMX219 de 8MP) y se gestiona de manera distinta.

1. Grabar la imagen, arrancar la Raspy


La distribución que vamos a usar es la DEBIAN JESSIE (RASPBIAN) que te puedes bajar desde aqui, naturalmente. Yo he usado la que trae el GUI (Pixel) porque es más cómodo, aunque luego lo vamos a deshabilitar. Te descargas la imagen a tu PC, y la grabamos en la tarjeta. Yo estoy en MacOS asi que he usado dd. En linux es similar.

Como tostarla:
  1. Buscas el disco (df -h)   (/dev/disk6s1   3.7Gi  4.1Mi  3.7Gi   1%   0   0  100%   /Volumes/TWICHDRONE)
  2. Lo desmontas:  sudo diskutil unmount /dev/disk6s1
  3. Descomprimes la imagen
  4. Lo tuestas con dd:   sudo dd bs=1m if=2017-03-02-raspbian-jessie.img of=/dev/rdisk6
  5. Conectamos el HDMI, el teclado y el ratón.
  6. Rebotamos y esperamos hasta que salga el prompt (la partición de la tarjeta se reajusta)

Usuario por defecto:    pi (passwd raspberry)
Supersuario (ROOT):  root (no password, usa sudo su -)

En este punto deberías de tener la raspberry arrancada en el escritorio de PIXEL (GUI) sin problemas.

2 Configuración inicial (Red, etc).

La imagen va comprimida para que entre en una tarjeta pequeña (ocupa 4.4 GB) si quieres utilizar todo el espacio disponible de la partición (por ejemplo, porque hayas metido la imagen en una tarjeta de 16GB) hay que expandir el sistema de ficheros. Lanzas estos dos comandos como root, y fuera,  tras rebotar lo tendrás.

raspi-config --expand-rootfs
shutdown -r now

Lo primero que necesitamos es tener una salida a internet operativa. Usa el cable Ethernet para pinchar la raspberry a tu router, o conectala via WiFi. La cosa es poder salir a internet. Mejor el cable, porque vamos a andar trasteando con la WiFi.

Instalamos los siguientes paquetes:

  • apt-get install hdparm
  • apt-get install hostapd dnsmasq
  • apt-get install cmake libjpeg8-dev

Ahora actualizamos el firmware de la raspberry. Tarda unos 10 minutos, no te pongas nervioso.

Lanzamos este comando como root.


Tras actualizar el firmware y rebotar, si lanzamos este comando, veremos que se carga el módulo de la cámara correctamente.

  • # modprobe bcm2835-v4l2

Una vez actualizado el firwmare, nos podemos poner a configurar la red. Recuerda, queremos que la Raspberry funcione como un AP (Access Point) para permitir conectarnos al drone desde el movil/tablet y un cliente WiFi para poder controlar la GoPro (versiones 3, la 4 funciona distinta).

Para ello, tenemos que configurar dnsmasq, los interfaces de red, y el firewall para que haga masquerading. La configuración de red del drone queda como sigue:

  • AP_SSID:            TwichDrone01
  • AP_IP:              192.168.2.1
  • AP_PASSWD:          rainbow6
  • GOPROWIFI_SSID:     GOPROR6
  • GOPROWIFI_PASSWD:   rainbow6

Empezamos a configurar. Descomenta  y edita estas lineas en /etc/dnsmasq.conf

    interface=lo,uap0
    no-dhcp-interface=lo,wlan0
    dhcp-range=192.168.2.100,192.168.2.200,12h

edita /etc/hostapd/hostapd.conf y donde pone la variable mas abajo, mete estos parámetros:

SSID_OF_AP                          = TwichDrone01
SAME_CHANNEL_NUMBER_AS_WIFI_CLIENT  = 1
WIFI_AP_PASS                        = rainbow6

SAME_CHANNEL_NUMBER_AS_WIFI_CLIENT tiene que ser EL MISMO que el canal de la WiFi a la que te quieras conectar, porque si no, no funciona. Mira el canal WIFI con WifiAnalyzer, por ejemplo, para comprobar el canal. En el caso de la gopro es fácil, porque es el 1. (si te quieres conectar a la wifi de tu casa en vez de a la gopro, tienes que poner el mismo número)

    interface=uap0
    ssid=[SSID_OF_AP]
    hw_mode=g
    channel=[SAME_CHANNEL_NUMBER_AS_WIFI_CLIENT]
    macaddr_acl=0
    auth_algs=1
    ignore_broadcast_ssid=0
    wpa=2
    wpa_passphrase=[WIFI_AP_PASS]
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP

Edita y añade esto en el /etc/network/interfaces

    auto uap0
    iface uap0 inet static
    address 192.168.2.1
    netmask 255.255.255.0

Crea un fichero nuevo /usr/local/bin/hostapdstart y añade:

    iw dev wlan0 interface add uap0 type __ap
    service dnsmasq restart
    sysctl net.ipv4.ip_forward=1
    iptables -t nat -A POSTROUTING -s 192.168.2.0/24 ! -d 192.168.2.0/24 -j MASQUERADE
    ifup uap0
    hostapd /etc/hostapd/hostapd.conf

Cambia los permisos de /usr/local/bin/hostapdstart

    chmod 667 /usr/local/bin/hostapdstart

Edita y añade esta linea al  /etc/rc.local

    hostapdstart >1&

Añade esto al fichero  /etc/network/interfaces (quita todas las referencias al adaptador wlan0) y cambia [SSID_OF_NETWORK_TO_CONNECT], [PSK_KEY_OF_NETWORK_TO_CONNECT] con los valores de la red que te interese. (Te puedes conectar a mas redes, pero acuérdate que el canal tiene que ser el mismo).

    auto wlan0
    iface wlan0 inet dhcp
    wpa-ssid [SSID_OF_NETWORK_TO_CONNECT]
    wpa-psk [PSK_KEY_OF_NETWORK_TO_CONNECT]

Reemplaza PSK_KEY_OF_NETWORK_TO_CONNECT con esto:

    SSID_OF_NETWORK_TO_CONNECT: SSID network a conectar (e.g. GOPROWIFI)
    PSK_KEY_OF_NETWORK_TO_CONNECT: wpa_passphrase GOPROWIFI PasswordEnTextoPlano

el comando wpa_passphrase devuelve tres campos. Quédate con el más largo. Algo como esto:
a03133ea3333471b0d33dbd1b2b19233294649968537c35904eb3389a7df65ba (e.g. wpa_passphrase GOPROR6 rainbow6)

Rebotamos la Raspberry, y en este punto, deberías de poder conectarte al TwichDrone mediante su red WiFi. Compruébalo con un teléfono móvil o una tablet. Lo de la GoPro lo vemos ahora mismo:

  1. Arranca la GoPro con la configuracion WIFI seleccionada, y enciende la WiFi (modo remote app)
  2. Rearranca la Raspberry (así comprobamos en el log que se arranca y se conecta bien)
  3. Tras arrancar, deberías de tener la red bien configurada con esta pinta:

    # ifconfig -a
    # en0   -> cable        [Adapter IP: if plugged, DHCP asigned]
    # wlan0 -> GoPro Wifi   [Adapter IP: 10.5.5.x]
    # uap0  -> Ap Wifi      [Adapter IP: 192.168.2.1]

  1. Ahora hacemos ping a la gopro, que siempre tiene la misma IP: ping 10.5.5.9
  2. Podemos comprobar que podemos acceder a su puerto HTTP http://10.5.5.9:8080
  3. De hecho, podemos ver el live stream con un navegador: http://10.5.5.9:8080/live/amba.m3u8

Y con esto tenemos comprobado que podemos acceder a la raspberry como un access point, y que la raspberry accede correctamente como cliente a la WiFi de la GOPRO. Nota sobre la GOPRO: solo funciona con las GOPROs que tengan este tipo de  interface WIFI, es decir, las 3 y las 3+. La 4 funciona de otra manera distinta, así que esto solo funciona con la GOPRO 3 y 3+.

Now, were are going to configure the PI for DEVELOPING. Turn off the gopro for
now, change the WLAN to your WIFI AP, or use a cable to connect (better).

2. Configuración de parámetros de sistema, contraseñas, SSH y RSYNC.

En esta sección configuramos algunos parámetros para que vaya más suave la Raspberry, y configuramos un par de servicios para poder conectarnos a la raspberry bajar ficheros de un modo más cómodo. Ni que decir tiene que si no piensas toquetear nada, lo del SSH y el RSYNC te lo puedes saltar.

Edita el fichero /etc/sysctrl.conf y añade:

    vm.swappiness=15
    vm.vfs_cache_pressure=50
    vm.dirty_background_ratio=15
    vm.dirty_ratio=20
    vm.min_free_kbytes = 16384

Edita  /lib/systemd/system/networking.service.d/network-pre.conf
(Si no lo encuentras créalo, pero debería de estar) y añade:

    [Service]
    TimeoutStartSec=15

De esta manera no espera 60 segundos en buscar una red WiFi en caso de que no la encuentre.

Ahora lanza el script raspi-config y configura las siguientes opciones:

  1. Arrancar el CLI
  2. Configura el teclado en tu idioma (ES)
  3. Autologin to Pi User disabled (que pida login)
  4. Establece la zona horaria (Europe/Madrid, GMT+1)
  5. Habilita estos servicios (deshabilita el resto):  camera, ssh, serial
  6. Cambia el nombre al host a TwichDrone01    
  7. Establece el pais de la Wifi (para el canal)

Ahora vete a la shell y configuramos la password del usuario pi:

        #sudo su -
        #passwd pi [pon rainbow6]

Edita /etc/ssh/sshd_config y añade "UseDNS no". De este modo no se queda "colgado" esperando el login. (resolviendo DNS). Rebota la raspberry, y deberías de poder entrar en la Raspberry.

A partir de aquí, esto es opcional y solo se usa en caso de que vayas a andar subiendo y bajando ficheros a la raspberry.  Básicamente esto sirve para configurar el acceso por ssh con certificado, y que no te pida password (lo que facilita el rsync). Para ello debe de funcionar el acceso SSH, así que pruébalo desde tu equipo antes. Una vez que funcione:

1) En la raspberry hacemos esto:
    #ssh -l pi 192.168.2.1
    Haz login (esto crea el directorio .ssh)

2) En tu equipo de desarrollo:
    #ssh-keygen -t rsa      (passphrase y password vacío)
    #cat .ssh/id_rsa.pub    (copia el contenido)

3) Nos volvemos a la raspberry y hacemos esto:
    # cd .ssh (/home/pi)
    # vi authorized_keys [pega el contenido del .ssh/id_rsa.pub]
   
4) Si probamos en el equipo de desarrollo:
    # ssh -l pi 192.168.0.163 (no debería de pedir contraseña)

3. Resto del Software.

3.1 Instalación del MJPEG-STREAMER

Tras probar con NINGX-RTMP, UVL4, FFMPEG, AVCONV, VLC y GStreamer, encontré que la mejor solución es MJPEG-Streamer. Por que? pues porque necesitamos muy baja latencia y una calidad no demasiado alta de imagen. Las soluciones de streaming puro de video no funcionan porque:
  1. El video en adroid necesita codificarse en WebM o MP4  para verlo dentro del tag video
  2. La latencia es muy alta.
Así que tras múltiples pruebas, acabamos usando MJPEG-STREAMER, que es un fork del MJPEG-STREAMER original que sirve imágenes JPEGS  continuamente. Así que nosotros en el HTML lo que hacemos es usar un tag en vez del tag.

Para instalarlo:

    # apt-get install cmake libjpeg8-dev
    # git clone https://github.com/jacksonliam/mjpg-streamer.git
    # cd mjpg-streamer-experimental
    # make

Tras compilarlo se lanza fácil:

# export LD_LIBRARY_PATH=.
# ./mjpg_streamer -o "output_http.so -w ./www" -i "input_raspicam.so -x 768 -y 432 -fps 25"


3.2. Python WebSockets

Para poder implementar los servicios de control del dron, he usado una implementación de WebSockets para python 2.7. Python3.0 la trae nativa, pero como estábamos usando la 2.7... pues eso.
Utilizo simple-websocket-server, una implementación rápida, ligera y fácil de usar. (ver su github para más detalles). La instalación es bien sencilla:

    #pip install git+https://github.com/dpallot/simple-websocket-server.git

3.3 ControlServer y Simulator

Estos dos programillas en python es lo que he desarrollado para el control de los motores del arduino. Están escritos en Python2.7 y tienen algunas cosas chulas, por ejemplo soporta curvas de mapeo no lineales (potencia y dirección) ajuste del ángulo de giro, etc. Además el controlServer funciona desacoplado de la entrada, lo que permite comprobar el estado con una frecuencia determinada, de forma asíncrona.

El simulator es básicamente una consola en pygame en la que se muestran los diversos parámetros físicos del drone, y nos permiten controlar una simulación desde el interface web. Gracias a este simulador se pudieron optimizar los ángulos de giro, la potencia aplicada, etc. Además permitió escribir el código de control antes de tener montado el drone.


Simulator.py funcionando.
El interface web es bastante sencillo. Se presenta una página web que tiene un tag img de fondo y a través de un poco de javascript y usando la librería NippleJS se capturan los comandos y se mapean al servidor a través de WebSockets.

Lo mejor es que si tenéis curiosidad os deis una vuelta por el código del controlserver.py y el simulator.py.


Parte II. Interface con el Arduino

Para controlar los motores, vamos a utilizar un Arduino Uno con su Motor Shield, que es lo que tenía por casa.

Arduino Uno "clone" con el CH341

 Además, el arduino que vamos a utilizar, es un "clone" que se caracteriza a parte de por ser muy barato, por usar un driver serial basado en el chip CH341, lo que hace que tengamos que instalar un driver en nuestro sistema operativo para poder conectarnos con el arduino. La buena noticia es que en linux y en la raspberry está soportado nativamente, pero en MacOS y en Windows necesitamos el driver. c'est la vie.

Arduino MotorShield R3

El arduino Motor shield que vamos a utilizar es el original, revisión 3. Este shield se monta encima del Arduino y nos permite controlar dos motores DC, o bien uno paso a paso. No tiene mucho misterio. Los motores se conectan en las bornas azules que se ven en la parte inferior izquierda de la foto, junto con su alimentación. Es necesario CORTAR el puente "Vin Connect" de la placa motorshield (ver este enlace). De este modo, la alimentación del arduino es independiente de la del motor shield (5V vs 7.4V). Si no cortamos el puente, freímos el arduino, porque lo vamos a alimentar externamente.

Una vez montado el shield encima del arduino, tenemos que instalar el NanPy en la raspberry Y en el Arduino. Nanpy permite controlar via python todos los componentes del arduino (via puerto serie sobre el USB). Por esta razón, tenemos que descargar el firwmare de NanPy en el arduino.

Lo primero es que si estás en MacOS, necesitas los drivers; El Capitán, Sierra. Si estás en Windows, entonces estos son los tuyos. Los descargas, y los instalas.

En la raspberry no tenemos que hacer nada, porque vienen los paquetes preinstalados. Lo que si tenemos que hacer es poner el firmware en el Arduino, y esto lo podemos hacer desde el equipo de desarrollo.

Lo primero es instalarse el Arduino IDE para tu plataforma. Nos hace falta para compilar el código y descargarlo al arduino. Lo descargas y lo instalas. No lo abras todavía.

Desde una shell, ejecutamos lo siguiente:

git clone https://github.com/nanpy/nanpy-firmware.git
cd nanpy-firmware
cp sample_cfg.h Nanpy/cfg.sh
Ahora conectamos el Arduino UNO via USB al equipo de desarrollo. Comprobamos que funciona el IDE y podemos descargar un sketch sencillo (e.g. blink). Cuando nos hayamos asegurado de que esto funciona, cerramos el IDE y:
  • Copiamos el directory Nanpy al directorio de sketches del Arduino IDE.
  • Arrancamos el Arduino IDE, seleccionamos nuestra placa (Arduino UNO).
  • Abrimos el sketch Nanpy
  • Le damos a "upload". Si todo va bien, ya lo tenemos instalado.


Para montar el drone, lo primero que tenemos que agenciarnos es un recipiente adecuado para meter toda la electrónica. Yo he usado un tupper del mercadona, en concreto de helado. Se puede utilizar la base en la que vienen las ruedas (ver más adelante) o bien un maleta estanca... yo no me quería complicar porque era una prueba. Eso si, el tupper lo pinté en negro, para que quedara más aparente.

La caja
En realidad, el montaje del drone es bastante sencillo, y de lo único que nos tenemos que encargar es de que entren todos los componentes. En mi caso tuve que taladrar la caja para sacar las ruedas y atornillar los motores ya que no usé la pletina que viene con el kit. Aquí cada uno que haga un poco lo que le cuadre. El kit que compré en amazon incluye un portapilas, los motores, las ruedas y una rueda jockey. Como véis en la foto, se puede usar la pletina para realizar el montaje. No quedará tan pintón, pero es más rápido. El portapilas y los cables no los usamos.
Car Kit

El montaje de los motores es importante para encontrar la polaridad correcta. En mi caso, los he puesto de manera que las bornas vayan hacia dentro de la caja, y poder identificar así correctamente el polo positivo y el negativo. En nuestro montaje, el motor B es el izquierdo y el motor A es el derecho.  Es importante establecer esto correctamente porque si no luego el código de control no va a identificar correctamente la polaridad y los motores, y no va a funcionar.

Motor derecho A
Como podéis ver en las fotos la borna superior es la positiva (cable ROJO) y la borna inferior es la negativa (cable NEGRO).

Motor Izquierdo B
Estas bornas van conectadas a las bornas del arduino SHIELD marcadas a tal efecto en la foto. Vamos, el B a las de arriba (marcada como B) y el A a la del medio (marcada como A) respetando la polaridad. El de la parte de abajo del todo (más abajo a la izquierda) es la entrada de corriente.

Conexiones de los motores al arduino shield
El siguiente paso es conectar el arduino con la raspberry, esto es fácil, porque se hace a través del cable USB. De este modo se alimenta el arduino, y se le pasan los comandos de control via serie. Y ya queda poco.

Ahora es el momento de soldar otro rato y crear el sistema de alimentación. Yo he usado una batería LIPO de 2S (7.4V). Para conectarla he usado un conector estándar XT60 (el naranja que se ven las fotos). Como estos conectores son muy duros, he metido un switch que conmuta el positivo para no andar quitando y poniendo el conector. El esquema eléctrico es el siguiente:
Esquema eléctrico.


Acordaros que la alimentación del shield se toma ANTES del UBEC ya que necesitamos 7.4V. El UBEC convierte la tensión a 5V, que es la que usamos para alimentar la Raspberry. Para ello, soldamos la salida del UBEC a un conector MiniUSB macho que en teoría luego se puede meter en su conector. Yo no fui capaz, así que le metí termoretráctil y cola caliente.  Tened cuidado que es delicado.


Como conectar los pines de alimentación al conector MiniUSB.
Y con eso tenemos las conexiones eléctricas. Nos queda conectar el MiniUSB a la raspberry, esta a la cámara (que se hace con la faja CSI, es sencillo pero con cuidadito) y el USB que conecta con el arduino. Al final tiene que quedar algo parecido a esto:

La raspberry con el Switch de encendido, el USB, la cámara y la alimentación

Y esta es la pesadilla de cables que se ve dentro. Como veréis tampoco es para tanto. Se ve elUBEC (perdió la pegatina) y el conector XT60. Lo que se ve azul debajo del UBEC es la batería LIPO.

Cableado interior
Solo nos quedaría encenderlo, conectar el teléfono/tablet a la WiFi del Drone, y apuntar el navegador a la  dirección http://192.168.2.1 Con esto debería de estar funcionando sin problemas.

Si quereís una información más detallada sobre el proceso de instalación a mano, podéis consultar el fichero README_ENGLISH.txt





Lista de la compra

Estos son los componentes principales y donde comprarlos.

08 marzo 2017

Pedales para el Rainbow Six

Rainbow six siege

Llevo unos días dándole al Rainbow Six Siege, y la verdad es que hacía bastante que no me enganchaba a un juego (bueno, quitando el DOOM, que también tuvo lo suyo). Bueno, la cosa es que Rainbow Six (R6, a partir de ahora) es un juego táctico que requiere bastante precisión, rapidez de movimientos, y unas buenas dotes tácticas.



Como se ve cuando te asomas

Uno de las características de este juego (a parte de otras muchas) es el tema de inclinarse. Para no exponer todo el cuerpo al fuego enemigo, es posible "asomarse" a izquierda y derecha, evitando plantarse en medio de la línea de tiro, evitando que te maten. Este movimiento está mapeado por defecto a las teclas 'Q' y 'E', respectivamente.

Justo falta "Lean", pero las opciones son Toggle, o Hold.

El problema que tenemos aquí, es que si te quieres mover e inclinarte, tienes dos opciones: O tienes siete dedos en la mano izquierda (para poder pulsar simultáneamente la 'A' y la 'Q' por ejemplo) o bien, configuras el juego (R6 da esa opción) para que el movimiento se "quede pisado" hasta que vuelvas a dar a la tecla (una pulsación de la 'Q' te inclina a la izquierda, y se queda así hasta que le vuelvas a dar (cambiar/Toogle)). El problema que tiene eso, es que si andas así, vas mas despacio, lo que te convierte en una presa fácil. La otra opción es mantener/Hold, pero te obliga a los siete dedos.

Así que aquí tenemos varias opciones: o configuras la acción en otras teclas (que no tiene mucho sentido, porque hay más acciones que hacer, y no hay tantas teclas libres) o bien... te inventas algo para manejar esas teclas... que es lo que he hecho yo. Básicamente se me ocurrió usar unos "pedales" para inclinarme a cada lado.

Por qué unos pedales? pues porque los pies los tienes libres, son dos acciones con una lateralidad muy marcada (izquierda, derecha) y además tienes dos pies... así que parece una idea razonable.

Manos a la obra

Si miramos por ahí pedales, nos encontramos que todos los que he encontrado son para simuladores de coches, o son para simuladores de vuelo, así que no nos valen, porque son analógicos. Se podrían meter, mapeando el control analógico con el driver... pero es un rollo y bastante lío. Además, no tengo yo claro que R6 soportara mapear unas acciones al teclado y otras a un joystick. Así que queremos algo bonito, barato, fácil de construir, que sea digital y que se use de la manera más sencilla en el PC.


Arduino, partiendo la pana finamente.

Aquí es donde entra Arduino, ya que además tengo un par de ellos por casa. Arduino es una plataforma de desarrollo basada en un diseño hardware OpenSource junto con unas librerías y un toolchain OpenSource, que nos permite realizar montajes hardware de manera sencilla, cómoda, rápida y lo mas importante: barata.

Hay muchos modelos hardware, cada uno con sus especificaciones y sus características, pero el que nos interesa en este caso es el Arduino Micro. y por qué este? pues muy fácil, porque esta plaquita utiliza un microcontrolador ATMega32U4 que tiene entre sus características tener el controlador USB dentro... por lo que puede ser reprogramado... lo que permite al dispositivo comportarse como distintos dispositivos USB de un modo sencillo.

Y que quieres decir con todas esas cosas que no entiendo? pues muy fácil: que podemos programar el Arduino de manera que se comporte como un dispositivo USB. en concreto, como si fuese un TECLADO. Y aquí viene la gracia: Cuando pinchas el Arduino al PC, se comporta como un teclado; cuando pulsas el botón de la izquierda, mandamos una 'Q'. Cuando pulses el botón de la derecha, mandamos una 'E'. Como es un teclado, pues asunto resuelto. Ya tenemos la integración realizada.

Lista de Componentes


  • Arduino Micro. Se puede hacer con un Nano, con un Pro, o con un Teensy, pero en ese caso hay que mirarse la documentación, ver que pines son y ver si soporta el USB integrado en el micro (para que funcione como un teclado). Aquí vamos a usar Arduino Micro, el genuino. 27.79€ en Amazon sin rebuscar mucho.
Arduino Micro. Bueno, Bonito y Barato

    • Un par de botones de arcade, con sus micro interruptores. Son cómodos los convexos (con tripita) ya que los vamos a pisar. Yo uso los de industrias lorenzo, comprados en Factory arcade (2.60€ cada uno con micro interruptor).
    Botón convexo de industrias lorenzo (el clásico)
      • Cables para conectar. Yo he usado una combinación de fastons y pines hembra para hacer los cables. Date cuenta de que son dos botones, así que con cuatro fastons y cuatro pines lo tienes hecho. Se puede también soldar, etc.
      Faston (para el lado del microswitch)
        • Fastons (3.00 €/100 unidades) queda perfecto. Pines (2.69€ /150 unidades) Fundas de plástico (3.00€/100 unidades). OJO: Cuando compres el botón, mira el ancho del microinterruptor para comprar el faston que corresponda (hay de 6.3mm, 4.8mm, etc). El cable cualquier cable finito nos vale.
        El microswitch (microinterruptor) Revisad el ancho (4.8mm o 6.3mm) para los faston
        • Madera para hacer el reposapies. Yo he usado unos retales de DM de 1cm de ancho, que se corta fácil y es resistente. Para pegarlo he usado una pistola de pegamento caliente, y perfecto.
        Conector de 1 PIN para la parte del arduino (plástico y pin por separado)

        • Herramientas (una taladradora para hacer el agujero de los botones, con una broca de corona, y una sierra para cortar la madera).
        • Un cable mini usb para conectar el arduino al PC.

        Para comprar los componentes es casí mas fácil pedir los botones a Factory Arcade (por ejemplo) o reciclar unos viejos, y los conectores comprarlos en una tienda de electrónica local (Conectrol, por ejemplo) o hacer un pedido para tener provisiones, que es barato y se usa bastante.



        Manos a la obra

        Lo primero es hacer el mueble. Para hacerlo, he tirado de un par de retales que tenía por casa de DM de 1cm de grosor. Se puede hacer con cualquier tipo de madera, pero lo ideal es que sea resistente, se mecanice bien y se pueda unir sin mucho lío. En mi caso el DM se que pega bien con pegamento caliente (las tipícas pistolas de barritas) asi que el diseño es sencillo: una plancha en la que realizamos dos taladros para los botones, un lateral para elevarlo a la altura deseada, y un par de pies para darle estabilidad. Cada uno que se la haga a su medida, ya que cada uno se siente cómodo con una altura determinada, etc. También está la opción de usar un reposapiés fabricado y hacerle dos taladros.


        El mueble visto desde arriba
         No hay mucha magia, corto los listones con la sierra manual, hago los agujeros con la taladradora de corona, encolo con la pistola de pegamento caliente ayudado con unos gatos y listo. Para evitar que se deslice (y desliza) le he pegado cuatro patas de esas de goma antideslizante, como puede verse en la siguiente foto. Como veréis, no es muy complicado el bricolage.


        Las patas antidelizantes y el montaje del mueble.

        Cableado

        Ahora hay que cablear el asunto. Una de las gracias que tiene el Arduino Micro es que tiene resistencias de pull up dentro, para las entradas digitales. Estas resistencias lo que hacen es que evitan que se queme el micro, ya que al tener un interruptor, es necesario "tirar" de la corriente mientras se cierra el circuito. Si no tuviera estas resistencias internas, habría que cablearlas entre los botones y el arduino, pero en nuestro caso, no hace falta, así que el montaje es muy sencillo. Los microinterruptores tienen tres patas, la de abajo, NC (2) y NO (4). la de "abajo" es el GROUND y va pinchado al GROUND del Arduino. la NC (también rotulada como 2) es NORMAL CLOSED, y se usa cuando quieres usarlo de manera inversa (que pite cuando se abre). Nosotros queremos que "pite" cuando se cierra, asi que usamos NO (también rotulada como 4).

        Diagrama de conexiones

        Es importante que todos los GND (grounds) sean comunes. Así que como el Arduino tiene dos pines de GND, usamos uno para cada uno, y santas pascuas.

        Los cables los preparamos como sigue: en el lado del Arduino, montamos un conector de pin. Para eso pelamos el cable, crimpamos la parte de metal, y ponemos su fundita de plástico. En el otro extremo (la parte del microinterruptor) metemos la capucha de plástico en el cable, y crimpamos el faston. Listo. Hacemos cuatro de estos, que son los que vamos a necesitar. La longitud del cable es importante, así que ten en cuanta a qué distancia has hecho los taladros y por dónde vas a sacar el cable USB.

        Resumen de los pines:

        • Pin D9 del Arduino al NO (4) del Interruptor de la Izquierda (Q)
        • Pin D8 del Arduino al NO (4) del Interruptor de la Derecha (E)
        • Pin GND de la izquierda al Interruptor E
        • Pin GND de la derecha al Interruptor Q

        Realmente los Pines GND del arduino dan igual como los conectes, pero conéctalos.
        Date cuenta de que los pines del Arduino estan rotulados. D9 es la pata 14 si empezamos a contar en el diagrama del Arduino, por arriba a la izquierda, asi que cuidado con esto que es importante. Recuerda, usamos D9 para la Q y D8 para la E.

        Programación del Arduino

        Aquí viene lo que más asusta, pero lo más fácil de hacer, ya que voy a intentar explicarlo todo de manera sencilla. Lo primero que hay que hacer es bajarse el IDE (herramienta de desarrollo) de Arduino desde aquí. Es la 1.8.1, para tu plataforma. Esto lo he probado en MacOS 1.12 y Windows 7, y funciona sin problemas. Una vez que te lo bajes, lo instalas y lo abres. Te recomendaría que te dieses una vuelta por la web de Arduino y te leyeras los tutoriales, porque están muy bien.

        NO CONECTES EL ARDUINO MICRO VIA USB al PC TODAVÍA.

        Lo primero que vamos a hacer es seleccionar  nuestra placa de desarrollo. Para ello vamos al menú herramientas, placas y seleccionamos "Arduino/Genuino Micro". No te equivoques que esto es importante (por como afecta al bootloader y al toolchain). Tu selecciónalo bien.

        Lo segundo es bajarse la librería Bounce2. Es muy fácil, ya que está integrada en el IDE. Vamos al menú Programa, Incluir Librería, Gestionar Librerías. Ahí buscamos "Bounce2" y le damos a instalar. Sencillísimo. En el vídeo se ve como hacer ambas cosas.

        Ahora cerramos el IDE, conectamos el Arduino, volvemos a abrir el IDE y nos bajamos el código fuente del programa. Para ello nos vamos al repositorio GIT, pinchamos en el botón verde "Clone or Download" y le damos a "Download ZIP". Aquí tienes en enlace directo al código fuente. Cuando lo tengas, descomprímelo, renombra la carpeta r6pedals-master a r6pedals y abre el fichero r6pedals.ino con el IDE de Arduino (doble click en el fichero y lo tienes).

        Probamos que compila sin problemas (Menú Programa, Verificar/Compilar) y si no vemos errores (que no los tendrá) pues lo subimos al Arduino (Menú Programa, Subir). Si no te lo sube, hay que darle un par de veces al reset mientras lo cargas. Esto es porque hay que resetear el micro para que pille el puerto USB como serie (recuerda que tienes todo integrado dentro del microcontrolador).

        Compilado y descargado al Arduino.

        Probamos en un notepad que dando a los botones se escriben las letras Q y E ... y ya lo tenemos hecho. Abrimos Rainbow Six Siege, vamos a la configuración, Controles, buscamos Inclinarse y lo configuramos como Hold (presionar). Y con eso y un bizcocho ... ahí lo tenemos funcionando! A disfrutarlo!.


        Tras una manita de pintura, la cosa queda bastante más chula.

        Ya pintadito.
        Quality Control by Firulais

        Todo correcto!