Introducción al ESP32 y entorno de desarrollo (Arduino IDE / PlatformIO)

Características del ESP32, configuración del entorno de desarrollo, herramientas de programación

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

Introducción

En esta lección exploraremos el ESP32, un microcontrolador de alto rendimiento con conectividad WiFi y Bluetooth integradas, ideal para proyectos de IoT. Aprenderemos a configurar el entorno de desarrollo utilizando Arduino IDE y PlatformIO, y estableceremos las bases para implementar un sistema completo de monitoreo con sensores DHT11, comunicación MQTT a través de Mosquitto, y visualización web con Flask.

Stack Tecnológico del Curso
  • Hardware: ESP32 + Sensor DHT11
  • Comunicación: MQTT con broker Mosquitto
  • Backend: Flask (Python)
  • Entornos de desarrollo: Arduino IDE y PlatformIO

Conceptos Fundamentales

¿Qué es el ESP32?

El ESP32 es un microcontrolador de bajo costo y consumo energético desarrollado por Espressif Systems. Es la evolución del popular ESP8266, ofreciendo mejores prestaciones y más funcionalidades.

Características principales del ESP32:

  • Procesador: Dual-core Xtensa LX6 de 32 bits hasta 240 MHz
  • Memoria: 520 KB SRAM, hasta 4 MB Flash externa
  • Conectividad: WiFi 802.11 b/g/n, Bluetooth 4.2 y BLE
  • GPIO: Hasta 36 pines programables
  • Periféricos: SPI, I2C, UART, PWM, ADC, DAC, RTC
  • Alimentación: 2.2V - 3.6V (típico 3.3V)
  • Consumo: Desde 5µA en deep sleep hasta 240mA en operación

Ventajas del ESP32 para IoT:

  • Conectividad dual (WiFi + Bluetooth) integrada
  • Procesamiento de doble núcleo para multitasking
  • Bajo consumo energético con modos de sleep avanzados
  • Amplio ecosistema de desarrollo (Arduino, ESP-IDF, MicroPython)
  • Precio accesible y alta disponibilidad
  • Soporte para protocolos IoT (MQTT, HTTP, WebSocket)

Pinout del ESP32 DevKit v1

Pines importantes para nuestro proyecto:

  • GPIO 2: LED integrado (útil para debugging)
  • GPIO 4: Conexión para sensor DHT11
  • 3V3: Alimentación 3.3V para el sensor
  • GND: Tierra común
  • EN: Pin de reset/enable
  • GPIO 0: Pin de boot (para programación)

Entornos de Desarrollo

Arduino IDE

  • IDE oficial simplificado y fácil de usar
  • Gran comunidad y abundantes librerías
  • Sintaxis basada en C++ con abstracciones Arduino
  • Compilación e instalación sencilla
  • Ideal para principiantes y proyectos simples

PlatformIO

  • Entorno profesional multiplataforma
  • Gestión avanzada de librerías y dependencias
  • Soporte para múltiples frameworks y placas
  • Debugging avanzado y análisis estático
  • Integración con editores populares (VSCode, Atom)
  • Ideal para proyectos complejos y desarrollo profesional

Implementación Práctica

Configuración del Entorno Arduino IDE

Pasos para configurar Arduino IDE:
  1. Descargar Arduino IDE desde arduino.cc
  2. Abrir Preferencias (Archivo → Preferencias)
  3. Agregar URL del gestor de placas ESP32:

URL del gestor de placas ESP32:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Continuación de la configuración:

  1. Ir a Herramientas → Placa → Gestor de placas
  2. Buscar "ESP32" e instalar "esp32 by Espressif Systems"
  3. Seleccionar placa: "ESP32 Dev Module"
  4. Configurar puerto serie correspondiente

Primer programa: Blink LED

Ejemplo: LED Parpadeante en ESP32


// Programa básico para parpadear el LED integrado del ESP32
#define LED_PIN 2  // Pin del LED integrado en la mayoría de ESP32

void setup() {
  // Inicializar comunicación serie a 115200 baudios
  Serial.begin(115200);
  
  // Configurar el pin del LED como salida
  pinMode(LED_PIN, OUTPUT);
  
  // Mensaje de inicio
  Serial.println("ESP32 iniciado correctamente!");
  Serial.println("Programa: LED Blink");
}

void loop() {
  // Encender LED
  digitalWrite(LED_PIN, HIGH);
  Serial.println("LED encendido");
  delay(1000);  // Esperar 1 segundo
  
  // Apagar LED
  digitalWrite(LED_PIN, LOW);
  Serial.println("LED apagado");
  delay(1000);  // Esperar 1 segundo
}
            

