Relé WiFi Controlado por web
1.Objetivo:
El objetivo más extenso de este proyecto es desarrollar un sistema económico y versátil para controlar a distancia y automatizar distintos dispositivos eléctricos domésticos. El objetivo más inmediato y asequible se limita al control a distancia de un relé empleando para ello una página web.
He elegido el relé como dispositivo a controlar porque es un elemento básico y económico a partir del cual poder controlar el encendido o apagado de cualquier dispositivo eléctrico doméstico (bombilla, ventilador, caldera, estufa, persiana, toldo, válvula, impresora, etc.) en mi caso concreto pretendo gestionar a distancia el encendido de mi impresora que habitualmente se encuentra en una habitación distinta a la que ocupa mi ordenador personal.
Por otro lado he elegido controlar el relé a través de una página web porque es el medio más estandarizado y accesible que conozco. En primer lugar los lenguajes HTML, Javascript y PHP son estándares abiertos y gratuitos, y su uso está ampliamente extendido, ya que cualquier dispositivo informático de uso común dispone de un navegador de páginas web (ordenador personal, tableta, teléfono inteligente, videoconsola, televisor inteligente, etc.) lo que evita la necesidad de emplear dispositivos específicos para el control. Si hubiera elegido limitar a un teléfono inteligente o una tableta el control del sistema, debería elaborar un programa especifico para cada sistema operativo en particular (en este caso Android y IOS son los principales) con la complicación que añade esto al diseño. Por otro lado, ya que había planeado que el sistema pudiera ser accesible desde cualquier punto del mundo con acceso a Internet, decidí que la logica del sistema estaría alojada en un servidor web local, ya que es relativamente fácil de implementar y es económico. En principio mi servidor web local estará ubicado en mi ordenador personal, por la sencillez que supone, más adelante pienso alojarlo en un ordenador sencillo (Raspberry Pi B+) o un NAS del que dispongo en la actualidad.
2.Requerimientos hardware:
El proyecto está basado en la plataforma Arduino, ya que se trata de una iniciativa de hardware abierta muy extendida entre los aficionados a la electrónica y por tanto es económica, además de ampliamente documentada por el fabricante y por los aficionados.
En concreto, como cerebro del relé WiFi he elegido un modelo compatible con Arduino UNO R3, ya que dentro de esta plataforma es el más empleado por su versatilidad, además me puede servir de base para la elaboración de futuros proyectos.
Otro elemento imprescindible del control del relé es la capa WiFi. En este caso he elegido un modelo compatible con el CC3000 de Adafruit.
3.Requerimientos software:
Para la programación del Arduino UNO R3 empleamos el IDE de Arduino, concretamente la versión ARDUINO 1.6.0.
También emplearemos las librerías:
- Adafruit CC3000 Library: Para comunicar el Arduino UNO R3 con la capa WiFi CC3000
- CC3000 Multicast DNS: Para poder emplear un nombre de dominio en vez de la IP de la capa WiFi.
- aREST Library: Para transmitir instrucciones al Arduino UNO R3 mediante la URL.
Para instalar estas librerías debemos descargar las carpetas que las contienen y copiarlas en la carpeta del IDE, en mi caso C:\Program Files (x86)\Arduino\libraries
Además debemos disponer de un servidor web con interprete PHP integrado. Yo he empleado XAMPP, porque es gratuito y versátil.
4.Conexionado del hardware:
El conexionado de la capa WiFi al controlador es típica, los 2 componentes están preparados para acoplarse.
La distribución de patillas es la siguiente:
- Digital (3) IRQ Interrupción
- Digital (5) VBAT Tensión de alimentación
- Digital (13) SPI CLK Reloj del Bus de Interfaz de Periféricos
- Digital (12) SPI MISO Master Input Slave Output
- Digital (11) SPI MOSI Master Output Slave Input
- Digital (10) CS Habilitación de WiFi
- 5V Vin Alimentación
- GND GND
- Digital (6) Salida Relé (LED Naranja)
Emplearemos la patilla digital 3 como interrupción para indicar al microcontrolador que atienda a la capa WiFi. La patilla digital 5 sirve para comprobar la tensión de la batería de respaldo. El bus de interfaz de periféricos (SPI) lo componen las patillas 13, 12 y 11. La patilla digital 10 sirve para inhibir el funcionamiento de las comunicaciones entre el controlador y la capa WiFi.
5.Comprobación del Arduino
Para comprobar si el Arduino funciona correctamente antes de seguir adelante con el proyecto completo introducimos un programa sencillo que nos provoque la intermitencia de la salida digital 6, porque será la que emplearemos en el proyecto definitivo para activar el relé, ya que su estado lógico es visible gracias a que está asociado a un led naranja en la capa WiFi.
El código del programa a introducir en el Arduino es el siguiente:
intermitente.ino
// Programa sencillo para comprobar Arduino
// Sección de declaraciones globales
const int relay_pin = 6; //Declaramos en número de la patilla que asociamos al relé
void setup() { //Sección de configuración
pinMode(relay_pin,OUTPUT); //Configura patilla 6 como salida
}
void loop() { //Programa iterativo principal
// Pone pin 6 de salidas digitales a 5V
digitalWrite(relay_pin, HIGH);
// Espera 5000ms
delay(5000);
// Pone pin 6 de salidas digitales a 0V
digitalWrite(relay_pin, LOW);
// Espera 5000ms
delay(5000);
}
6.Comprobación
del proyecto completo
Una vez que hemos comprobado en el paso anterior que somos capaces
de programar el bucle de activación y desactivación del pin 6 de
las salidas digitales, cosa que podemos monitorizar a través del
encendido y apagado del led naranja integrado en la capa WiFi,
pasamos a programar el proyecto completo en el arduino, cuyo código
expongo a continuación:rele_wifi.ino
/*
* Simple remote relay control with Arduino & the CC3000 chip
* Part of the code is based on the work done by Adafruit on the CC3000 chip
* Writtent by Marco Schwartz for Open Home Automation
*/
// Librerías necesarias
#include <Adafruit_CC3000.h>
#include <SPI.h>
#include <CC3000_MDNS.h>
#include <aREST.h>
// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ 3
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Parámetros WiFi
#define WLAN_SSID "Nombre_red_wifi" //SSID de tu red WiFi Local
#define WLAN_PASS "Tu_Clave_Wifi" //Clave de tu red WiFi Local
#define WLAN_SECURITY WLAN_SEC_WPA2 //Tipo de encriptación de tu red WiFi Local
// Puerto al que atender para conexiones TCP
#define LISTEN_PORT 80
// Crea instancia CC3000
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
// Crea instancia del servidor
Adafruit_CC3000_Server restServer(LISTEN_PORT);
// Crea instancia DNS
MDNSResponder mdns;
// Crea instancia aREST
aREST rest = aREST();
// Patilla que controla el Relé
const int pin_rele = 6;
void setup() {
// Initialize Serial
Serial.begin(115200);
// Set name & ID
rest.set_name("control_rele");
rest.set_id("1");
// Define que controla el relé como salida
pinMode(pin_rele,OUTPUT);
// Conectar CC3000 a la red wifi local
if (!cc3000.begin()) //si no se inicia el objeto
{
while(1); //Se entra en un bucle infinito
}
//Si no se establece conexión con la red local
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
while(1); //Se entra en un bucle infinito
}
while (!cc3000.checkDHCP()) //Mientras nuestro router no asigne una dirección IP
{
delay(100); //esperamos 0,1 segundo
}
// Print CC3000 IP address
while (! displayConnectionDetails()) {
delay(500);
}
// Start multicast DNS responder
if (!mdns.begin("rele", cc3000)) {
while(1);
}
// Start server
restServer.begin();
Serial.println(F("Conectando por WiFi a red local..."));
}
void loop() {
// Handle any multicast DNS requests
mdns.update();
// Handle REST calls
Adafruit_CC3000_ClientRef client = restServer.available();
rest.handle(client);
}
// Print connection details of the CC3000 chip
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("No se ha obtenido una dirección IP!\r\n"));
return false;
}
else
{
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
En este punto Una vez programado el servidor en el Arduino, se reinicia y al cabo de unos 30 o 40 segundos el dispositivo es completamente funcional y aunque de manera un poco incómoda ya podemos comprobar su funcionamiento con la única ayuda de un explorador web.
Podemos averiguar la dirección IP del Arduino a través del monitor serie del entorno de desarrollo de Arduino Herramientas>Monitor Serie [Ctrl]+[Mayúsc]+M:
A los 30 o 40 segundos de reiniciar nuestro Arduino, en el monitor serie (yo uso el COM9) aparece la información de conexión local de nuestro Arduino:
Esto nos indica que hemos establecido conexión con éxito.
El siguiente paso puede ser enviar una orden a nuestro dispositivo introduciendo una url en nuestro navegador, por ejemplo, si la dirección ip de nuestro Arduino es 192.168.1.10 introduciríamos en nuestro navegador la url "http://192.168.1.10/digital/6/r" que gracias a la librería aREST.h incluida en nuestro Arduino este interpreta como "leer el estado de la salida digital 6" y nos devuelve una cadena JSON con el estado de esta: "{"return_value": 1, "id": "1", "name": "control_rele", "connected": true}".
De forma parecida podemos ordenarle a nuestro Arduino que ponga la salida digital 6 a "1" o a "0" introduciendo en el navegador la url correspondiente, "http://192.168.1.10/digital/6/1" y obtendriamos como respuesta la cadena JSON que confirma la acción "{"message": "Pin D6 set to 1", "id": "1", "name": "control_rele", "connected": true}"
Llegados a este punto y habiendo comprobado que nuestro dispositivo WiFi responde correctamente, procedemos a realizar la programación de la interfaz con la cual controlaremos el dispositivo de forma más gráfica y cómoda en vez de introducir comandos en forma de url en el navegador. Este interfaz está compuesto por una página html con un par de botones para controlar el estado de la salida digital 6 de nuestro dispositivo y está alojada en un servidor web XAMPP en nuestra red local. Dado que la dirección de nuestro servidor web XAMPP es 192.168.0.30 y la interfaz "interface.html" está en su carpeta principal, debemos introducir la dirección "http://192.168.15.30/interface.html".
El código de esta página es
el siguiente:
interface.html
<head> <LINK href="./style.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="jquery-2.0.3.min.js"></script> <script type="text/javascript" src="script.js"></script> </head> <body> <div class="mainContainer"> <div class="buttonBlock"><span class="buttonTitle">LED</span> <button class="ledButton" type="button" id="1" onClick="buttonClick(this.id)">On</button> <button class="ledButton" type="button" id="2" onClick="buttonClick(this.id)">Off</button> </div> </div> </body>
script.js
function buttonClick(clicked_id){
if (clicked_id == "1"){
$.get( "curl.php", {
pin: "6", state: "1"} );
}
if (clicked_id == "2"){
$.get( "curl.php", {
pin: "6", state: "0"} );
}
}
curl.php
<?php $pin = $_GET['pin']; $state = $_GET['state']; // Create cURL call $service_url = 'http://rele.local/digital/' . $pin . '/' . $state; $curl = curl_init($service_url); // Send cURL to Yun board curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); $curl_response = curl_exec($curl); curl_close($curl); //Print answer echo $curl_response; ?>
Su funcionamiento se muestra en este video:
https://www.youtube.com/watch?v=pWuSQhAGiAo







