Controlando las puertas de un garaje con un ESP32 - Parte 2

ESP32 - Relay - Sensor wiring

*ESP32 - Relay - Sensor wiring*

En esta segunda entrada de esta serie, veremos como conectar un par de interruptores magnéticos, uno para cada puerta, los cuales nos permitirán saber si las puertas están cerradas o no.

En este caso, estoy usando este interruptor: https://www.adafruit.com/product/375.

El interruptor tiene dos cables, uno va a tierra (GND) y el otro a uno de los GPIO de nuestro micro controlador. En este caso uso los GPIOs 25 y 26 para las puertas izquierda y derecha respectivamente.

Con esta nueva adición, nuestro esquema sería algo así:

ESP32 - Relay - Sensor schematics

*ESP32 - Relay - Sensor schematics*

He actualizado el repositorio con el código necesario para manejar estos nuevos sensores. Todos los cambios se han hecho en el fichero main/app_main.c. A continuación veremos las partes del código relevantes a esta entrada:

static const char *LEFT_DOOR_STATUS_TOPIC = "garage/door/left/status";
static const char *RIGHT_DOOR_STATUS_TOPIC = "garage/door/right/status";
...
#define LEFT_DOOR_SENSOR_GPIO 25
#define RIGHT_DOOR_SENSOR_GPIO 26

Aquí podemos ver cuatro constantes nuevas, dos para definir los canales por los que se recibirá y enviará la información relevante a los interruptores, y otras dos para definir los GPIO a los que estos se conectarán.

En la parte de inicialización:

gpio_set_direction(LEFT_DOOR_SENSOR_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(RIGHT_DOOR_SENSOR_GPIO, GPIO_MODE_INPUT);
gpio_pullup_en(LEFT_DOOR_SENSOR_GPIO);
gpio_pullup_en(RIGHT_DOOR_SENSOR_GPIO);

Establecemos el modo de los GPIOs como entrada (INPUT), ya que vamos a leer el estado de estos, y los ponemos en modo alto (pullup)

case MQTT_EVENT_CONNECTED:
    ...
    msg_id = esp_mqtt_client_subscribe(client, LEFT_DOOR_STATUS_TOPIC, 0);
    ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

    msg_id = esp_mqtt_client_subscribe(client, RIGHT_DOOR_STATUS_TOPIC, 0);
    ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

En esta parte se muestra que, cuando nos conectamos al servidor MQTT, nos suscribimos a los dos canales (topics) que acabamos de definir, para así recibir la información que se envíen por ellos.

Y por último:

if (strcmp(topic, LEFT_DOOR_TOPIC) == 0) {
  ...
} else if (strcmp(topic, RIGHT_DOOR_TOPIC) == 0) {
  ...
} else if (strcmp(topic, LEFT_DOOR_STATUS_TOPIC) == 0) {
    if (strcmp(data, "get") == 0) {
        if (gpio_get_level(LEFT_DOOR_SENSOR_GPIO)) {
            esp_mqtt_client_publish(client, LEFT_DOOR_STATUS_TOPIC, "status:open", 0, 0, 0);
        } else {
            esp_mqtt_client_publish(client, LEFT_DOOR_STATUS_TOPIC, "status:closed", 0, 0, 0);
        }
    }
} else if (strcmp(topic, RIGHT_DOOR_STATUS_TOPIC) == 0) {
    if (strcmp(data, "get") == 0) {
        if (gpio_get_level(RIGHT_DOOR_SENSOR_GPIO)) {
            esp_mqtt_client_publish(client, RIGHT_DOOR_STATUS_TOPIC, "status:open", 0, 0, 0);
        } else {
            esp_mqtt_client_publish(client, RIGHT_DOOR_STATUS_TOPIC, "status:closed", 0, 0, 0);
        }
    }
}

Aquí es donde decidimos que hacer cuando nos llega un mensaje. Vemos que sólo respondemos cuando recibimos el mensage get, en cuyo caso, leemos el estado del sensor (izquierdo o derecho, dependiendo del canal por el que nos llegue el mensaje) con la función gpio_get_level(….), y si el resultado es true (distinto de 0), devolvemos el mensaje status:open, o en caso contrario devolvemos status:closed.

Aquí os dejo un pequeño vídeo mostrando la funcionalidad descrita en esta entrada, usando un sólo sensor:

Si te perdiste la primera entrada de este seria, la puedes ver en Parte 1

This post is also available in English