You Are Browsing ‘Cyberlab’ Category

Proyectos IoT con Raspeberry Pi en contenedores Docker

by tuxotron - on May 23rd 2016 - No Comments


DockerARM.png

Con anterioridad hemos publicado varias entradas dedicadas a proyectos con Raspberry Pi. Dependiendo del proyecto en si y la tecnología que uses, normalmente tienes que instalar ciertas dependencias y/o servicios. Y si por el motivo que sea necesitas tener diferentes versiones de dichas tecnologías, por ejemplo distintas versiones de ruby, python, etc aquello se puede convertir en un pequeño infierno. Para evitar este posible lío y poder fácilmente instalar tus proyectos de forma automática y sencilla, Docker es un perfecto candidato.

También hemos hablado sobre Docker en el pasado y mi afán por familiarizarme con esta tecnología, el uso de contenedores Docker en mi proyectos IoT era algo que tenía pendiente.

En esta entrada voy a describir los pasos que yo personalmente he seguido para hacer uso de contenedores Docker en RPi.

En mi caso he usado un Raspberry Pi 3 y la imagen oficial Raspbian Jessie Lite. Para la instalación de la misma puedes seguir los pasos descritos en la web oficial.

Una vez tienes tu RPi instalado y conectado a internet, ya sea por red inalámbrica o por cable. Lo primero que haremos será actualizar el sistema:

sudo apt-get update
sudo apt-get upgrade

Después de haber hecho esto, lo que haremos será instalar Docker. Recuerda que RPi lleva un procesador ARM y la versión de Docker disponible en los repositorios oficiales de Raspbian es bastante antigua, considerando que Docker, actualmente, saca versiones nuevas con bastante frecuencia.

Los chic@s de hypriot.com (fuente excepcional sobre Docker y RPi) mantienen un repositorio en packagecloud.io con paquetes de Docker engine compilados para ARM, recordemos, que es la arquitectura del procesador que llevan los RPis. Lo primero será instalar  una dependencia de Docker, luego añadir el repositorio de hypriot y finalmente la instalación y activación de Docker:

sudo apt-get install -y apt-transport-https
wget -q https://packagecloud.io/gpg.key -O - | sudo apt-key add -
echo 'deb https://packagecloud.io/Hypriot/Schatzkiste/debian/ jessie main' | sudo tee /etc/apt/sources.list.d/hypriot.list
sudo apt-get update
sudo apt-get install -y docker-engine
sudo systemctl enable docker

Esta entrada está basada en Raspbian Jessie, pero si usas la distribución basada en wheezy, necesitarás cambiar la tercera línea:

echo 'deb https://packagecloud.io/Hypriot/Schatzkiste/debian/ wheezy main' | sudo tee /etc/apt/sources.list.d/hypriot.list

Este proceso te llevará un rato y si todo ha ido bien, puedes comprobar que Docker está corriendo con el comando docker version:


docker-version.png

Lo siguiente será crear nuestro contenedor. Para ello existe una imagen basada en Raspbian.

Yo he creado mi propia imagen, la cual puedes descargar desde hub.docker.com (opcional):

sudo docker pull tuxotron/rpi-python-gpio

Ésta, como decía está basada en Raspbian y además lleva Python (2.7), WiringPi2 (librerías para interactuar con la interfaz GPIO) y el módulo para python RPi.GPIO.

El fichero Dockerfile tiene está pinta:


Dockerfile.png

En realidad no necesitas descargarte dicha imagen (docker pull tuxotron/rpi-python-gpio) y puedes ejecutar el contenedor directamente desde Docker hub con el siguiente comando (la primera vez tarda un buen rato):

sudo docker run --rm -ti --cap-add SYS_RAWIO --device /dev/mem tuxotron/rpi-python-gpio

Dicho comando, si has usado Docker anteriormente quizás veas un par de parámetros que no son comunes. De todas formas vayamos por partes y veamos cual es la función de cada uno de los parámetros.

run: crea y lanza un contenedor.
–rm: este parámetro es perfecto para hacer pruebas. Le indica a Docker que cuando terminemos con el contenedor, lo borre. Si no hacemos esto, los contenedores se quedarán almacenados en disco y por lo tanto ocupando espacio. Siempre los puedes borrar manualmente.

tuxotron/rpi-python-gpio: nombre de la imagen. Docker busca la imagen localmente primero, si no la tienes descargada, la busca por defecto en hub.docker.com

En condiciones normales, estos son los comandos que necesitarías para correr algún servicio en tu RPi dentro de un contenedor. Probablemente añadirías algún puerto y posiblemente algún volumen.

Pero como puedes observar el comando contiene dos parámetros más:

–device /dev/mem y –cap-add SYS_RAWIO

