martes, 5 de marzo de 2013

Domotica con la Raspberry Pi

Hace poco presenté un proyecto con la Raspberry Pi en la universidad en la que estudio Informática.
El objetivo era bastante genérico y era usar la cabecera de pines GPIO que trae consigo la Raspberry Pi y poder controlar las E/S desde un dispositivo móvil.

Entonces para realizar este proyecto pensé en realizar una maqueta de una vivienda y simular la domótica de la misma.



Aspectos relevantes

La aplicación permite la monitorización y control domótico de la vivienda (luces, persianas, presencia, temperaturas, humedad, luminosidad) en modo local mediante interruptores y en modo remoto desde cualquier dispositivo con conexión a Internet gracias a un servidor web.

El control manual de los sensores y actuadores funciona enviando ordenes a la Raspberry Pi y ésta ejecuta la lógica de la aplicación encendiendo/apagando luces, subiendo/bajando persianas, etc. Al control a través de servidor web se accede en el equipo cliente mediante un navegador web.

Antes de definir cual era el proyecto a realizar, primero se han probado algunas librerías para GPIO, se ha elegido la más conveniente en cuanto a tiempos de respuesta que es wiringPi. También para añadir más cosas al proyecto y de mayor dificultad se ha intentado usar los buses serie que dispone la RPi: SPI no se ha llegado a usar porque las pruebas con un RTC no funcionaron y no se disponía de más dispositivos que funcionasen por SPI, para I2C se hizo las pruebas con unos chips de expansión de E/S, funcionó a la perfección, y con la UART se hizo también pruebas hasta que funcionó. También se probó el SSH y VNC como control remoto de la RPi .

Una vez que se ha conseguido hacer funcionar lo que se quería se ha ido diseñando la lógica de la aplicación elegida que es la simulación de la domótica de una vivienda. Se detallan las especificaciones que debe tener la aplicación, y cómo se quiere simular la domótica. Para ello se pensó en poner luz, persiana, presencia y temperatura por cada habitación.

El modo de simulación es el siguiente: si existe presencia en una habitación se limita el poder modificar el estado de la luz y persiana de dicha habitación desde el exterior.


Para el control descentralizado se pensó en el servidor web ya que se puede usar en gran multitud de plataformas sin tener que hacer una aplicación para cada una.
Para acceder desde fuera de la red local hay que abrir los puertos 8080 y 443 en el router que da la IP al RPi.

Se puede usar SSH para acceder remotamente a la RPi. Si se quiere SSH totalmente remoto desde fuera de la red local hay que abrir el puerto configurado para SSH en el router, por defecto es el 22.

Como el bus i2c funcionaba muy bien y permite bastantes dispositivos, se piensa en expandir los pines GPIO ya que con 8 no llega para la aplicación que se quiere realizar. Pues con la luz, persiana y presencia por cada habitación ya salen 15 pines de entrada más luego los correspondientes de salida. Así que casi todo irá por el bus i2c.

Comunicación serie: Se ha usado la comunicación serie de la RPi a Arduino como ejemplo funcional. El objetivo era usar la comunicación serie de la RasPi para comunicarse a través de RS485. Pues esta especificación permite la comunicación a largas distancias (kilómetros) y solamente usa 2 cables entrelazados. Como no daba tiempo, no se ha usado RS485.

Uso del bus 1-wire: Se usa para recoger datos de los sensores de temperatura dispuestos por toda la vivienda. Aparte de estos sensores de temperatura existen más dispositivos en el mercado que usan este bus y se podrían haber utilizado en este proyecto.
Este bus permite distancias de decenas de metros sin deterioro de la señal. Puede usarse con un mínimo de tan sólo dos cables.

La RPi no permite 1-wire en sus pines GPIO ya que los sistemas operativos para la RPi están basados en Linux, que son multitarea y por ello no se ejecutaría en tiempo real la comunicación 1-wire. Otra posibilidad sería usar un sistema operativo especial para la RPi que usa este bus por software. Este SO tiene que parar la multitarea para poder realizar la comunicación 1-wire en algún momento determinado.

