2. Actuador Binario: Tomacorriente ESP-01

El dispositivo se enfoca en controlar un tomacorriente AC usando un relé, es presentado como base para el desarrollo de otros circuitos.

Premisas para el desarrollo del prototipo, versión 1:

  • Supone que ya se ha implementado un Broker MQTT
  • Dispone de Arduino IDE para cargar las instrucciones en el ESP9266-01
  • Dispone de una base para el desarrollo de dispositivos, verificando funcionamiento de WIFI y MQTT, en formato DIY (Do It Yourself)
  • Identifica otros elementos de desarrollo e inconvenientes para la implementación.
  • Usa diseños abiertos tipo: Open hardware y Open software
  • Usa componentes disponibles en el mercado local.
  • Considera alternativas para los componentes que solo se puedan conseguir por internet
  • Conecta dispositivos por medios inalámbricos.

Para activar el Sensor Binario en la plataforma con Raspberry, consulte la sección de Broker, donde se detallan las instrucciones.


Esquema de conexión:

Actuador Binario para controlar un elemento eléctrico AC de baja potencia como elemento complementario a un interruptor de control.

Por ejemplo, una luz iluminación y un interruptor de pared.

El actuador binario responde al interruptor de forma tradicional, sin embargo, al usar el Broker cambiará al estado deseado. El estado del interruptor físico puede volver a usarse para obtener el resultado deseado.

El límite de capacidad del dispositivo está dado por el Relé usado en el circuito.

Para activar el Sensor Binario en la plataforma con Rasberry, consulte la sección de Broker, donde se detallan las instrucciones.


Esquema Propuesto

La alimentación de energía se realiza con 110V AC. La reducción al voltaje de operación del ESP8266-01 se realiza en dos pasos: 5VDC y luego 3.3V DC, considerando la disponibilidad de:

  • Relé con voltaje de operación de 5V DC
  • Regulador de voltaje de 110V a 5 V DC

Protoboard

Para probar el circuito se puede armar en un protoboard.
Considere que solo por Esquema se incluye la parte de conexión AC, que se debe realizar separada y tomando las precauciones de aislamiento que correspondan.

Instrucciones Arduino

En este caso, como la versión del ESP8266-01 no dispone de muchos pines de trabajo, se usa como:

  • monitor de operación del dispositivo al LED interno (pin1 y TX)

Por el uso en operación de los pines de comunicación Serial (pines 1 y 3) se descartan las lineas Serial.print() convirtiéndolas en comentarios //.

A diferencia del modelo usado con el sensor binario, se requiere un pin adicional para la señal del actuador para controlar el Relé. Se seleccionó el PiN 2/GPIO_2 pues la configuración usada no presenta inconvenientes al momento del inicio del dispositivo en el modo requerido de trabajo: GPIO_0 y GPIO_2 en ALTO.

/*
 TOMACORRIENTE  | AC outlet
 Basic ESP8266 MQTT example with the ESP8266 board/library.
 Actuador Binario, para control de estado de una Luz.
 Para usar, se debe actualizar las secciones de:
 - WIFI datos para conexión a Router
 - MQTT: Servidor MQTT 
 - MQTT: identificador de dispositivo y topics
 Al usar ESP8266-01 se toman los pines TX para LED y GPI02 actuador
 por lo que se no se usa Serial.print(), con mesajes usado para depuración.
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// WIFI datos para conexión a Router
const PROGMEM char* ssid = "---";
const PROGMEM char* password = "---";

// MQTT: Servidor MQTT 
const PROGMEM char* MQTT_SERVER_IP = "192.168.xx.xxx";
const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
const PROGMEM char* MQTT_USER = "username";
const PROGMEM char* MQTT_PASSWORD = "password";

// MQTT: identificador de dispositivo y topics
const PROGMEM char* MQTT_CLIENT_ID = "luz1";
const PROGMEM char* MQTT_SENSOR_TOPIC = "oficina/luz1/contact";
const PROGMEM char* MQTT_SENSOR_COMMAND_TOPIC = "oficina/luz1/switch";
const PROGMEM char* SENSOR_ON  = "ON";
const PROGMEM char* SENSOR_OFF = "OFF";
char MQTT_SENSOR_STATE[10] = "OFF"; // inicializa

// Actuador Switch Luz
const PROGMEM uint8_t ACTUADOR_pin = 2;

// LED monitor interno
const PROGMEM uint8_t LED_pin = 1; //ESP01-pin=1

// Control de tiempos
unsigned long antes = 0; 
const long intervalo = 300;

WiFiClient wifiClient;
PubSubClient client(wifiClient);

void setup() {
    // Conexion serial
    // Serial.begin(115200);

    // SENSOR Binario
    pinMode(SENSOR_pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(SENSOR_pin),SensorActivado,CHANGE);
    
    // ACTUADOR Binario
    pinMode(ACTUADOR_pin, OUTPUT);
    digitalWrite(ACTUADOR_pin, HIGH);
    ACTUADORactivaestado();
    
    // LED monitor
    pinMode(LED_pin, OUTPUT);
    LEDactivaestado();
    
    // conexión WIFI y MQTT
    inicia_wifi();
    inicia_mqtt();
}

void loop() {
    if(WiFi.status() != WL_CONNECTED){
        inicia_wifi();
        }
    if (!client.connected()){
        inicia_mqtt();
        }
    client.loop();
    if (SENSOR_bandera){
        SENSOR_estado = digitalRead(SENSOR_pin);
        
        // Serial.println("Actualiza LED");
        LEDactivaestado();
        ACTUADORactivaestado();
        
        // actualiza estado del Sensor en MQTT
        if (SENSOR_estado){
            snprintf (MQTT_SENSOR_STATE,10, SENSOR_ON);
        }else{
            snprintf (MQTT_SENSOR_STATE,10, SENSOR_OFF);
        }
        // Serial.print("Sensor, estado: ");
        // Serial.println(MQTT_SENSOR_STATE);
        
        client.publish(MQTT_SENSOR_TOPIC,MQTT_SENSOR_STATE);
        client.subscribe(MQTT_SENSOR_COMMAND_TOPIC);

        SENSOR_bandera=false;
    }
    delay(10);
}

void inicia_wifi() {
    // conexion WiFi
    //Serial.print("\n Conectando a ");
    //Serial.println(ssid);
    WiFi.begin(ssid, password);
    int cuenta = 0;
    while (WiFi.status() != WL_CONNECTED){
        //Serial.print(".");
        cuenta = cuenta+1;
        if (cuenta>=40){
            //Serial.println();
            cuenta = 0;}
        // LED interno enciende en LOW
        digitalWrite(LED_pin, LOW);
        delay(250);
        digitalWrite(LED_pin, HIGH);
        delay(250);
        }
    //Serial.print("\n WiFi conectado \n Dirección IP: ");
    //Serial.println(WiFi.localIP());
    delay(10);
}

void inicia_mqtt(){
    client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
    client.setCallback(callback);
    while (!client.connected()) {
        //Serial.println("\n Conectando a MQTT ");
        if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
            //Serial.println(" MQTT conectado");  
        } else {
            //Serial.print("Falló, estado: ");
            //Serial.print(client.state()); 
            //Serial.print(" , reintento en 5 segundos");
            // LED interno enciende en LOW
            for (int i=0;i<=5;i=i+1){
                digitalWrite(LED_pin, LOW);
                delay(600);
                digitalWrite(LED_pin, HIGH);
                delay(400);
            }
        }
    }
    client.publish(MQTT_SENSOR_TOPIC, MQTT_SENSOR_STATE);
    client.subscribe(MQTT_SENSOR_COMMAND_TOPIC);
}

// llega mensaje MQTT
void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
    // convierte a cadena
    String payload;
    for (uint8_t i = 0; i < p_length; i++) {
        payload.concat((char)p_payload[i]);
        }
    // analiza mensaje por topico
    if (String(MQTT_SENSOR_COMMAND_TOPIC).equals(p_topic)) {
        if (payload.equals(String(SENSOR_ON))) {
            if (SENSOR_estado != true) {
                SENSOR_estado = true;
                LEDactivaestado();
                ACTUADORactivaestado();
                SENSORpublicaestado();
                }
        } else if (payload.equals(String(SENSOR_OFF))) {
            if (SENSOR_estado != false) {
                SENSOR_estado = false;
                LEDactivaestado();
                ACTUADORactivaestado();
                SENSORpublicaestado();
                }
        }
    }
}

// Publicar el estado del dispositivo
void SENSORpublicaestado() {
    if (SENSOR_estado) {
        client.publish(MQTT_SENSOR_TOPIC, SENSOR_ON, true);
    }else{
        client.publish(MQTT_SENSOR_TOPIC, SENSOR_OFF, true);
    }
    client.subscribe(MQTT_SENSOR_COMMAND_TOPIC);
    
}

// establece estado LED monitor en ESP8266
void LEDactivaestado(){
    if (SENSOR_estado){
        // LED interno enciende en LOW
        digitalWrite(LED_pin, LOW);
    }else{
        digitalWrite(LED_pin, HIGH);
    }
}