La razón por la que necesitamos estos dos parámetros es por el acceso al interfaz GPIO (si tu contenedor no hace uso del GPIO, puedes ignorar dichos parámetros). Recuerda que un contenedor Docker corre dentro del host de forma aislada y por defecto no tiene acceso a los recursos del éste. El acceso al interfaz GPIO se hace accediendo directamente a la memoria, de ahí que cuando necesitas acceder a este interfaz necesites privilegios de root. Para permitir que el contenedor tenga acceso a la memoria del host, necesitamos especificarlo de forma explícita con:

--device /dev/mem

Además de esto, Docker provee de granularidad fina de permisos, en la que podemos especificar que tipo de operaciones queremos permitir y/o cuales no. En nuestro caso sólo necesitamos SYS_RAWIO (acceso de entrada/salida a los puertos):

--cap-add SYS_RAWIO

También podemos hacer esto con el parámetro –privileged, pero con éste prácticamente damos carta blanca al contenedor para acceder a los recursos del host, así que por motivos de seguridad es mejor sólo asignar los permisos mínimos.

Si todo fue bien durante la ejecución del contenedor, deberías estar en una sesión de bash dentro del mismo. Para comprobar que el acceso al interfaz GPIO funciona propiamente podemos lanzar el comando: gpio readall y deberías ver algo parecido a esto:


gpio_readall.png

Con esto tienes un contenedor con Raspbian Jessie, Python y acceso al interfaz GPIO.

En futuras entradas publicaré algún ejemplo práctico usando como base la información mostrada en esta entrada.

In the meantime happy hacking!

Entradas relacionadas:

Mi show de luces y música de Navidad con Raspberry Pi

by tuxotron - on Ene 18th 2016 - 1 Comment


20151212_141833.jpg

En otro de mis proyectos “juguete” con Raspberry Pi, le di un poco de vida a las luces de esta pasada Navidad y añadí música y sincronización entre estas.

Había querido publicar esta entrada por la época navideña, pero el tiempo no me lo permitió.

Este proyecto es realmente sencillo, ya que vamos a usar lightshow, un proyecto que nos va  a proporcionar la sincronización entre las luces y la música, así que todo el trabajo realmente está en el cableado de nuestros componentes.

En este proyecto usaremos:

  • Raspberry Pi 2
  • Relay SSD de 8 canales
  • 8 enchufes (estos son los enchufes que yo usé, estándar en EEUU. Depende de dónde vivas será distintos, pero la funcionalidad será la misma).
  • Cables: rígido para la interconexión de los enchufes y flexible para el resto.
  • Ficha de empalmes
  • Cinta aislante
  • Altavoz (conectado a la salida analógica del Raspberry Pi)

La idea detrás de este proyecto es que podamos enchufar hasta 8 luces, tocar música y que las luces que enciendan y apaguen al ritmo de ésta.

Lo primero que vamos a hacer es instalar lightshow (asumo que usas Raspbian, aunque el procedimiento debería funcionar en otras distribuciones Linux):

# Actualiza tu sistema
sudo apt-get update
sudo apt-get upgrade
sudo rpi-update

# Instala git
sudo apt-get install git-core

# Clona el repositorio en /home/pi/lightshowpi
cd ~
git clone https://togiles@bitbucket.org/togiles/lightshowpi.git

# Sitúate en la versión estable
cd lightshowpi
git fetch && git checkout stable

# Corre el script de instalación
cd /home/pi/lightshowpi
sudo ./install.sh

# Reinicia
sudo reboot

Durante el proceso de instalación me dio un error cuando el script intentó instalar una de las dependencias: Beautifulsoup. En la versión de Raspbian que usaba, dicha librería había sido renombrada a BS4. Tus opciones aquí son instalarla manualmente (sudo apt-get install python-bs4), modificar el fichero que contiene las dependencias (lightshowPi/install-scripts/raspbian) o simplemente ignorarla. Una de las funcionalidades de lightshow es que te permite interactuar con el mismo a través de SMS (yo no configuré esa parte) y ahí es donde requiere Beutifulsoup para trabajar con unos ficheros XML.

Ahora que ya tenemos instalado nuestro software. Toca empezar a cablear. Lo primero que vamos a hacer es cablear nuetro RPi al relé. Por defecto lightshow asume que el relé está conectado a los 8 primeros GPIO pines (GPIO0 – GPIO7). Si quieres usar una configuración distinta, entonces tienes que modificar el fichero lightshowPi/config/defaults.cfg en la sección [hardware]:

...
# Using 8 pins of GPIO on the pi:
gpio_pins = 0,1,2,3,4,5,6,7
....

