Control WEB de persiana
El problema: Se trata de un taller en el que tanto el dueño como los operarios salen continuamente a hacer reparaciones dejando la puerta cerrada, pero la persiana levantada. Por horario o distancia, a veces no regresa nadie y van directamente a casa. Si no va personalmente, el jefe nunca sabe si se bajó.
La solución: Cerrar la persiana via WEB desde el móvil o un ordenador. Esto se hace cerrando un circuito en el receptor del mando de la persiana con un optoacoplador. El problema que hay es que este mando solo tiene un botón, tanto para subirla como para bajarla, lo que hace necesario un "feedback" del estado de dicha persiana. Esto se logra con un imán pegado a la persiana y un detector Hall.
Como el no saber, no te garantiza el recordar, además se ha dispuesto un reloj en tiempo real que de todas formas actúa a mediodía y por la noche.
Todo el sistema se basa en un Arduino programado con un servidor WEB que podemos ver en un ordenador o en el móvil viendo la situación de la persiana y pudiendo ordenar su cierre. Aprovechando el sistema, también se ha implementado la posibilidad de poder abrir la puerta del taller, ya que tiene cerradura eléctrica y nos saca de un apuro si a alguien se le olvida la llave.
El sistema consta de:
-Placa Arduino Uno
-Shield Ethernet
-Reloj tiempo real
-Placa de control, conexiones y regulador de 5 voltios.
-Sensor Hall
El circuito es muy simple
Con el Pin 6 actuamos sobre un optoacoplador que cierra el circuito del receptor del mando durante 400ms y bajará o subirá la persiana según su estado.
Con el Pin 7 se excita un transistor que cierra un relé para abrir la puerta del taller. Aquí es necesario un relé porque circula mucha corriente.
En el Pin A0 recibimos el sensor Hall que nos indica si la persiana esta levantada o cerrada (el imán estaría próximo al sensor). Se usa un imán de neodimio rescatado de un disco duro.
El montaje terminado con el sensor Hall a la derecha. Vemos la página Web como queda. Podemos activar la cerradura de la puerta y mandar un impulso a la persiana, pero siempre sabiendo si en ese momento está abierta o cerrada. Abajo vemos la hora del reloj para el cierre automatizado y la posibilidad de ajustar su hora a las 12h 00' de cualquier día. Para actuar desde Internet, lógicamente hay que cambiar a IP externa.
Dejo el código empleado
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
#include <SPI.h> //Importamos librería comunicación SPI
#include <Ethernet.h> //Importamos librería Ethernet
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,xxx); //Asingamos la IP al Arduino
EthernetServer server(xxxx); //Creamos un servidor Web con el puerto que queramos
unsigned long millisPrevio = 0; // almacena ultima vez del ciclo
const long intervalo = 6000; // intervalo del evento. Asegura un solo pulso en salida.
const int mandopersiana=6; //pin control de la persiana
const int mandopuerta=7; //pin control de la puerta
const int sensorHall=A0; //pin entrada control Hall
boolean estado=true;
int Hall =0;
byte hora; byte minutos;
void setup(){
// Serial.begin(57600);
Wire.begin();//Inicializamos la librería Wire
RTC.begin();//Inicializamos el módulo reloj
// Inicializamos la comunicación Ethernet y el servidor
Ethernet.begin(mac, ip);
server.begin();
pinMode(mandopersiana,OUTPUT);
pinMode(mandopuerta,OUTPUT);
pinMode(sensorHall, INPUT);
}
void loop()
{
unsigned long millisActual = millis();
if(millisActual - millisPrevio >= intervalo){
millisPrevio = millisActual;
DateTime now = RTC.now();//Creamos un objeto que contiene la hora y fecha actual
Hall = analogRead(sensorHall); Hall = map(Hall,0,1023,0,50);
//Serial.println(Hall);
//CERRAR LA PERSIANA A LAS 16h y a las 22h si esta subida
if ((Hall < 26) && (Hall > 22)) { //Hall = 23, 24 o 25 persiana subida
if (now.hour() == 22 && now.minute() == 0 && (now.second() >= 21 && now.second() <= 26)) {
digitalWrite(6,HIGH); //orden de cerrar persiana durante 400ms
// Serial.print("Cerrando persiana a las: ");
delay(400);
digitalWrite(6,LOW);}
if (now.hour() == 16 && now.minute() == 0 && (now.second() >= 21 && now.second() <= 26)) {
digitalWrite(6,HIGH); //orden de cerrar persiana durante 400ms
// Serial.print("Cerrando persiana a las: ");
delay(400);
digitalWrite(6,LOW);}
}
hora=now.hour(); minutos=now.minute();
EthernetClient client = server.available(); //Creamos un cliente Web
//Cuando detecte un cliente a través de una petición HTTP
if (client) {
// Serial.println("new client");
boolean currentLineIsBlank = true; //Una petición HTTP acaba con una línea en blanco
String cadena=""; //Creamos una cadena de caracteres vacía
while (client.connected()) {
if (client.available()) {
char c = client.read();//Leemos la petición HTTP carácter por carácter
// Serial.write(c);//Visualizamos la petición HTTP por el Monitor Serial
cadena.concat(c);
int posicion=cadena.indexOf("ACC="); //MIRAMOS EN LA URL
// Hall = analogRead(sensorHall); Hall = map(Hall,0,1023,0,50);
// if ((Hall < 26) && (Hall > 22)) { //Hall = 23, 24 o 25
if(cadena.substring(posicion)=="ACC=PERSIANA"){
digitalWrite(mandopersiana,HIGH);
delay(400);
digitalWrite(mandopersiana,LOW);
// }
}
if(cadena.substring(posicion)=="ACC=PUERTA"){
digitalWrite(mandopuerta,HIGH);
delay(3000);
digitalWrite(mandopuerta,LOW);
}
if(cadena.substring(posicion)=="ACC=RELOJ"){
ajustahora();
}
//SE CREA LA PÁGINA WEB EN EL SERVIDOR
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//Página web en formato HTML
client.println("<html>");
client.println("<head>");
client.println("</head>");
client.println("<body>");
client.println("<h1 align='center'>Taller TECNOSYS</h1>");
client.println("<div style='text-align:center;'>");
client.println("<button onClick=location.href='./?ACC=PERSIANA\' style='margin:auto;background-color: #84B1FF;color: snow;padding: 10px;border: 1px solid #3F7CFF; height:100px; width:200px;'>");
client.println("<H1>Persiana</H1>");
client.println("</button>");
client.println("<button onClick=location.href='./?ACC=PUERTA\' style='margin:auto;background-color: #84B1FF;color: snow;padding: 10px;border: 1px solid #3F7CFF; height:100px; width:200px;'>");
client.println("<H1>Puerta</H1>");
client.println("</button>");
client.println("</b><br />");
client.print("<H1>");
//ASIGNAR ESTADO SEGÚN POSICION DE PERSIANA. TRUE == CERRADA
estado=false;
if ((Hall > 26) || (Hall < 22)) { estado=true;}
if (estado==true){
client.println("<H1>Persiana cerrada</H1>");}
else { client.println("<H1>Persiana abierta</H1>");}
client.println("</b><br />");
client.print("<H1>");
client.print(hora); client.print(':');
if (minutos < 10){ client.print("0");}
client.print(minutos); client.print("</H1>");
client.println("</button>");
client.println("<button onClick=location.href='./?ACC=RELOJ\' style='margin:auto;background-color: #84B1FF;color: snow;padding: 10px;border: 1px solid #3F7CFF; height:90px; width:200px;'>");
client.println("<H2>Ajustar reloj a las 12h 00'</H2>");
client.println("</button>");
client.println("</b></body>");
client.println("</html>");
break;
}
if (c == '\n') {
currentLineIsBlank = true;
}
else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
//Dar tiempo al navegador para recibir los datos
delay(1);
client.stop();// Cierra la conexión
}
}}
void ajustahora(){ //AJUSTA HORA A LAS 12H 00'
RTC.adjust(DateTime(2015,02,15,12,00,00));
}