1. Sensor Binario Puerta-Ventana ESP-01

Sensor binario para registrar el estado abierto o cerrado de una puerta o ventana.

El dispositivo es de tipo inalámbrico, WIFI, usa protocolo MQTT para comunicación con el broker y es implementado con ESP8266 versión ESP-01

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 Propuesto

La alimentación de energía se realiza con 110V AC. Se requiere usar un regulador de voltaje para llegar hasta a 3.3V DC que es el voltaje de operación del ESP8266-01.

Por disponibilidad de componentes, la implementación se realiza dos pasos:

  •  Reducción de 110V AC a 5V DC
  •  Reducción de 5V DC a 3.3V DC

Los pasos se pueden simplificar si se dispone del componente HLK-PM03, que realiza la reducción completa hasta 3.3V.

Alternativas a componentes

Se comprobó el funcionamiento sustituyendo el regulador de 110VAC a 5V por un cargador USB a 5V de los usado para teléfonos celulares.
Considere que se midieron voltajes aproximados a 5V DC

No fué posible durante la semana de desarrollo obtener localmente un HLK-PM-01 y un regulador DC de 5V  a 3.3 V. De se optó por usar diodos para disminuir el voltaje hasta lo requerido.

Otra opciónes para 5V a 3.3V:

  • usar diodos Zener de 3.3V
  • conección de diodos en modo de paso para caidas de 0.7V por cada diodo.

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.


Circuito impreso – PCB

Se adjunta la imagen de la placa del circuito impreso realizada con Fritzing en vista superior.

Para el archivo de producción de placa, escribir al email de contacto al final de la página.

Alternativas durante el proceso de desarrrollo

Durante el desarrollo del prototipo se usó una placas perforadas de circuito impreso de 4×6 cm.

Luego de algunas pruebas, se dispondrá del diseño mejorado y se actualizará la versión 1 del circuito impreso.


Instrucciones Arduino

En éste 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 (TX)
  • sensor el pin 3 que también puede ser configurado como RX

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

La carga del archivo.ino se la realiza fuera del circuito. Una vez cargado el script se inserta el ESP8266 en la placa.

Las instrucciones para iniciar WIFI y MQTT se realizaron de forma separada en funciones como base para otros dispositivos.

/*
 Basic ESP8266 MQTT example with the ESP8266 board/library.
 Sensor Binario, para control de estado de puerta/ventana.
 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 RX para el sensor,
 por lo que se no se usa Serial.print(), con mesajes usador para depuración.
*/

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

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

// 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"; // sustituir
const PROGMEM char* MQTT_PASSWORD = "password";

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

// Sensor puerta
const PROGMEM uint8_t SENSOR_pin = 3;
volatile boolean SENSOR_estado = false;
volatile boolean SENSOR_bandera = false;

// LED monitor interno
const PROGMEM uint8_t LED_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);
    
    // 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();
        
        // 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_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_TOPIC);
}

void callback(char* topic, byte* payload, unsigned int length) {
    // Serial.print("\n MQTT Mensaje :");
    // Serial.print(topic);
    // Serial.print(" , ");
    for (int i = 0; i < length; i++) {
        // Serial.print((char)payload[i]);
    }
    // Serial.println();
    // client.subscribe(MQTT_SENSOR_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);
    }
}

// ISR interrupción activada
void SensorActivado(){
    // Serial.println("ISR activada");
    unsigned long ahora = millis();
    if((ahora - antes)> intervalo) {
        antes = ahora;
        SENSOR_bandera = true;
    }
}

Temas para desarrollo posterior

  • Otros dispositivos, actuadores
    Ampliar la forma de carga de scripts en el tablero, de forma alámbrica o inalámbrica.
  • Analizar consumos de corriente para uso con baterías.
  • Revisar el uso de los canales WIFI para evitar desconexiones por saturación de canal.

implementación versión 1

Instalado en una caja eléctrica en una puerta.