Y cambiar esos números por los pines que hayas elegido. Lightshow también nos ofrece la posibilidad de retransmitir nuestra música a través de ondas FM, para la cual usa el pin 7, con lo que si quires usar dicha funcionalidad, tienes que dejar el pin 7 libre (ahí conectarás la antena). Un poco más abajo de la línea mostrada anteriormente tienes:

#
# Using 8 pins of GPIO with FM transmitting on the pi b+:
#pin 7 cannot be used in FM mode because that is used for the antenna
#gpio_pins = 0,1,2,3,4,5,6,21

Cómo ves el pin 7 sería sustituido por el 21. Tendría que de-comentar dicha línea y comentar la anterior de forma que quedaría algo así:

...
# Using 8 pins of GPIO on the pi:
# gpio_pins = 0,1,2,3,4,5,6,7
....
#
# Using 8 pins of GPIO with FM transmitting on the pi b+:
#pin 7 cannot be used in FM mode because that is used for the antenna
gpio_pins = 0,1,2,3,4,5,6,21
...

En mi caso, tampoco usé la función de retransmitir por FM. Así que nos quedaremos con la configuración por defecto usando los GPIO0-GPIO7.

A continuación os dejo el esquema del cableado entre el RPi y el relé:


rpi_relay.png

Rapsberry Pi – Relé


GPIO_Pi2.png

Pines de Raspberry Pi 2

Una vez tenemos nuestros dispositivos cableados, podemos hacer la primera prueba. El relé dispone de un LED por cada canal lo que nos permite visualizar si lo hemos conectado correctamente. Lightshow dispone de un script de prueba que nos permitirá saber si hemos conectado los cables correctamente.

sudo python ~/lightshow/py/hardware_controller.py --state=flash

Éste encenderá y apagará los LEDs del relé de forma consecutiva de uno en uno. En el siguiente vídeo podemos verlo en funcionamiento:

Lightshow trae algunas canciones de ejemplo. Puedes probar una de ellos con este comando:

sudo python ~/lightshow/py/synchronized_lights.py --file=/home/pi/lightshowpi/music/sample/ovenrake_deck-the-halls.mp3

Si todo funciona bien, deberías ver algo así:

Una vez hemos comprobado que todos los LEDs se encienden en orden, toca conectar los enchufes. Voy a usar cuatro enchufes dobles, lo que me da un total de ocho conectores. El esquema del cableado sería algo así:


relay_sockets.png

Las líneas azules representan la conexión de cada enchufe a cada una de las entradas de nuestro relé y la línea marrón, es la alimentación que iría al otro par de cada una de las entradas del relé, además de alimentar el primero de los enchufes (izquierda). Las líneas verdes (cable rígido) hacen de puente entre los enchufes y pasan la corriente de uno al otro. Por último la línea negra (abajo) es la de tierra (yo no la usé, ya que las luces que conecté no tenía toma de tierra, pero la pongo como referencia).

Aquí un par de fotos del montaje:


20151212_141904.jpg

Parte trasera


20151212_141819.jpg

Parte delantera

Para conectar la corriente usé un cable de alimentación de un ordenador antiguo que tenía por ahí. Le corte el extremo que se conecta al ordenador, y de ahí salían tres cables: negro, blanco y verde (tierra). Como comenté antes, el cable de tierra (verde) no lo conecté.


20160118_150450.jpg

Una vez tenemos montado todo el cableado, sólo nos queda probarlo y rezar por que todo salga como esperamos :).

Para la música, yo personalmente busqué en youtube canciones de Navidad y allí multitud de “vídeos”, algunos que duran horas. Los cuales puedes descargar con algo así:

youtube-dl –extract-audio –audio-format mp3 -l [URL VIDEO]

El mp3 lo copias a tu Raspberry Pi y puedes tocar con el comando:

sudo python ~/lightshow/py/syncronized_lights.py --file=/path/tu/mp3

Si quieres tocar varios mp3s, también puedes crearte una lista.

El resultado final de mi montaje podéis verlo en los siguientes vídeos:

Cómo decía anteriormente, el proyecto lightshow además de luces y audio, te permite transmitir tu música via FM e incluso mandarle comandos via SMS, para ello échale un vistazo a la documentación.

Si queréis algo espectacular también montado con Raspberry Pi, échale un vistazo a http://www.johnsonlightshow.com/.

Hasta aquí hemos llegado. Tuve funcionando las luces por 2-3 semanas sin ningún problema. Espero que esta entrada te sirva de algo, sobre si te la has leído entera 🙂

PD: mis conocimientos de electrónica son muy básicos, así que si le he pegado una patada a la convención de colores de los cables en los esquemas o algún símbolo, pido disculpas 🙂

 

Entradas relacionadas: