Un enchufe inteligente puede ser el primer camino sencillo para empezar la automatización del hogar ,objetivo que sin duda esta muy pronto por llegar (en cuanto bajen aun mas los precios del hardware , pero sobre todo se mejore el software respecto a la seguridad) . Como hemos visto en este blog en numerosas ocasiones, existen muchos tipos de enchufes inteligentes disponibles en el mercado , pero aunque su precio empieza a ser razonable, desgraciadamente son soluciones cerradas y por tanto no son personalizables estando unidos a una solución sw que es muy difícil de cambiar.
En general, un enchufe inteligente es un dispositivo compacto que se conecta a tomas de corriente tradicionales pudiendo actualizarse con control remoto (normalmente por wifi) y por programación mediante diversas aplicaciones a medida ejecutadas desde un smartphone ( o desde un pagina web).
Hoy, día de año nuevo, vamos a ver lo sencillo que es construir un enchufe inteligente mediante la plataforma Cayenne y utilizando el económico módulo wifi ESP8266

Con esta solución se consiguen varios objetivos:
- Control local y remoto – el dispositivo basado en Cayenne puede ser fácilmente encendido/apagado usando la aplicación para smartphone Cayenne o desde la página web de Cayenne.
- Motion Control – puede automáticamente encender o apagar con su presencia así como activar o desactivar esta opción por medio de la propia app de Cayenne.
- Control por voz – puede activar o apagado el enchufe usando el Asistente de voz de Alexa
- Poder de programación – se puede crear fácilmente horarios de
encendido/apagado para sus dispositivos .También fácilmente puede configurar el temporizador de Cayenne directamente desde la aplicación. - Protección térmica – gracias a un sensor de temperatura incorporado automáticamente se puede apagar aparatos por sobrecalentamiento y notificar esta condicion a través de SMS o correo electrónico.
- Monitorización remota – Por medio de la aplicación de Cayenne se puede monitorear el voltaje, corriente, temperatura y estado del enchufe (o está activado o desactivado).
- Estadísticas de uso de energía – se puede controlar el consumo de energía de los dispositivos conectados y obtener notificaciones.
El circuito
Para este proyecto se usa la siguiente lista de componentes:
- Módulo de ESP8266-12E
- Adaptador DC5V
- Regulador de 3.3V
- Modulo sharp S108T02
- . Sensor de temperatura (DS18B20)
- Sensor Consumo (ACS712)
- Sensor de presencia PIR HC-SR501
- Cables y placa de prototipos.
El circuito no es demasiado complejo pues básicamente consiste en conectar los sensores al ESP8266 , sin olvidar la alimentación de 3.3v obtenida a partir de una fuente standard conmutada de 5v DC y un reductor de 5v y 3.3v DC . Puede usar un viejo cargador de teléfono móvil y realizar la conversión de 5V a 3.3V con un circuito regulador integrado como el AMS1117 . También puede alimentar con 5v el circuito usando directamente un micro-usb.
Usaremos el sensor digital de temperatura DS18B20 con bus de hilo de Maxim IC , componente muy usado por cierto en muchos proyectos de registro de datos y control de temperatura
Este chip envia al bus I2C la información de la temperatura exterior en grados C con precisión 9-12 bits, -55C a 125C (+/- 0.5C).a.
Cada sensor tiene un número de serie único de 64 bits grabado en él lo cual permite un gran número de sensores que se utilizarán en un bus de datos.
Para medir el interior temperatura del enchufe se usa el sensor de temperatura DS18B20 que alimentaremos con 5v DC desde el propio ESP8266 .Respecto a la salida digital del sensor de temperatura lo conectaremos a la una entrada digital por el pin 13.
Como vemos en el esquema anterior , el sensor de proximidad lo conectaremos al pin 4 digital y también a la alimentación de 5v DC de la placa.
Respecto al sensor de consumo , éste esta basado en el AC712 el cual conectaremos en derivación ( es decir en serie ) con la carga AC y a su vez con el modulo sharp S108T02 (que es un relé de estado solido ) que a su vez llevaremos al enchufe para conectar la carga que deseamos controlar.
El modulo sharp S108T02 (que es un relé de estado solido ) lo comandaremos directamente con una salida digital por medio del pin 5 ( al pin+) y masa . No debemos confundir los pines de control (+-) con lo pines de la carga AC controlar rotulados con el signo de ca .
Respecto al sensor de consumo eléctrico, nos basaremos en el modulo ACS712 , el cual asimismo también debe conectarse a la carga en serie como ya comentábamos . Para evitar precisamente problemas en las conexiones , el modulo ACS712 cuenta con dos terminales atornillables para conectar aquí la carga en serie y justo en el lado opuesto tres pines donde conectaremos la alimentación y el pin de datos (OUT) que soldaremos al pin analógico (ADC) del ESP8266
El modulo ACS712 puede medir hasta 30 amperios gracias a su tamaño compacto fácil de usar basándose en el Chip IC de producto: ACS712ELC 30 A . Su tensión de alimentación es de 5V y la tensión de salida con corrientes de hasta 30A es de185 mV/A siendo el rango de temperatura de funcionamiento entre -40 °C a 85 °C
Rrefiriéndonos al sensor PIR podemos conectar un sensor PIR HC-SR501 que alimentaremos a 5v DC
El modelo HC-SR501HC-SR501 es un Sensor infrarrojo de bajo coste (menos de 2€ por modulo en Amazon) con placa de circuito de control donde se pueden ajustar la sensibilidad y el tiempo de retención gracias a dos resistencias ajustables que dispone en un lateral.
La gama de voltaje de trabajo es DC 5V-20V con un consumo de corriente de menos de 60uA. La salida es binaria digital siendo el voltaje de salida de 3,3 V para un nivel alto o “1” logico y 0V para el cero lógico (no detección de movimiento).
Lo primero que hacemos es conocer el pinout del HC-SR501, pero rápidamente al ver la serigrafía de la placa, queda perfectamente claro :GND para la masa , VCC para la alimentación (que tomaremos desde la Orange Pi ) y un pin de salida (OUT) que será el que nos indique si ha detectado algún movimiento.
Luego lleva un par de resistencia variables o potenciómetros que nos permiten ajustar los parámetros de sensibilidad y duración de la señal, es decir, durante cuanto tiempo vamos a querer que en pin OUT tener la salida informada.
El primer potenciómetro hacia la derecha sirve para ajustar la distancia de modo que el , rango de detección aumenta (unos 7 metros), por el contrario, la gama de detección disminuye (unos 3 metros).El otro potenciómetro rotándolo a la derecha sirve para retrasar el retardo de sensor a tiempos más largos (sobre 300s).Si se gira la contrario el retardo sera corto (sobre 5).
Plataforma Cayenne
Gracias a la plataforma de Cayenne , de la que hemos hablado en este blog en numerosas ocasiones es bastante sencillo monitorizar cualquier variable física de un modo realmente sencillo simplemente haciendo drug &drop desde el panel de control de Cayenne utilizando internet sin tener conocimientos de programación conseguiendo asi controlar o monitorizar una carga AC a en tan solo unos minutos .
En efecto, gracias a un framework genérico desarrollado por myDevices IO Project Builder llamado Cayenne , los desarrolladores , fabricantes y también aficionados pueden construir rápidamente prototipos y proyectos que requieran controlar o monitorizar cualquier cosa conectada a una placa con conectividad , permitiendo con una sóla cuenta gratuita de Cayenne, crear un número ilimitado de proyectos mediante una solución muy sencilla basada en arrastrar y soltar
Para probar Cayenne con el ESP12E necesitamos programar su ESP-12E para conectarse a su punto de acceso wifi (el código fuente a subir se puede descargar desde https://codebender.cc/embed/sketch:398516)
Como hemos hablado en muchas ocasiones de Cayenne pues en realidad está concebido para que su manejo sea realmente sencillo de configurar, de modo que nos iremos a su url : https://cayenne.mydevices.com/
Tras registrarnos nos iremos al panel de control ,pulsaremos en Add new y seleccionamos generic ESP8266
A continuación nos ofrece la API key que deberemos añadir al sw del ESP12E y tras reiniciarlo ya debería poderse comunicar con el node de Cayenne
Ahora la placa está configurada con el MQTT ( username /pwd) así como con conectividad wifi , de modo que ya debería de poder conectarse al framework de Cayenne y podemos seguir hacia adelante añadiendo sensores que deberán estar de acuerdo con el sw instalado en el ESP12E
Para visualizar los datos y controlar el dispositivo basta con añadir el widget apropiado usando arrastrar y soltar el método por lo que en primer lugar, es necesario determinar los parámetros que quieres monitorear.
Cayenne utilizar un canal separado para cada parámetro y necesita definir cuándo configurar un widget para cada funcionalidad
Estos son algunos de los widges que podemos usar para este circuito :

Como vemos ,en este caso , como se aprecia en la pantalla anterior se han añadido:
- Dos valor pantalla Widgets para mostrar temperatura y corriente.
- Un calibrador de pantalla Widget para mostrar el voltaje.
- Un 2 Widget de pantalla de estado para monitorear el estado de la clavija
- Tres botón controlador Widget para el torneado de encendido y apagado el enchufe, proximidad de activación/desactivación y activación/desactivación temporizador.
- Un regulador controlador Widget para ajustar la hora.
- Una línea gráfico pantalla Widget para mostrar el índice de consumo de energía.
- Dos disparadores, uno por automático apagado si se sobrecalienta y otra para correo electrónico y notificación por SMS.
Básicamente el código a subir al ESP12E usa 5 librerías: tres de Cayenne donde tendremos que definir el SSID y la pwd de la red wifi así como las credenciales de Cayenne , una cuarta de temporización para enviar muestras a intervalos prefijados ( que obviamente podemos cambiar )
Es de destacar la creación de dos puertos virtuales para capturar los valores en tiempo real de la temperatura y la humedad tomadas ambas del DHTXX , lo cual nos van a permitir comunicarnos con el API de Cayenne.
Este es un ejemplo muy sencillo de utilización:
Md Hairul ha compartido el código de su prototipo mediante licencia GPL, código, el cual para que sea mas legible hemos añadido unos breves lineas explicatorias.
// usado para enviar datos a la nube Cayenne
#include "CayenneDefines.h"
#include "CayenneWiFi.h"
#include "CayenneWiFiClient.h"
// Incluye las bibliotecas para el sensor de temperatura DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
// Habilitando la voz de Alexa
include "WemoSwitch.h"
include "WemoManager.h"
include "CallbackFunction.h"
WemoManager wemoManager;
WemoSwitch *light = NULL;
// configurar la depuración de cayenne
define CAYENNE_PRINT Serial
// tipos de datos
define TYPE_DIGITAL_SENSOR "digital_sensor"
define TYPE_VOLTAGE "voltage"
define TYPE_CURRENT "current"
// tipos de unidades
define UNIT_DIGITAL "d"
define UNIT_VOLTS "v"
define UNIT_AMP "a"
// El pin e datos está conectado al puerto 2 del ESP8622
define ONE_WIRE_BUS 2
// Configurar una instancia de OneWire para comunicarse con cualquier dispositivo OneWire (no solo IC de temperatura Maxim / Dallas)
OneWire oneWire(ONE_WIRE_BUS);
// Pasar la referencia oneWire al sensor de temperatura.
DallasTemperature sensors(&oneWire);
define PLUG 5
define pirPin 4
//variables
int timer_flag = 0;
int timer_time = 120;
int pir_flag = 0;
long timer_millis = 0;
int calibrationTime = 30;
long unsigned int lowIn;
long unsigned int pause = 60000;
boolean lockLow = true;
boolean takeLowTime;
int PIRValue = 0;
unsigned long lastMillis = 0;
int mVperAmp = 185; // usar 100 para el modulo de 20A y 66 para el módulo
int RawValue= 0;
int ACSoffset = 500; //solo para el modulo esp8266
double Voltage = 0;
double current = 0;
float temp = 0;
// Información de la red WiFi que debe personalizarse con lso datos de su red.
const char ssid[] = "xxxxxxxx";
const char wifiPassword[] = "xxxxxxxxx";
// información de autentificación Cayenne que deben obtenerse desde el tablero de Cayenne.
const char username[] = "xxxxxxxxxxxxxxxxxxxxxx";
const char password[] = "xxxxxxxxxxxxxxxxxxxxxx";
const char clientID[] = "xxxxxxxxxxxxxxxxxxxxxx";
void setup() {
Serial.begin(9600);
pinMode(PLUG, OUTPUT);
pinMode(pirPin, INPUT);
//configurar cayenne
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
// Poner en marcha la biblioteca de sensores de temperatura
sensors.begin();
// iniciar wemo library
wemoManager.begin();
// Formato: Alexa invocation name, local port no, on callback, off callback
light = new WemoSwitch("Smart Plug", 80, plugOn, plugOff);
wemoManager.addDevice(*light);
delay(100);
digitalWrite(PLUG, LOW);
}
void loop() //aquí comienza el bucle infinito de lecturas y envios
{
Cayenne.loop();
wemoManager.serverLoop();
if(timer_flag){
check_time();
}
if(pir_flag)
{
PIRSensor();
}
read_temperature();
int voltage = 220; // definir voltaje standard
read_current();
float energy = 0.7 * voltage * current * millis()/(1000 * 60);
//en kWh, asumiendo un factor de potencia de 0.7
if (millis() - lastMillis > 10000)
{
lastMillis = millis();
// Enviar datos a Cayenne desde aquí.
//Este ejemplo simplemente envía el tiempo de actividad actual en milisegundos.Cayenne.virtualWrite(1, voltage, TYPE_VOLTAGE, UNIT_VOLTS);
Cayenne.virtualWrite(2, current, TYPE_CURRENT, UNIT_AMP);
Cayenne.virtualWrite(3, temp, TYPE_TEMPERATURE, UNIT_CELSIUS);
Cayenne.virtualWrite(4, energy, TYPE_ENERGY, UNIT_KW_PER_H);
}
}
CAYENNE_IN(5)
// recepción de datos del canal 5 (encendido / apagado)
{
int value = getValue.asInt(); //aceptar y convertir valor a entero
Serial.println(value);
digitalWrite(PLUG, value); //cambiar el estado de
Cayenne.virtualWrite(7, value, TYPE_DIGITAL_SENSOR, UNIT_DIGITAL);
}
CAYENNE_IN(6)
// recepción de datos del canal 6 (encendido / apagado)
{
int value = getValue.asInt(); //aceptar y convertir valor a entero
Serial.println(value);
timer_time = value;
}
CAYENNE_IN(8)
//Datos recibidos desde el canal 6 de proximidad on / off
{
int value = getValue.asInt(); //accept and convert value to Int
Serial.println(value);
pir_flag = value;
}
CAYENNE_IN(10)
// recepción de datos del temporizador de activación / desactivación del canal 6
{
int value = getValue.asInt();// aceptar y convertir valor a Int
Serial.println(value);
timer_flag = value;
timer_millis = millis();
}
// Función predeterminada para procesar comandos del actuador desde el Tablero de Cayenne.
//También puede usar funciones para canales específicos, por ejemplo, CAYENNE_IN (1) para los comandos del canal 1.
CAYENNE_IN_DEFAULT()
{
CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, %s", request.channel, getValue.getId(), getValue.asString());
//Procesar mensaje aquí. Si hay un error, establezca un mensaje de error utilizando getValue.setError (),
//por ejemplo, getValue.setError ("Mensaje de error");
}
void read_temperature(){
// llamada a sensores.requestTemperaturas () para emitir una temperatura global // solicitud a todos los dispositivos en el bus
Serial.print("Recuperando temperaturas…");
sensors.requestTemperatures(); // Envía el comando para obtener temperaturas.
Serial.println("HECHO");
// Después de que tengamos las temperaturas, podemos imprimirlas aquí. // Usamos la función ByIndex, y como ejemplo obtenemos la temperatura solo del primer sensor.
Serial.print("Temperatura para el dispositivo 1 (indice 0) es: ");
temp = sensors.getTempCByIndex(0);
Serial.println(temp);
}
void read_current()
{
//1000 lecturas analógicas para promediar
for(int i = 0; i < 1000; i++)
{
RawValue = RawValue + analogRead(A0); // agregar cada lectura A / D a un total
}
Voltage = ((RawValue / 1000) / 1023.0) * 1000;
// Gets you mV, max is 1000mV
current = ((Voltage - ACSoffset) / mVperAmp);
}
void check_time()
{
if(((millis()-timer_millis)/60000) > timer_time)
{
digitalWrite(PLUG, !digitalRead(PLUG));
Cayenne.virtualWrite(7, !digitalRead(PLUG), TYPE_DIGITAL_SENSOR, UNIT_DIGITAL);
timer_flag = 0;
}
}
void PIRSensor()
{
if(digitalRead(pirPin) == HIGH)
{
if(lockLow)
{
PIRValue = 1;
lockLow = false;
Serial.println("Movimiento detectado.");
digitalWrite(PLUG, HIGH);
Cayenne.virtualWrite(7, 1, TYPE_DIGITAL_SENSOR, UNIT_DIGITAL);
delay(50);
}
takeLowTime = true;
}
if(digitalRead(pirPin) == LOW) {
if(takeLowTime){
lowIn = millis();takeLowTime = false;
}
if(!lockLow && millis() - lowIn > pause) {
PIRValue = 0;
lockLow = true;
Serial.println("Movimiento terminado.");
digitalWrite(PLUG, LOW);
Cayenne.virtualWrite(7, 0, TYPE_DIGITAL_SENSOR, UNIT_DIGITAL);
delay(50);
}
}
}
void plugOn()
{
Serial.print("Conmutar 1 a encendido …");
digitalWrite(PLUG, HIGH);
Cayenne.virtualWrite(7, 1, TYPE_DIGITAL_SENSOR, UNIT_DIGITAL);
}
void plugOff()
{
Serial.print("Conmutar 1 a apagado …");
digitalWrite(PLUG, LOW);
Cayenne.virtualWrite(7, 0, TYPE_DIGITAL_SENSOR, UNIT_DIGITAL);
}
En el siguiente vídeo podemos ver el resultado de este interesante proyecto
Debe estar conectado para enviar un comentario.