Como 1-wire no hay en la RPi, se usó en un primer momento 1-wire sobre i2c mediante un chip (DS2482-800) que hace de puente.
Primero se usó un código en c para recoger los sensores de temperatura directamente desde la RasPi, pero no funcionaba. Por tanto, se buscó otra solución y se hizo un script para usar el programa owfs para recoger las temperaturas. De esta manera si que funcionaba. Pero pensándolo mejor el owfs es un servidor amplio que está diseñado para muchas soluciones. Se ha decidido usar Arduino para tratar el bus 1-wire por ser una solución más sencilla y además no hace falta instalar ningún servidor más en la RasPi.

Para el sensor de humedad y temperatura exterior SHT15 se usa Arduino ya que necesita unas especificaciones de señales de comunicación en tiempo real. Con la RPi habría sido muy complicado de implementar.

No se ha incorporado PWM a pesar de haber probado con un ventilador y con un led.
Se pensó en poner un sistema de climatización en la vivienda, pero por falta de tiempo no se ha realizado. Básicamente primero se quería hacer funcionar las luces, persiana y presencia y una vez implementado esto, añadir temperaturas, humedad y temperatura exterior, luminosidad, la comunicación con Arduino y lo que diese tiempo.

Se hizo un circuito de protección al principio del proyecto para coger práctica y no estropear la Rpi al comienzo. Al incluir más funcionalidad como el aumento de pines con los expansores de E/S se hizo otra placa más grande.
Se ha usado una placa de potencia para usar bombillas estándar de 6V y 3W para las luces y las persianas de habitación.

Hay alguna restricción como que solo se puede usar el mismo interruptor 2 veces por segundo, si no, la tabla historial tendría conflicto porque habrá claves primarias repetidas. De todos modos, esto se puede cambiar, modificando la clave primaria, pero se entiende que no es para jugar y que ya está bien poder accionar 2 veces en 1 segundo el mismo interruptor.

Diseño arquitectónico
La vivienda está formada por 5 habitaciones, en el siguiente orden: salón, cocina, baño, habitación 1 y habitación 2. Cada habitación tiene 3 sensores digitales que son luz, persiana y detector de presencia.

La simulación consiste en que cuando hay alguien en la habitación se tiene que accionar el interruptor de presencia, para dar la luz hay que accionar el interruptor de la luz y para la persiana consistirá en que al accionar el interruptor de persiana se encienda o se apague una luz indicando el paso de luz o no por la ventana.

3 sensores por 5 habitaciones dan un total de 15 pines GPIO a usar. Hace falta leer las entradas, es decir, saber cuando se ha accionado un interruptor, para ello hacen falta 15 y luego hacen falta otras 15 para las salidas, es decir, para encender las bombillas. Se usan dos expansores de pines GPIO(chip mcp23017). En total son 15 entradas y 15 salidas.
Estos pines o este chip se comunica con la RPi mediante i2c.

Por cada habitación también hay un sensor analógico de temperatura que permite medir los grados centígrados de cada habitación. La temperatura usará 1-wire y como este bus no lo tiene la RPi se accederá mediante i2c a 1-wire. La temperatura será sólo de entrada pues recoge información. Aquí ha habido un cambio en el diseño, pues se ha pasado la funcionalidad de las temperaturas a Arduino que usa 1-wire por software.

También hay 3 fotoresistencias en las habitaciones salón, cocina y baño para mostrar el nivel de luminosidad que hay en dichas habitaciones.
Y luego en el exterior de la vivienda se mide la temperatura, humedad y el nivel de luminosidad.

En la imagen siguiente se muestra un diagrama de modulos de toda la aplicación de domótica:


En cuanto al despliegue de la aplicación hay un servidor web Apache corriendo en la Raspberry Pi, hay una base de datos MySQL con las tablas de sensores/actuadores y el historial de estados. Luego está la aplicación principal la cual es un bucle infinito en la que está pendiente de escuchar cambios de estado y es el que lleva la sincronización. Y por último la página web que permite ver y monitorizar toda la domótica.