Salida Esperada (Monitor Serie):

ESP32 iniciado correctamente!
Programa: LED Blink
LED encendido
LED apagado
LED encendido
LED apagado
...
            

Configuración de PlatformIO

Archivo platformio.ini para ESP32:


; Configuración de PlatformIO para ESP32
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps = 
    adafruit/DHT sensor library@^1.4.4
    knolleary/PubSubClient@^2.8
    arduino-libraries/WiFi@^1.2.7

; Configuraciones adicionales
upload_speed = 921600
monitor_filters = esp32_exception_decoder
            

Proyecto Completo: ESP32 + DHT11 + MQTT

Código ESP32 - Sensor DHT11 con MQTT:


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

// Configuración WiFi
const char* ssid = "TU_WIFI_SSID";
const char* password = "TU_WIFI_PASSWORD";

// Configuración MQTT
const char* mqtt_server = "192.168.1.100";  // IP del broker Mosquitto
const int mqtt_port = 1883;
const char* mqtt_user = "mqtt_user";
const char* mqtt_password = "mqtt_pass";
const char* mqtt_topic = "sensors/dht11";

// Configuración DHT11
#define DHT_PIN 4
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);

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

// Variables de control
unsigned long lastMsg = 0;
const long interval = 5000;  // Enviar datos cada 5 segundos

void setup() {
  Serial.begin(115200);
  
  // Inicializar sensor DHT11
  dht.begin();
  Serial.println("Sensor DHT11 inicializado");
  
  // Conectar a WiFi
  setup_wifi();
  
  // Configurar servidor MQTT
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  
  Serial.println("Sistema iniciado correctamente");
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi conectado!");
  Serial.print("Dirección IP: ");
  Serial.println(WiFi.localIP());
}

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...");
    
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    
    if (client.connect(clientId.c_str(), mqtt_user, mqtt_password)) {
      Serial.println("Conectado al broker MQTT");
      client.subscribe("sensors/commands");
    } else {
      Serial.print("Falló conexión, rc=");
      Serial.print(client.state());
      Serial.println(" Reintentando en 5 segundos");
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > interval) {
    lastMsg = now;
    
    // Leer datos del sensor DHT11
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();
    
    // Verificar si las lecturas son válidas
    if (isnan(humidity) || isnan(temperature)) {
      Serial.println("Error al leer el sensor DHT11");
      return;
    }
    
    // Crear JSON con los datos
    StaticJsonDocument<200> doc;
    doc["device_id"] = "ESP32_DHT11_001";
    doc["temperature"] = temperature;
    doc["humidity"] = humidity;
    doc["timestamp"] = now;
    
    char jsonString[200];
    serializeJson(doc, jsonString);
    
    // Publicar datos por MQTT
    if (client.publish(mqtt_topic, jsonString)) {
      Serial.print("Datos publicados: ");
      Serial.println(jsonString);
    } else {
      Serial.println("Error al publicar datos");
    }
    
    // Mostrar datos en consola
    Serial.printf("Temperatura: %.2f°C, Humedad: %.2f%%\n", temperature, humidity);
  }
}
            

Configuración del Broker Mosquitto

Instalación de Mosquitto en Ubuntu/Debian:


# Actualizar repositorios
sudo apt update

# Instalar Mosquitto broker y cliente
sudo apt install mosquitto mosquitto-clients

# Iniciar el servicio
sudo systemctl start mosquitto
sudo systemctl enable mosquitto

# Verificar estado
sudo systemctl status mosquitto
            

Configuración básica de Mosquitto (/etc/mosquitto/mosquitto.conf):


# Configuración básica de Mosquitto
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd

# 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/
            

Aplicación Flask para visualización

Código Python/Flask - Servidor Web (demo mínimo):


from flask import Flask, jsonify
import paho.mqtt.client as mqtt

app = Flask(__name__)

latest = {"temperature": None, "humidity": None}

MQTT_BROKER = "localhost"
MQTT_PORT = 1883

def on_connect(client, userdata, flags, rc):
    if rc == 0:
        client.subscribe("sensors/dht11")

def on_message(client, userdata, msg):
    try:
        import json
        data = json.loads(msg.payload.decode("utf-8"))
        latest.update({"temperature": data.get("temperature"), "humidity": data.get("humidity")})
    except Exception:
        pass

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect_async(MQTT_BROKER, MQTT_PORT, 60)
client.loop_start()

@app.get("/api/last")
def get_last():
    return jsonify(latest)

if __name__ == "__main__":
    app.run(debug=True)