Controlando las puertas del garaje con un Raspberry Pi

2014-02-02_13-48-45_462.jpg

En esta entrada os voy a detallar un pequeño proyecto en el que trabajé la semana pasada aprovechando la helada que tuvimos.

El proyecto consiste en poder abrir y cerrar las puertas del garaje de forma remota, así como saber el estado (abierta o cerrada) de cada una de las puertas. En mi caso, hablo de puertas en plural porque como podéis ver en la foto que encabeza esta entrada mi garaje tiene dos puertas. El proyecto es perfectamente válido para garajes de una o más de dos puertas.

2014-01-03_11-32-48_922.jpg

En la foto podemos ver los componentes que he usado, algunos no son necesarios, pero te hacen la vida un poco más fácil. La lista es la siguiente:

  • Raspberry Pi (aunque estoy usando el modelo B, puedes usar el modelo que es algo más barato, ya la mayor diferencia en éste último es la ausencia de conector ethernet, el cual no usaremos)
  • Tarjeta de red inalámbrica
  • Relé de 2 módulos. En este caso necesito 2 módulos, uno para cada puerta.
  • Tarjeta de memoria. Aquí con 4 Gb debería ser más que suficiente.
  • Sensor de puerta. Necesitas un sensor por puerta, en este caso necesito dos sensores.
  • Fuente de alimentación. Preferible de 1 amperio o más. Tenemos que pasar corriente el relé.
  • Placa de prototipos. Este componente aunque no es necesario te hace la vida muy fácil conectando los cables. Además tiene marcado los diferentes pines con sus funciones: número de GPIO, corriente, tierra, etc.
Lo primero que necesitamos es instalar nuestro sistema y conectar nuestro Raspberry Pi a la red interna. El sistema que uso es la imagen oficial de Raspbian:

tuxotron@tuxotron-T530:~$ ssh pi@192.168.1.32 pi@192.168.1.32’s password: Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l

El proceso de instalación me lo voy a saltar, ya que no es el objetivo de esta entrada. Por lo tanto a partir de ahora asumo que nuestro Raspberry Pi está conectado a nuestra red inalámbrica y su IP es 192.168.1.32.

El proyecto lo podemos dividir en dos partes: el relé y los sensores de las puertas.

El Relé

relay1.jpg

Como vemos el relé tiene tres pines en la parte izquierda el cual contiene un jumper que une los pines JD-VCC y VCC. Y en la parte derecha tenemos los pines que tenemos que conectar a nuestro Raspberry Pi. GND (tierra) lo tenemos que conectar a cualquiera de los pines GND de nuestro RPi, VCC (el de más a la derecha) es el de corriente y necesita 5V. En RPi tenemos dos pines que proveen corriente 3V y 5V, así que lo conectamos al de 5V. Y los dos pines restantes IN1 e IN2, son las entradas para cada uno de los módulos, estos los tenemos que conectar a cualquiera de los GPIO genéricos de nuestro RPi. En mi caso usé los pines GPIO 17 y 18. A continuación podemos ver una foto de mis conexiones:

2014-02-02_13-57-35_568.jpg

Ahora toca probarlo. El relé dispone de dos diodos led que nos permite ver de forma visual el funcionamiento del mismo. Básicamente cuando mandamos corriente se ilumina el led y cuando cortamos, pues se apaga el led. Veamos una pequeña prueba (justo debajo de la pantalla se ven los leds encendiéndose y apagándose):

Como podemos ver en el vídeo, tengo un página web muy simple con el estado de las puertas y dos botones, uno para cada puerta, que lo único que hace es activar el módulo correspondiente del relé por medio segundo. Como vemos en el vídeo cuando hago click en los botones, vemos como el diodo led correspondiente del relé se enciende por medio segundo y luego se apaga. Es decir, el relé mandará corriente al módulo correspondiente por esa cantidad de tiempo y luego corta la corriente. Más adelante hablaremos del software.

Sensores de puerta

Ahora veremos como funcionan los sensores. En nuestro caso usamos dos sensores magnáticos que actúan puramente como un conmutador. Estos no requieren corriente alguna y sólo disponen de dos cables: tierra y el pin GPIO genérico que elijamos:

2014-02-02_14-44-12_751.jpg

En mi caso tengo conectados los sensores al GPIO 22 y 23, más sus correspondientes conexiones a tierra (GND):

2014-02-02_14-44-24_368.jpg

A continuación os dejo un pequeño vídeo de demostración. Como vemos inicialmente los dos sensores están cerrados (las dos piezas están unidas) como podemos ver en la página: CLOSED. Cuando abrimos el sensor de la derecha, vemos como se actualiza el estado en la página y pasa a OPEN. Lo mismo ocurre con el sensor de la izquierda. El refresco ocurre cada 3 segundos actualmente.

Una vez tenemos probado nuestro sistema, es hora de pasar a la instalación real. Las instalación de los sensores de las puertas no tiene ningún misterio, sólo tenemos que colocar la parte del sensor que tiene el cable en la pared y la otra parte del mismo en la puerta y por supuesto tirar un par de cables hasta nuestro RPi. Para el relé, hemos visto los conectores que van a nuestro RPi, pero de alguna forma tenemos que conectar cada módulo a cada motor de las puertas.