Os recomiendo ver los siguientes videos para tener una mejor idea práctica de lo que veria el usuario.
Cualquier cuestion me podeis preguntar.








En siguientes posts quizás comente alguna cosa sohre I2C y puede que algun otro tema.
Ya que es un poco complicado explicar como unir todo los programas y todo lo que he realizado; sugiero que si alguien quiere saber más sobre este proyecto que comente o me mande un email a mi correo especificando que es lo que no entiende o las preguntas que tengan al respecto.

24 comentarios:

  1. Me parece muy interesante. Espero poder leerlo más despacio.
    Gracias por las molestias en compartirlo con todo el mundo.

    Saludos,

    ResponderEliminar
    Respuestas
    1. De nada. Me alegra saber que lo encuentras interesante.

      Eliminar
    2. Esta genial , seria muy bueno si pudieras compartir mas información detallada al respecto para realizarlo de igual forma , me alegra que alla información así para compartir .... desde ya saludos y gracias por compartir informacion

      Eliminar
    3. Hola oReLcAiN.
      No he publicado con mas detalles porque es complicado/largo de explicar paso por paso como deberias montar este mismo proyecto. Creo que la instalación de domótica no es la misma para cada vivienda, ni creo que vayas a querer poner justamente lo mismo que yo.

      Además tiene la dificultad de la implementación de las PCBs la cual yo explicaria un poco mal debido a que no soy electronico, las placas estan hechas a mano (con soldadura casera) y cuando he necesitado un divisor de voltaje o cuando no sabia como desarrollar una parte del circuito he buscado por google la solucion que mas convenia. Vamos que esto ha sido una locura para mi y creo que liaria al personal jaja.

      Sobre el codigo: depende bastante de los dispositivos, sensores, actuadores que he usado, si tu usas otros o añades algun otro habria que añadir/cambiar cosas.
      Si quieres puedo publicar un diagrama de flujo, quizas podria servir para ver como funciona la aplicacion y intentar explicarlo un poco. Si te doy el codigo asi sin mas, te costaria entenderlo y si no tienes el mismo HW (placas) pues no tiene sentido.

      Y el codigo de la web, como habras podido observar no esta curradisima, soy novato en programacion web y esta realizado en html y php a pelo ,solo buscando la usabilidad. No he usado ningun framework ni nada. Seguro que algunos de ustedes lo harian mejor si tienen tiempo.

      Te invito a que me cuentes que es lo que quieres realizar y asi poder ayudarte. Quizas publique algo, pero depende del interes que haya por algo en concreto.
      Tampoco me has dicho si quieres hacer una maqueta o si quieres implementarlo en una situacion real.
      Yo por ejemplo estoy pensando ahora en implementarlo en una situacion real, para ello hay que pensar bastante y en eso estoy :)

      Eliminar
  2. Hola Victor, me parece muy interesante tu proyecto, me gustaría saber como has realizado el control vía web, o en su defecto que me dijeses de donde podría sacar esta información, ya que al contrario que tú yo soy ingeniero electrónico y esa parte es la que me suena un poco a chino y necesitaría una explicación para dummies.
    Gracias, y espero que me puedas ayudar.

    ResponderEliminar
  3. Hola Julio, me alegra que te parezca interesante.
    Mira te explico asi un poco todo el proceso
    Primero tienes que decidir que servidor web vas a usar, tiene que haber un servidor web corriendo en tu Raspberry o tambien podrias tenerlo en otro PC pero bueno, en tu caso como en el mio supongo que el servidor le ponemos en la RPi.
    Bien, si no sabes que servidor web poner te recomiendo leer algun post que he publicado haciendo referencia a Apache, lighttpd o nginx. Puedes elegir el que quieras y si tienes alguna duda o algo me puedes preguntar.
    Una vez que tienes el servidor web, tienes que saber como poner paginas en lenguaje html, hacer carpetas, etc.
    Todo esto es facil. Bien, una vez que controlas esto tienes que pensar en para que vas a usar la aplicacion web, me refiero a si el contenido es estatico o dinamico. Si estas trtabajando con GPIO supongo que sera dinamico y querras tener una base de datos en la cual almacenar los datos y construir tu web con los datos que esten en las tablas de la BD.
    Pues instalas MySQL que esta explicado en el post de Apache (un servidor LAMP). Y creas las tablas oportunas, puedes hacerlo con phpmyadmin (interfaz web)
    Tienes que elegir el lenguaje para trabajar con contenido dinamico, yo usé PHP. pero hay otros como Perl, Python, etc. Yo te recomiendo PHP.

    Bueno hasta aqui, tendrias el servidor web, BD de MYSQL y PHP.

    Para el control via web que me preguntas: Pues puedes crear una pagina con lenguaje PHP en la que pones un formulario y usas botones como yo he usado o mismamente pones una caja de texto donde escribes el numero de pin y el estado.
    Si haces el formulario tienes que indicar que cuando se de al boton enviar o cualquier otro, toda la informacion que hay en ese formulario vaya a cierta pagina php que trate su contenido.
    Por ejemplo si encendemos la luz del salon pues tiene que haber una pagina con una funcion PHP que compruebe datos de la BD y los actualize en funcion de si el usuario ha decidido cambiar el estado de ese actuador.
    Asi conseguirias modificar la BD, pero claro aun no has encendido la luz. Para encender la luz hay que cambiar el estado del pin en el HW de la RPi, para eso puedes usar un programa principal en Python, en C o cualquier otro lenguaje usando wiringPi, RPI.GPIO o cualquier otra libreria para tratar los pines GPIO de la Raspi. Entonces en este programa principal lo que haces es leer el estado de la BD y escribes el estado de los pines, asi conseguirias el control ia web.

    Resumiendo, el control seguiria este flujo de datos:
    Pagina web con botones para modificar estados->pagina web php para actualizar estados en la BD->tablas BD->programa principal->pines GPIO

    Y para la lectura de estados de los pines PGIO seria al reves, evidentemente.

    Mas o menos viene siendo esto. Creo que voy a postear en breves alguna cosa mas sobre este proyecto, un diagrama de flujo o para que veais las tablas que he usado y la cantidad de ficheros.

    Si no me he explicado tu insiste jeje

    Si necesitas ayuda con el PHP te puedo explicar, ademas tengo por ahi guardados los enlaces q consulté para por ejemplo el control de acceso (sesiones). Te dejo abajo un par de enlaces que te pueden interesar

    este es sencillo, quizas te pueda servir: http://www.instructables.com/id/Web-Control-of-Raspberry-Pi-GPIO/
    Algo mas currado seria esto, no lo he mirado pero creo que usa CSS
    https://github.com/NeonHorizon/berryio

    De todos modos si decides empezar a hacerlo tu solo, me puedes sugerir hacer algun tutorial de PHP.

    ResponderEliminar
  4. Muchas gracias por tu rapidez en responder, he trabajado algo de php, html y css, pero mi problema principal era el control del GPIO por estos medios, voy a exarle un vistazo a las web que me has sugerido y ya te contaré como me ha ido. Muchas gracias de nuevo.
    Un saludo

    ResponderEliminar
    Respuestas
    1. Ok, entonces si que manejas un poco la programacion web. Pues para el control lo que tienes que hacer es usar una base de datos para comunicar el php con el codigo del programa principal. Tambien hay otras maneras para pasar datos entra una aplicacion web un programa como pueden ser via sockets y otros.
      Lo bueno de la BD es que tienes los datos almacenados en tablas. Quizas sea algo mas lento tener que hacer operaciones de select y update pero es mas modulable asi un programa ya que si necesitas un sensor mas, añades una linea a una tabla y listo.

      Saludos

      Eliminar
  5. He detallado un poco como fue el diseño del proyecto. Podéis echarle un ojo aquí: http://muyraspi.blogspot.com/2013/04/diseno-del-proyecto-de-domotica.html
    [Post actualizado]

    ResponderEliminar
  6. Muchas gracias por toda la información me esta siendo de gran ayuda.

    ResponderEliminar
    Respuestas
    1. Victor primero que nada gracias por todos tus aportes. Mira es que estamos desarrollando un proyecto para la Universidad y necesitamos hacer una aplicacion en android que me permita conectarme via ssh con la raspberry pi y que al pulsar un boton en la aplicacion android se ejecute un comando especifico en la raspberry. Se necesita que pida la ip el usuario y contraseña. No se si puedas ayudarme con eso, le he dado vueltas y nada que lo logro. He leido algunos codigos pero son demasiado complejos y no creo que sea la solucion a lo que necesito. Te agradeceria muchisimo si me puedes colaborar, hacer una especie de tutorial o un video donde puedas explicarme paso a paso como hacer la conexion. Veo que tu lo hiciste en este proyecto es mas o menos lo que necesito. Muchas gracias.

      Eliminar
    2. Te he contestado al correo que me has mandado que es este mismo tema.
      Yo lo tengo hecho con SSL via https, no uso ssh

      Eliminar
    3. Hola Victor! Primero queria felicitarte por el gran trabajo.
      Yo también tengo que hacer un proyecto parecido al que comenta AJ89, en el que me tengo que comunicar con la RPi a través de un dispositivo móvil mediante un servidor web. Si puedieras enviarme algún tipo de información o tutorial te lo agradecería mucho. Un saludo y gracias.

      Eliminar
  7. Una duda, ¿cómo actualizas el PHP para cambiar los valores de los sensores? ¿Actualizas toda la página cada cierto tiempo?¿La mantienes a la escucha? Quiero hacer una interfaz de monitorización y ando un poco perdido.

    ResponderEliminar
    Respuestas
    1. Actualizo la página del PHP a los 2 segundos, es la manera que tengo para que escuche cual es el estado actual.

      Eliminar
    2. Entonces, valdría con algo así?: meta http-equiv="refresh" content="2"
      Muchas gracias!!!

      Eliminar
    3. Si, esa linea refresca la página cada 2 segundos

      Eliminar
  8. Hola.

    Queria darte las gracias por tu blog, yo también ando desarrollando un sistema de domotica con arduino, de momento no utilizo las raspberry pi pero al final lo voy a tener que incluir puesto que las posibilidades son impresionantes....

    La verdad es que tu blog a sido y sera seguro para mi una fuente de inspiración y espero que alguna vez pueda devolverte parte de esa inspiracion, por cierto si quieres darle un vistazo a mi proyecto...

    Proyecto domotica con arduino"

    ResponderEliminar
    Respuestas
    1. Hola Roberto, gracias por tu comentario y compartir tu proyecto.

      Eliminar
    2. cuando vas a incluir la raspberry en tu proyecto

      Eliminar
  9. Hola, que buen proyecto, oye no se si me puedas ayudar con el mio, es algo parecido, pero yo solo necesito medir temperatura y mi duda es como puedo enviar esos datos a la raspberry, lei tu proyecto, lo malo es que yo no tengo permitido usar arduino y tengo que usar un sensor que me entrgue la temperatura en señal analogiaca para usar un convertidor analogico-digital, esas son mis restricciones, que me aconsejarias? me podria contestar a mi correo: carlos_wolfi@hotmail.com
    te lo agradeceria mucho

    ResponderEliminar
  10. Hola, disculpa lo que pasa es que estoy haciendo algo parecido para controlarlo a traves de una interfaz web con raspberry (S.O. raspbian), primero lo hice con consola y todo bien encendio y apago el foco, pero, no puedo hacer que lo haga desde la apliacion web, si puedes ayudarme te lo agradecere bastante, gracias.
    P.D. si pudieras ayudarme mi correo es christianalatorre@outlook.es

    ResponderEliminar
  11. Gran proyecto felicidades... me nace una duda la comunicacion via internet la haces desde la red local o publica, si es pública me gustaria saber como lo haces. Hize un proyecto parecido usando un hostname gratuito que otorga no-ip.com para el envio de datos desde red publica pero ando en busca de otro metodo. Gracias

    ResponderEliminar

no-ip

Para usar la aplicación web se puede hacer indicando la IP pública y puerto, más el resto de la URL. Esto puede ser algo engorroso de u...