Configuración de pines y librerías para el sensor DHT11

Conexiones físicas, librerías necesarias, configuración de pines GPIO

Módulo 2 ⏱️ 2 horas 🛠️ ESP32 + DHT11 🌐 Flask + MQTT

Introducción

En esta clase aprenderemos la configuración completa del sensor DHT11 con ESP32, incluyendo las conexiones físicas, instalación de librerías necesarias y configuración de pines GPIO. El DHT11 es un sensor de temperatura y humedad ampliamente utilizado en proyectos IoT debido a su simplicidad y bajo costo.

Integraremos este sensor en nuestro stack tecnológico completo: ESP32 como microcontrolador, Mosquitto como broker MQTT para comunicación, y Flask como framework web para visualización de datos. Esta configuración forma la base de muchos sistemas de monitoreo ambiental profesionales.

Objetivos de la clase:
  • Entender las especificaciones técnicas del DHT11
  • Realizar conexiones físicas correctas
  • Configurar librerías y pines GPIO
  • Implementar comunicación MQTT
  • Crear interfaz web con Flask

Conceptos Fundamentales

Especificaciones del DHT11

El DHT11 es un sensor digital de temperatura y humedad que utiliza un protocolo de comunicación propietario de un solo cable:

  • Rango de temperatura: 0-50°C (±2°C precisión)
  • Rango de humedad: 20-90% RH (±5% RH precisión)
  • Voltaje de operación: 3.5-5.5V DC
  • Corriente: 0.3mA (medición), 60µA (standby)
  • Frecuencia de muestreo: Máximo 1Hz (1 muestra por segundo)

Pinout del DHT11

Pin Nombre Descripción
1 VCC Alimentación (3.3V-5V)
2 DATA Señal de datos (bidireccional)
3 NC No conectado
4 GND Tierra

Pines GPIO del ESP32

El ESP32 tiene múltiples pines GPIO que pueden utilizarse para el DHT11. Es importante seleccionar pines que no interfieran con otras funciones:

  • Pines recomendados: GPIO 4, 16, 17, 18, 19, 21, 22, 23
  • Pines a evitar: GPIO 0, 2 (boot), GPIO 6-11 (flash), GPIO 1, 3 (UART)
  • Pull-up interno: El ESP32 puede activar resistencias pull-up internas

Protocolo de Comunicación DHT11

El DHT11 utiliza un protocolo de comunicación específico:

  • Inicio: MCU envía señal de inicio (LOW por 18ms)
  • Respuesta: DHT11 responde con señal de sincronización
  • Datos: 40 bits de datos (16 humedad + 16 temperatura + 8 checksum)
  • Timing crítico: Requiere timing preciso para lectura correcta

Implementación Práctica

Conexiones Físicas

Diagrama de conexiones para ESP32 DevKit v1:

ESP32 DevKit v1    →    DHT11
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3.3V               →    VCC (Pin 1)
GPIO 4             →    DATA (Pin 2)
                        NC (Pin 3) - No conectar
GND                →    GND (Pin 4)

Resistencia pull-up de 10kΩ entre VCC y DATA (opcional con ESP32)
            

Instalación de Librerías

En Arduino IDE, instalar las siguientes librerías desde el Library Manager:

Librerías necesarias:


/*
Librerías a instalar en Arduino IDE:
1. DHT sensor library by Adafruit (versión 1.4.4 o superior)
2. Adafruit Unified Sensor by Adafruit
3. PubSubClient by Nick O'Leary (para MQTT)
4. ArduinoJson by Benoit Blanchon (para formateo JSON)
*/

// Includes necesarios en el código
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
            

Configuración completa del ESP32 con DHT11:


#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>

// Configuración DHT11
#define DHT_PIN 4          // GPIO 4 para datos del DHT11
#define DHT_TYPE DHT11     // Tipo de sensor DHT
DHT dht(DHT_PIN, DHT_TYPE);

// Configuración WiFi
const char* ssid = "Tu_Red_WiFi";
const char* password = "Tu_Password_WiFi";

// Configuración MQTT
const char* mqtt_server = "localhost";  // IP del broker Mosquitto
const int mqtt_port = 1883;
const char* mqtt_user = "esp32_user";
const char* mqtt_password = "esp32_pass";
const char* client_id = "ESP32_DHT11_001";

// Tópicos MQTT
const char* topic_temperature = "sensors/dht11/temperature";
const char* topic_humidity = "sensors/dht11/humidity";
const char* topic_status = "sensors/dht11/status";

// Objetos WiFi y MQTT
WiFiClient espClient;
PubSubClient client(espClient);

// Variables de tiempo
unsigned long lastMsg = 0;
const unsigned long MSG_INTERVAL = 30000; // 30 segundos entre lecturas

void setup() {
    Serial.begin(115200);
    Serial.println("Iniciando ESP32 con DHT11...");
    
    // Inicializar DHT11
    dht.begin();
    Serial.println("DHT11 inicializado en GPIO " + String(DHT_PIN));
    
    // Configurar WiFi
    setup_wifi();
    
    // Configurar MQTT
    client.setServer(mqtt_server, mqtt_port);
    client.setCallback(callback);
    
    // Mensaje de inicio
    Serial.println("Sistema listo. Intervalo de lectura: " + String(MSG_INTERVAL/1000) + " segundos");
}

