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:
- Descargar Arduino IDE desde
arduino.cc
- Abrir Preferencias (Archivo → Preferencias)
- 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:
- Ir a Herramientas → Placa → Gestor de placas
- Buscar "ESP32" e instalar "esp32 by Espressif Systems"
- Seleccionar placa: "ESP32 Dev Module"
- 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)