El sistema que tengo instalado en el garaje para abrir/cerrar las puertas es un Linear LDO50. Este aparato, en la parte trasera tiene cuatro conectores: Antena, Botón, Común y Luz (Beam). Nosotros lo que vamos a emular es la pulsación del botón que abre/cierra la puerta, por lo que sólo necesitamos dos hilos, uno para el conector botón y el otro para el común. Nuestro esquema quedaría tal que así:

Relay door opener

Ahora que tenemos ya todo el hardware montado es momento de enfocarnos en el software. Una de las cosas que más me gustan de RPi es que es un ordenador corriendo Linux y por lo tanto sus posibilidades de programación son enormes y no estamos relegados a un sistema o lenguaje concreto. De hecho en este proyecto he usado Python para ir probando el prototipo y finalmente Java.

Lo primero que vamos a ver son los scripts en Python que fui usando para mis pruebas. De esta forma también podemos ver como hacer prácticamente los mismo en dos lenguajes distintos.

El primer script que vamos a ver es el interactua con el relé, concretamente con el módulo que hemos conectado al GPIO 17:

#!/usr/bin/python

# Import required Python libraries
import RPi.GPIO as GPIO
import time

# We use the BCM schema
GPIO.setmode(GPIO.BCM)

# Setup GPIO 17 as OUTput pin
GPIO.setup(17, GPIO.OUT)
# Set it on HIGH initially
GPIO.output(17, GPIO.HIGH)

# Set it on LOW 
GPIO.output(17, GPIO.LOW)
# Wait for .5 seconds
time.sleep(0.5)
# Set it back to HIGH
GPIO.output(17, GPIO.HIGH)
# Cleanup
GPIO.cleanup()

Como vemos el script es muy sencillo. Todo lo que hace es preparar el GPIO 17 como un pin de salida (OUT) ya que vamos a “escribir” en él, ponerlo en HIGH para que no pase corriente al relé e inmediatamente después, lo pone en LOW, espera medio segundo y lo vuelve a poner en HIGH, de esta forma pasamos corriente al relé por 0.5 segundos y con ello deberíamos ver encenderse el diodo led correspondiente por tal cantidad de tiempo. La última línea del script simplemente libera recursos.

Para probar el segundo módulo conectado al GPIO 18, todo lo que tenemos que hacer es cambiar el 17 por el 18 y listo.

Luego tenemos un script para probar los sensores.

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
left_door = 22
right_door = 23

# activate input with PullUp
GPIO.setup(left_door, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(right_door, GPIO.IN, pull_up_down = GPIO.PUD_UP)

while True:
if GPIO.input(left_door):
print("LEFT DOOR OPEN!")
if GPIO.input(right_door):
print("RIGHT DOOR OPEN!")
time.sleep(0.5)

GPIO.cleanup()

Como podemos ver el script y casi igual que el anterior. En este caso los pins los preparamos de lectura (IN). Cada medio segundo lee el estado de los sensores y si está abierto, entonces imprime por pantalla el mensaje.

Para la instalación final, quería que fuera algo flexible y que me permita interactuar desde una aplicación web, una aplicación de móvil o incluso desde la línea de comandos, así que me decidí exponer el sistema a través de servicios RESTful. La plataforma que elegí fue Java y la librería Pi4J.

El código, dejando de lado la implementación de servicios RESTful en Java, es muy parecido al de Python que hemos visto anteriormente. Sólo una pequeña diferencia a tener en cuenta: el numerado de los pins. En los ejemplos que hemos visto en Python, hemos usado la numeración BCM2835, pero la librería Pi4J está basada en wiringp, que usa una numeración más independiente, ya que ésta no está pensada para RPi, sino para cualquier interfaz GPIO. Así que lo único que tenemos que saber es la correspondencia entre ambas numeraciones, las cuales podemos ver en el siguiente esquema:

gpio1.png

http://wiringpi.com/pins/

El código fuente lo tenéis en Gihub.

Para ejecutar el código uso Tomcat 7, disponible en los repositorios de Raspbian. Una nota importante a tener en cuenta es que para el acceso a los GPIO necesitamos acceso root. En mi caso cambié la configuración de tomcat para correr el servidor como root.

En /etc/default/tomcat, busca TOMCAT7_USER y TOMCAT7_GROUP y asignales root:

TOMCAT7_USER=root
TOMCAT7_GROUP=root

Si el servidor está expuesto a algún tipo de red compartida, deberías considerar este paso y buscar otra alternativa. De la misma forma, en el código de ejemplo, los servicios RESTful no están protegidos con ningún tipo de sistema de autenticación, por lo que cualquiera con acceso a la red, te puede abrir/cerrar la puerta del garaje, así que de nuevo, si estas en un red compartida asegúrate que proteger tus servicios.

Y para finalizar aquí os dejo un pequeño vídeo de demostración:

La instalación es muy chapucera como podéis ver, pero ya la iré mejorando, mientras tanto ahí se va a quedar el Raspberry Spider Pi :) En el vídeo se ve como cuando pulso sobre el botón Right Push se abra la puerta izquierda y viceversa, los botones los tengo orientados vista desde afuera del garaje y el vídeo lo grabé desde adentro.

Si has llegado hasta aquí, vaya tostón te has tragado, al menos espero que no haya sido en vano.

Happy hacking!!