void setup_wifi() {
    delay(10);
    Serial.println();
    Serial.print("Conectando a ");
    Serial.println(ssid);
    
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    
    int attempts = 0;
    while (WiFi.status() != WL_CONNECTED && attempts < 20) {
        delay(500);
        Serial.print(".");
        attempts++;
    }
    
    if (WiFi.status() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("WiFi conectado!");
        Serial.println("IP asignada: ");
        Serial.println(WiFi.localIP());
    } else {
        Serial.println("Error: No se pudo conectar al WiFi");
        ESP.restart();
    }
}

void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Mensaje recibido [");
    Serial.print(topic);
    Serial.print("]: ");
    
    String message;
    for (int i = 0; i < length; i++) {
        message += (char)payload[i];
    }
    Serial.println(message);
}

void reconnect() {
    while (!client.connected()) {
        Serial.print("Intentando conexión MQTT...");
        
        if (client.connect(client_id, mqtt_user, mqtt_password)) {
            Serial.println("Conectado al broker MQTT");
            client.publish(topic_status, "ESP32_DHT11_ONLINE");
            client.subscribe("sensors/dht11/commands");
        } else {
            Serial.print("Falló conexión MQTT, rc=");
            Serial.print(client.state());
            Serial.println(" reintentando en 5 segundos...");
            delay(5000);
        }
    }
}

void readAndPublishSensorData() {
    // Leer temperatura y humedad
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();
    
    // Verificar si las lecturas son válidas
    if (isnan(humidity) || isnan(temperature)) {
        Serial.println("Error: Falló lectura del sensor DHT11!");
        client.publish(topic_status, "DHT11_READ_ERROR");
        return;
    }
    
    // Mostrar valores en Serial
    Serial.printf("Temperatura: %.2f°C, Humedad: %.2f%%\n", temperature, humidity);
    
    // Crear JSON con los datos
    StaticJsonDocument<200> doc;
    doc["device_id"] = client_id;
    doc["timestamp"] = millis();
    doc["temperature"] = round(temperature * 100) / 100.0;  // Redondear a 2 decimales
    doc["humidity"] = round(humidity * 100) / 100.0;
    doc["heat_index"] = dht.computeHeatIndex(temperature, humidity, false);
    
    char jsonString[200];
    serializeJson(doc, jsonString);
    
    // Publicar datos individuales
    client.publish(topic_temperature, String(temperature, 2).c_str());
    client.publish(topic_humidity, String(humidity, 2).c_str());
    
    // Publicar JSON completo
    client.publish("sensors/dht11/data", jsonString);
    
    Serial.println("Datos publicados via MQTT");
}

void loop() {
    // Mantener conexión MQTT
    if (!client.connected()) {
        reconnect();
    }
    client.loop();
    
    // Verificar conexión WiFi
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Conexión WiFi perdida. Reintentando...");
        setup_wifi();
    }
    
    // Leer y publicar datos del sensor
    unsigned long now = millis();
    if (now - lastMsg > MSG_INTERVAL) {
        lastMsg = now;
        readAndPublishSensorData();
    }
    
    delay(100);  // Pequeña pausa para evitar watchdog reset
}
            

Configuración del broker Mosquitto:


# /etc/mosquitto/mosquitto.conf
port 1883
allow_anonymous true
listener 1883 0.0.0.0

# Para producción, configurar autenticación:
# password_file /etc/mosquitto/passwd
# allow_anonymous false

# Logging
log_dest file /var/log/mosquitto/mosquitto.log
log_type error
log_type warning  
log_type notice
log_type information

# Persistencia
persistence true
persistence_location /var/lib/mosquitto/

# Reiniciar servicio
sudo systemctl restart mosquitto
sudo systemctl enable mosquitto
            

Aplicación Flask para visualización:


from flask import Flask, render_template, jsonify
import paho.mqtt.client as mqtt
import json
import threading
import time
from datetime import datetime

app = Flask(__name__)

# Variables globales para almacenar datos del sensor
sensor_data = {
    'temperature': 0.0,
    'humidity': 0.0,
    'last_update': None,
    'status': 'Desconectado',
    'history': []
}

# Configuración MQTT
MQTT_BROKER = "localhost"
MQTT_PORT = 1883
MQTT_USERNAME = "esp32_user"
MQTT_PASSWORD = "esp32_pass"

def on_connect(client, userdata, flags, rc):
    print(f"Conectado al broker MQTT con código: {rc}")
    if rc == 0:
        sensor_data['status'] = 'Conectado'
        # Suscribirse a todos los tópicos del DHT11
        client.subscribe("sensors/dht11/+")
        client.subscribe("sensors/dht11/data")
    else:
        sensor_data['status'] = 'Error de conexión'

def on_message(client, userdata, msg):
    topic = msg.topic
    payload = msg.payload.decode('utf-8')
    
    print(f"