Monitoriza Temperatura y Humedad con ESP32: Web en Tiempo Real y Gráficos
¿Te gustaría crear un sistema IoT para monitorizar la temperatura y humedad en tiempo real? Proyecto IoT con ESP32 y previsión meteorológica. En este proyecto, te mostramos cómo usar un ESP32 con un sensor DHT11 para capturar datos ambientales, visualizarlos en una web interactiva y almacenarlos en una base de datos MySQL. Además, incluimos gráficos dinámicos y la posibilidad de expandir el proyecto con un modelo de previsión.

¿Qué Necesitas?
- ESP32: El cerebro del proyecto.
- Sensor DHT11: Para medir temperatura y humedad.
- Servidor local: Usamos una Raspberry Pi o un servidor en casa con IP
192.168.1.100
. - Node.js: Para el backend.
- MySQL: Para almacenar los datos.
- Chart.js: Para crear gráficos interactivos.
Cómo Funciona
- Captura de Datos: El ESP32 lee la temperatura, humedad y voltaje de la batería.
- Envío de Datos: Los datos se envían a un servidor Node.js mediante HTTP.
- Almacenamiento: Los datos se guardan en una base de datos MySQL.
- Visualización: Una interfaz web muestra los datos en tiempo real y gráficos históricos.
Código y Configuración
- ESP32: Usamos el sensor DHT11 y medimos el voltaje de la batería.
- Node.js: Creamos un servidor para recibir y almacenar los datos.
- MySQL: Configuramos una base de datos para almacenar los datos del sensor.
- Frontend: Usamos HTML, CSS y JavaScript con Chart.js para visualizar los datos.
Gráficos en Tiempo Real
Con Chart.js, puedes visualizar la temperatura, humedad y voltaje de la batería en gráficos interactivos que se actualizan automáticamente. Esto te permite analizar tendencias y tomar decisiones basadas en datos.
Expande tu Proyecto
- Modelo de Previsión: Usa los datos almacenados para entrenar un modelo de Machine Learning y predecir futuras condiciones ambientales.
- Notificaciones: Configura alertas cuando la temperatura o humedad superen ciertos umbrales.
- Integración con Cámara: Captura imágenes periódicamente y guárdalas en la base de datos.
Conclusión: Proyecto IoT con ESP32 y previsión meteorológica
Este proyecto es ideal para principiantes y expertos en IoT. Con un ESP32, un sensor DHT11 y un servidor local, puedes crear un sistema completo para monitorizar condiciones ambientales. ¡Perfecto para aplicaciones de domótica, agricultura o análisis ambiental!

Proyecto IoT con ESP32 y previsión meteorológica
¿Listo para empezar? Descarga el código fuente y sigue nuestra guía paso a paso para crear tu propio sistema de monitorización con ESP32. Vamos a desglosarlo en partes para que sea más manejable:
1. Recopilación de Datos con el ESP32
- Sensor DHT11: Para leer la temperatura y humedad.
- Batería de 9V: Necesitas medir el voltaje de la batería para saber cuándo cambiarla.
- Cámara integrada: Capturar imágenes cada minuto y almacenarlas.
2. Envío de Datos a un Servidor
- WiFi: El ESP32 puede conectarse a una red WiFi para enviar datos a un servidor.
- Protocolo HTTP/MQTT: Puedes usar HTTP para enviar datos a un servidor web o MQTT para un enfoque más ligero y eficiente.
3. Base de Datos
- MySQL/PostgreSQL: Para almacenar los datos de temperatura, humedad, voltaje de la batería y las imágenes.
- InfluxDB: Especialmente útil si planeas hacer gráficos y análisis de series temporales.
4. Servidor Web
- Backend: Puedes usar Node.js, Python (Flask/Django), o cualquier otro lenguaje/framework que prefieras.
- Frontend: HTML, CSS, JavaScript (puedes usar librerías como Chart.js para los gráficos).
5. Visualización de Datos
- Gráficos: Usar Chart.js o similar para mostrar la temperatura y humedad a lo largo del tiempo.
- Estado de la Batería: Mostrar el voltaje de la batería y una alerta cuando esté baja.
- Imágenes: Mostrar las imágenes capturadas por la cámara.
6. Modelo de Previsión
- Machine Learning: Puedes usar Python con librerías como TensorFlow o Scikit-learn para crear un modelo de previsión basado en los datos históricos.
Implementación Paso a Paso
1. ESP32 – Lectura de Sensores y Envío de Datos
// Librerías necesarias
#include <LiquidCrystal_I2C.h> // Para la pantalla LCD 16x2 I2C
#include <Wire.h> // Para comunicación I2C
#include <DHTesp.h> // Para el sensor DHT11
#include <WiFi.h> // Para conexión WiFi
#include <HTTPClient.h> // Para enviar solicitudes HTTP
// Definición de pines
#define SDA 13 // Pin SDA para I2C
#define SCL 14 // Pin SCL para I2C
#define DHTPIN 4 // Pin para el sensor DHT11
#define BATTERY_PIN 34 // Pin analógico para medir voltaje
// Configuración de WiFi y servidor
const char* ssid = "TU FIBRA"; // Cambia por el nombre de tu red WiFi
const char* password = "TU CLAVE"; // Cambia por la contraseña de tu WiFi
const char* serverName = "http://192.168.1.100:3000/api/datos"; // URL del servidor
// Objetos globales
LiquidCrystal_I2C lcd(0x27, 16, 2); // Inicializa LCD con dirección I2C 0x27
DHTesp dht; // Objeto para el sensor DHT11
// Función para probar dirección I2C
bool i2CAddrTest(uint8_t addr) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
return true; // Dirección encontrada
}
return false; // Dirección no encontrada
}
// Configuración inicial
void setup() {
Serial.begin(115200); // Inicia comunicación serial
Wire.begin(SDA, SCL); // Inicia I2C con pines personalizados
// Verificar dirección I2C del LCD
if (!i2CAddrTest(0x27)) {
lcd = LiquidCrystal_I2C(0x3F, 16, 2); // Cambia a dirección alternativa si falla
}
// Inicializar LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Iniciando...");
// Configurar sensor DHT11
dht.setup(DHTPIN, DHTesp::DHT11);
pinMode(BATTERY_PIN, INPUT); // Configurar pin analógico como entrada
// Conectar a WiFi
WiFi.begin(ssid, password);
lcd.setCursor(0, 1);
lcd.print("Conectando WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConectado a WiFi");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi OK");
delay(2000);
}
// Bucle principal
void loop() {
// Leer datos del sensor DHT11
TempAndHumidity data = dht.getTempAndHumidity();
float temp = data.temperature;
float hum = data.humidity;
// Leer y calcular voltaje de la batería
int analogValue = analogRead(BATTERY_PIN);
float voltage = (analogValue / 4095.0) * 3.3 * 2.79; // Factor calibrado
// Mostrar datos en Serial
Serial.print("Valor ADC: ");
Serial.println(analogValue);
Serial.print("Voltaje calculado: ");
Serial.println(voltage);
Serial.print("Temperatura: ");
Serial.println(temp);
Serial.print("Humedad: ");
Serial.println(hum);
Serial.println("---");
// Verificar errores en el sensor DHT11
if (isnan(temp) || isnan(hum)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Error DHT11");
delay(2000);
return;
}
// Mostrar datos en LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temp);
lcd.print("C B:");
lcd.print(voltage, 1); // 1 decimal
lcd.print("V");
lcd.setCursor(0, 1);
lcd.print("Humedad: ");
lcd.print(hum);
lcd.print(" %");
// Enviar datos al servidor si hay conexión WiFi
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverName);
http.addHeader("Content-Type", "application/json");
// Crear cuerpo JSON
String jsonData = "{\"temperatura\":" + String(temp) +
",\"humedad\":" + String(hum) +
",\"voltaje\":" + String(voltage) + "}";
// Enviar solicitud POST
int httpResponseCode = http.POST(jsonData);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("Código de respuesta: " + String(httpResponseCode));
Serial.println("Respuesta: " + response);
} else {
Serial.println("Error en la solicitud HTTP: " + String(httpResponseCode));
}
http.end();
} else {
Serial.println("WiFi desconectado");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi Error");
delay(2000);
}
delay(5000); // Esperar 5 segundos antes de la próxima iteración
}
Este código envía los datos al servidor y también los muestra en la pantalla.
2. Servidor Web y Base de Datos
- Backend: Puedes usar Node.js con Express para crear un API que reciba los datos del ESP32 y los almacene en una base de datos.
- Base de Datos: Configura una base de datos MySQL o PostgreSQL para almacenar los datos.
- Almacenamiento de Imágenes: Puedes almacenar las imágenes en un sistema de archivos o en un servicio de almacenamiento en la nube como AWS S3.
3. Frontend – Visualización de Datos
- HTML/CSS/JavaScript: Crea una interfaz web que muestre los datos en tiempo real, gráficos y las imágenes capturadas.
- Chart.js: Para crear gráficos de temperatura y humedad.
4. Modelo de Previsión
- Recopilación de Datos: Usa los datos almacenados en la base de datos para entrenar un modelo de Machine Learning.
- Entrenamiento: Usa Python con TensorFlow o Scikit-learn para crear un modelo de previsión.
- Integración: Puedes integrar el modelo en tu servidor para hacer predicciones en tiempo real.
Herramientas y Tecnologías Recomendadas
- ESP32: Para la recopilación de datos.
- Node.js/Express: Para el backend.
- MySQL/PostgreSQL: Para la base de datos.
- Chart.js: Para gráficos en el frontend.
- Python: Para el modelo de previsión.
Consideraciones Adicionales
- Seguridad: Asegúrate de que la comunicación entre el ESP32 y el servidor sea segura (HTTPS, autenticación).
- Escalabilidad: Si planeas expandir el proyecto, considera usar un servidor en la nube como AWS o Google Cloud.
Este es un proyecto bastante completo, pero con un enfoque modular y paso a paso, puedes ir implementando cada parte y asegurarte de que todo funcione correctamente antes de pasar a la siguiente.
Vamos a crear una base de datos MySQL, un archivo index.html
, un archivo CSS y un archivo JavaScript para tu proyecto. Aquí tienes una guía paso a paso:
1. Base de Datos MySQL
Primero, crea una base de datos en tu servidor MySQL para almacenar los datos del sensor (temperatura, humedad, voltaje de la batería) y las imágenes capturadas.
Estructura de la Base de Datos
Conéctate a tu servidor MySQL:
mysql -u root -p
Crea una base de datos llamada esp32_data
:
-- Crear la base de datos para los datos del ESP32
CREATE DATABASE esp32_data;
-- Seleccionar la base de datos recién creada
USE esp32_data;
Crea una tabla para almacenar los datos del sensor:
CREATE TABLE sensor_data (
id INT AUTO_INCREMENT PRIMARY KEY, -- Identificador único autoincremental
temperatura FLOAT NOT NULL, -- Valor de temperatura, no nulo
humedad FLOAT NOT NULL, -- Valor de humedad, no nulo
voltaje FLOAT NOT NULL, -- Valor de voltaje, no nulo
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Fecha y hora de registro, valor por defecto actual
);
También una tabla para almacenar las imágenes capturadas:
CREATE TABLE images (
id INT AUTO_INCREMENT PRIMARY KEY, -- Identificador único autoincremental
image_path VARCHAR(255) NOT NULL, -- Ruta de la imagen, hasta 255 caracteres, no nulo
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Fecha y hora de creación, valor por defecto actual
);

2. Backend (Node.js con Express)
Vamos a crear un servidor en Node.js para recibir los datos del ESP32 y almacenarlos en la base de datos.
- Instala Node.js y Express en tu servidor:
# Instalar Node.js y npm en el sistema
sudo apt install nodejs npm # Instala Node.js y su gestor de paquetes npm
# Crear un directorio para el proyecto
mkdir esp32_server # Crea una carpeta llamada 'esp32_server'
cd esp32_server # Entra al directorio recién creado
# Inicializar un proyecto Node.js
npm init -y # Genera un archivo package.json con valores predeterminados
# Instalar dependencias necesarias
npm install express mysql body-parser cors # Instala Express, MySQL, body-parser y CORS
2. Crea un archivo server.js
:
// Importación de módulos necesarios
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const cors = require('cors');
// Configuración inicial
const app = express();
const port = 3000;
// Configuración de la conexión a MySQL
const db = mysql.createConnection({
host: 'localhost', // Servidor de la base de datos
user: 'root', // Cambia por tu usuario de MySQL
password: 'tu_contraseña', // Cambia por tu contraseña de MySQL
database: 'esp32_data' // Nombre de la base de datos
});
// Conexión a la base de datos
db.connect((err) => {
if (err) throw err;
console.log('Conectado a la base de datos MySQL');
});
// Middleware
app.use(bodyParser.json()); // Parsear solicitudes con cuerpo JSON
app.use(cors()); // Habilitar CORS para permitir solicitudes desde otros dominios
// Ruta POST para recibir datos del ESP32
app.post('/api/datos', (req, res) => {
const { temperatura, humedad, voltaje } = req.body;
const query = 'INSERT INTO sensor_data (temperatura, humedad, voltaje) VALUES (?, ?, ?)';
db.query(query, [temperatura, humedad, voltaje], (err, result) => {
if (err) {
console.error(err);
res.status(500).send('Error al guardar los datos');
} else {
res.status(200).send('Datos guardados correctamente');
}
});
});
// Ruta GET para obtener los últimos 100 datos
app.get('/api/datos', (req, res) => {
const query = 'SELECT * FROM sensor_data ORDER BY fecha DESC LIMIT 100';
db.query(query, (err, results) => {
if (err) {
console.error(err);
res.status(500).send('Error al obtener los datos');
} else {
res.status(200).json(results);
}
});
});
// Iniciar el servidor
app.listen(port, () => {
console.log(`Servidor corriendo en http://192.168.1.100:${port}`);
});
3. Ejecuta el servidor:
node server.js
3. Frontend (HTML, CSS, JavaScript)
Vamos a crear una interfaz web para mostrar los datos.
Archivo index.html
<!DOCTYPE html>
<html lang="es">
<head>
<!-- Configuración básica del documento -->
<meta charset="UTF-8"> <!-- Codificación de caracteres -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Responsive design -->
<title>Datos del Sensor ESP32</title> <!-- Título de la página -->
<link rel="stylesheet" href="styles.css"> <!-- Enlace al archivo CSS -->
</head>
<body>
<!-- Título principal -->
<h1>Datos del Sensor ESP32</h1>
<!-- Contenedor para mostrar los datos -->
<div id="datos">
<p><strong>Temperatura:</strong> <span id="temperatura">--</span> °C</p>
<p><strong>Humedad:</strong> <span id="humedad">--</span> %</p>
<p><strong>Voltaje de la Batería:</strong> <span id="voltaje">--</span> V</p>
</div>
<!-- Elemento canvas para el gráfico -->
<canvas id="grafico"></canvas>
<!-- Scripts externos -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <!-- Librería Chart.js -->
<script src="script.js"></script> <!-- Lógica JavaScript -->
</body>
</html>
Archivo styles.css
/* Estilos generales del cuerpo */
body {
font-family: Arial, sans-serif; /* Fuente clara y legible */
background-color: #f4f4f4; /* Fondo gris claro */
color: #333; /* Color de texto oscuro */
margin: 0; /* Sin márgenes externos */
padding: 20px; /* Espaciado interno */
}
/* Estilos para el título principal */
h1 {
color: #007BFF; /* Azul vibrante */
}
/* Estilos para el contenedor de datos */
#datos {
background-color: #fff; /* Fondo blanco */
padding: 20px; /* Espaciado interno */
border-radius: 5px; /* Bordes redondeados */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Sombra sutil */
margin-bottom: 20px; /* Espacio inferior */
}
/* Estilos para el elemento canvas (gráfico) */
canvas {
max-width: 100%; /* Ancho máximo adaptable */
height: auto; /* Altura automática */
background-color: #fff; /* Fondo blanco */
padding: 20px; /* Espaciado interno */
border-radius: 5px; /* Bordes redondeados */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Sombra sutil */
}
Archivo script.js
// Selección de elementos del DOM
const temperaturaElement = document.getElementById('temperatura');
const humedadElement = document.getElementById('humedad');
const voltajeElement = document.getElementById('voltaje');
const ctx = document.getElementById('grafico').getContext('2d');
// Configuración del gráfico con Chart.js
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: [], // Etiquetas del eje X (tiempo)
datasets: [
{
label: 'Temperatura (°C)',
borderColor: 'red',
data: [] // Datos de temperatura
},
{
label: 'Humedad (%)',
borderColor: 'blue',
data: [] // Datos de humedad
},
{
label: 'Voltaje (V)',
borderColor: 'green',
data: [] // Datos de voltaje
}
]
},
options: {
responsive: true,
scales: {
x: {
display: true,
title: {
display: true,
text: 'Tiempo'
}
},
y: {
display: true,
title: {
display: true,
text: 'Valores'
}
}
}
}
});
// Función para actualizar los datos desde el servidor
function actualizarDatos() {
fetch('http://192.168.1.100:3000/api/datos')
.then(response => response.json())
.then(data => {
// Mostrar el último dato en los elementos HTML
const ultimoDato = data[0];
temperaturaElement.textContent = ultimoDato.temperatura;
humedadElement.textContent = ultimoDato.humedad;
voltajeElement.textContent = ultimoDato.voltaje;
// Actualizar los datos del gráfico
chart.data.labels = data.map(d => new Date(d.fecha).toLocaleTimeString());
chart.data.datasets[0].data = data.map(d => d.temperatura);
chart.data.datasets[1].data = data.map(d => d.humedad);
chart.data.datasets[2].data = data.map(d => d.voltaje);
chart.update();
})
.catch(error => console.error('Error al obtener los datos:', error));
}
// Actualizar datos inicialmente y luego cada 5 segundos
actualizarDatos(); // Primera llamada inmediata
setInterval(actualizarDatos, 5000); // Actualización periódica
4. Prueba y Despliegue
- Coloca los archivos
index.html
,styles.css
yscript.js
en la carpeta pública de tu servidor (por ejemplo, en/var/www/html
si estás usando Apache). - Asegúrate de que el servidor Node.js esté corriendo.
- Accede a la interfaz web desde tu navegador:
http://192.168.1.100/index.html
.

¡Y eso es todo! Ahora deberías ver los datos del sensor en tiempo real y un gráfico que se actualiza automáticamente. Si tienes alguna duda, no dudes en preguntar. 😊
Problemas añadidos al Proyecto IoT con ESP32 y previsión meteorológica:

Consumo del ESP32
El consumo de energía del ESP32 depende del modo en que esté funcionando y de los periféricos conectados (como WiFi, Bluetooth, pantalla, etc.). Aquí tienes una idea general basada en datos típicos del ESP32 (como el WROOM-32) en diferentes modos:
Modos de operación sin pantalla
- Modo activo con WiFi encendido:
- Consumo: 100-240 mA (dependiendo de la actividad, picos de hasta 500 mA al transmitir).
- Este es el caso si tu ESP32 está conectado a la red enviando datos constantemente.
- Modo activo sin WiFi (solo CPU):
- Consumo: 20-50 mA (varía con la frecuencia del CPU, 80-240 MHz).
- Modo Light Sleep:
- Consumo: ~0.8-3 mA (WiFi apagado, CPU pausado, RAM activa).
- Modo Deep Sleep:
- Consumo: 10-150 µA (0.01-0.15 mA), dependiendo de si el coprocesador ULP está activo.
Impacto de la pantalla
- Pantalla OLED pequeña (ej. SSD1306, 128×64): 5-20 mA si está encendida constantemente, dependiendo del brillo y el contenido mostrado.
- Pantalla TFT o LCD más grande: 50-100 mA o más, especialmente si tiene retroiluminación.
Si la pantalla está siempre encendida, suma su consumo al del ESP32. Supongamos que es una OLED de 10 mA como estimación conservadora.
Problema con la batería de 9V
Una batería de 9V estándar (como una PP3 alcalina) tiene una capacidad típica de 500-600 mAh. Sin embargo:
- Estas baterías tienen alta resistencia interna y no son ideales para corrientes sostenidas altas (como las que requiere el ESP32 con WiFi).
- El ESP32 suele alimentarse a 3.3V, así que necesitas un regulador (lineal como un AMS1117 o un buck converter). Un regulador lineal desperdicia mucha energía (convierte el exceso de voltaje en calor), reduciendo la eficiencia.
Por ejemplo:
- Si usas un regulador lineal de 9V a 3.3V, y el ESP32 + pantalla consumen 100 mA a 3.3V:
- La corriente desde la batería es ~100 mA (conservación de potencia).
- Pero el regulador disipa (9V – 3.3V) × 100 mA = 570 mW como calor, ¡más que lo que usa el ESP32!
Esto explica por qué la batería se agotó rápido y no veía los datos: el voltaje cayó por debajo del mínimo necesario para que el ESP32 funcione (unos 3.2-3.6V al regulador).
Cálculo de duración de la batería
Supongamos que quiero mantener el ESP32 encendido todo el tiempo con WiFi activo para recolectar datos, más la pantalla. Estimemos:
- Consumo total:
- ESP32 con WiFi activo: 150 mA (promedio conservador).
- Pantalla OLED: 10 mA.
- Total: 160 mA.
- Capacidad de la batería:
- Batería de 9V alcalina: 550 mAh.
- Duración:
- Tiempo = Capacidad / Consumo = 550 mAh / 160 mA = 3.44 horas.
- Con picos de WiFi o una pantalla más grande, podría ser incluso menos (2-3 horas).
Solución para mayor duración
Para que el ESP32 aguante más y cumpla con el objetivo de recolectar datos constantemente (y luego hacer predicciones), tenemos estas opciones:
1. Cambiar la batería
- Batería LiPo de 3.7V (1000 mAh):
- Más eficiente (menos pérdida en regulación).
- Duración: 1000 mAh / 160 mA = 6.25 horas.
- Con mayor capacidad (ej. 2500 mAh): ~15.6 horas.
- Pack de 4 pilas AA (2000 mAh total):
- Con un regulador eficiente: ~12.5 horas.
2. Optimizar el consumo
- Usar Deep Sleep: Si no necesitas datos en tiempo real, pon el ESP32 en Deep Sleep y despiértalo cada pocos minutos para enviar datos. Ejemplo:
- Activo 10 segundos cada 5 minutos (2% del tiempo a 150 mA, 98% en Deep Sleep a 0.1 mA).
- Consumo promedio: (0.02 × 150) + (0.98 × 0.1) = 3 + 0.098 = ~3.1 mA.
- Duración con 550 mAh: 550 / 3.1 = 177 horas (~7 días).
- Reducir uso de WiFi: Conecta solo para enviar datos y apaga el WiFi el resto del tiempo.
3. Mejorar la eficiencia energética
- Usa un buck converter (80-90% eficiente) en lugar de un regulador lineal para bajar de 9V a 3.3V. Esto puede duplicar la duración de la batería de 9V (~6-7 horas).
Respuesta a las preguntas
- ¿Cuánto consume el ESP32?: Depende del modo. Con WiFi y pantalla, estima 150-200 mA. Sin pantalla y en Deep Sleep, 0.01-0.15 mA.
- ¿Cuánto tiempo puede aguantar la batería?: Con tu batería de 9V y uso continuo, unas 3-4 horas. Con optimizaciones (Deep Sleep), días o semanas.
Si tu idea es mantenerlo siempre encendido, te recomiendo una batería de mayor capacidad (LiPo o AA) y un regulador eficiente. Si puedes usar Deep Sleep, incluso la batería de 9V podría durar más.
recolectar datos continuamente y hacer predicciones más adelante.

Consumo de la pantalla LCD 16×2 I2C
El consumo de una pantalla LCD 16×2 con interfaz I2C depende principalmente de la retroiluminación (backlight), ya que el LCD en sí consume muy poco. Aquí tienes los detalles:
- LCD sin retroiluminación: ~1-2 mA (solo el módulo básico).
- Retroiluminación encendida: 10-40 mA, dependiendo del brillo y la resistencia limitadora. Típicamente, con retroiluminación a nivel medio, consume unos 20 mA.
- Interfaz I2C (expansor como PCF8574): Añade ~1-5 mA dependiendo de la actividad, pero suele ser insignificante.
Asumamos que mantienes la retroiluminación encendida todo el tiempo (si no, el consumo baja drásticamente). Un valor realista para tu pantalla sería 20-25 mA.
Consumo total (ESP32 + Pantalla)
Combinemos el consumo del ESP32 con la pantalla LCD 16×2 I2C:
- ESP32 con WiFi activo:
- Promedio: 150 mA (100-240 mA, según actividad WiFi).
- Pantalla LCD 16×2 I2C:
- Con retroiluminación: 20 mA.
- Total estimado:
- 150 mA (ESP32) + 20 mA (pantalla) = 170 mA.
Si usas un regulador lineal para bajar de 9V a 3.3V, la corriente de la batería será aproximadamente la misma (170 mA), pero con mucha energía desperdiciada en calor.
Duración de la batería de 9V
- Capacidad: Una batería alcalina de 9V estándar tiene ~550 mAh.
- Duración:
- 550 mAh / 170 mA = 3.24 horas (~3 horas y 15 minutos).
Esto coincide con tu experiencia de que la batería se agotó rápido y los datos dejaron de llegar. Con la pantalla y WiFi siempre encendidos, la batería de 9V no es suficiente para un uso continuo prolongado.
Optimizaciones para mayor duración
Dado que quiero recolectar datos constantemente y usarlos más adelante para predicciones, aquí hay algunas opciones para extender la vida de la batería o adaptarlo a tus necesidades:
1. Mantener todo encendido (sin optimización)
- Duración: ~3-4 horas con la batería de 9V.
- Solución: Cambia a una batería de mayor capacidad:
- LiPo 3.7V 2000 mAh: ~11.8 horas (2000 / 170).
- 4 pilas AA (2000 mAh total): ~11.8 horas con un regulador eficiente.
- Usa un buck converter (en lugar de regulador lineal) con la batería de 9V para mejorar la eficiencia (~5-6 horas).
2. Reducir consumo de la pantalla
Apagar la retroiluminación cuando no se necesita:
Muchas LCD 16×2 I2C permiten controlar la retroiluminación mediante código. Si usas una librería como LiquidCrystal_I2C, puedes apagarla:
lcd.backlight(); // Encender
lcd.noBacklight(); // Apagar
Consumo sin retroiluminación: ~2 mA (ESP32 + 152 mA).
Duración con 9V: 550 / 152 = 3.6 horas (poco mejora).
Mejor con una LiPo 2000 mAh: ~13 horas.
Encender solo para mostrar datos ocasionalmente:
Si muestras datos cada 5 minutos por 10 segundos, el consumo promedio de la pantalla baja mucho.
3. Usar Deep Sleep en el ESP32
Si no necesitas datos en tiempo real continuo, el modo Deep Sleep es ideal:
- Ejemplo: Activo 10 segundos cada 5 minutos (enviar datos por WiFi), resto en Deep Sleep.
- Activo (170 mA × 10s / 300s = 5.67 mA promedio).
- Deep Sleep (~0.1 mA × 290s / 300s = 0.097 mA).
- Total promedio: ~5.77 mA.
- Duración con 9V: 550 / 5.77 = 95 horas (~4 días).
- Ajusta el intervalo según tus necesidades (cada 1 minuto, 10 minutos, etc.).
4. Energía externa
Si el ESP32 estará fijo y recolectando datos a largo plazo, considera:
- Adaptador USB (5V): Con un cable y un cargador, eliminas el límite de batería.
- Panel solar pequeño: Para exteriores, con una batería recargable.
Respuesta a tus preguntas
- ¿Cuánto consume el ESP32 con la pantalla?: Aproximadamente 170 mA con WiFi y retroiluminación encendidos.
- ¿Cuánto tiempo aguanta la batería de 9V?: Unas 3-4 horas sin optimización. Con Deep Sleep, hasta días.
Recomendación el caso
Si necesitas datos constantes: Usa una batería LiPo de 2000-3000 mAh (~12-18 horas) o alimentación USB.
Si puedes muestrear datos periódicamente: Implementa Deep Sleep (por ejemplo, cada 5-10 minutos) y la batería de 9V te durará días. Apaga la retroiluminación cuando no la mires.
Código básico para Deep Sleep:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Ajusta la dirección I2C si es diferente
void setup() {
lcd.init();
lcd.backlight();
lcd.print("Iniciando...");
delay(1000); // Mostrar mensaje
lcd.noBacklight(); // Apagar luz
// Enviar datos por WiFi aquí
esp_sleep_enable_timer_wakeup(5 * 60 * 1000000ULL); // 5 minutos en microsegundos
esp_deep_sleep_start();
}
void loop() {
// No se usa en Deep Sleep
}
¿Cada cuánto necesitas recolectar datos? Si me das más detalles de tu proyecto (qué datos, frecuencia, etc.), puedo afinar la solución para las predicciones que planeas.

¿Por qué funciona con un cargador USB?
El ESP32 (como el WROOM-32 o modelos con conector micro-USB o USB-C) está diseñado para alimentarse a través de su puerto USB, que típicamente recibe 5V desde un cargador estándar de teléfono móvil. Internamente, el ESP32 tiene un regulador de voltaje (por ejemplo, un AMS1117) que convierte esos 5V a 3.3V, el voltaje operativo del microcontrolador.
Ventajas:
- Energía ilimitada: Un cargador conectado a la red eléctrica no se agota como una batería, ideal para mantener el ESP32 y la pantalla LCD 16×2 I2C funcionando 24/7.
- Estabilidad: Los cargadores de teléfono suelen proporcionar una corriente estable (500 mA a 2A, dependiendo del modelo), más que suficiente para el ESP32 y la pantalla.
- Simplicidad: Solo necesitas un cable USB (micro-USB o USB-C, según tu placa) y un cargador que ya tengas.
Consumo y compatibilidad
Repasemos el consumo para asegurarnos de que un cargador típico lo soporte:
- ESP32 con WiFi activo: ~150 mA (picos hasta 500 mA al transmitir).
- Pantalla LCD 16×2 I2C con retroiluminación: ~20-25 mA.
- Total: ~170-175 mA promedio, con picos de hasta 525 mA.
Los cargadores de teléfono modernos suelen ofrecer:
- 500 mA (0.5A): Típico en cargadores antiguos o baratos.
- 1A o 2A: Estándar en cargadores actuales.
Incluso un cargador de 500 mA es suficiente para el promedio de 175 mA y debería manejar los picos breves de 525 mA sin problemas. Con un cargador de 1A o 2A, tienes margen de sobra.
¿Qué necesitas?
- Cargador USB: Cualquier cargador de teléfono de 5V (0.5A o más) sirve. Ejemplo: un cargador de 5V/1A que venía con un móvil viejo.
- Cable USB: Compatible con tu ESP32 (micro-USB para la mayoría de placas como la ESP32 DevKit V1, o USB-C para modelos más nuevos).
- Conexión existente: La pantalla LCD 16×2 I2C ya está conectada al ESP32 (probablemente por SDA/SCL y alimentada desde los pines de 3.3V o 5V del ESP32), así que no necesitas cambiar nada ahí.
Consideraciones importantes
- Voltaje de la pantalla:
- Si la LCD 16×2 está conectada al pin de 5V (VIN) del ESP32, funcionará directamente con el USB porque ese pin refleja los 5V del cargador.
- Si está conectada al pin de 3.3V, el regulador interno del ESP32 la alimentará sin problema.
- Verifica tu conexión (¿usa VCC de 5V o 3.3V?). Las LCD 16×2 suelen operar a 5V, pero el módulo I2C puede ajustar niveles lógicos a 3.3V para el ESP32.
- Corriente del cargador:
- Un cargador de 500 mA es el mínimo. Si planeas añadir más sensores o aumentar el uso de WiFi, usa uno de 1A o más para evitar caídas de voltaje.
- Calor:
- El regulador interno del ESP32 (de 5V a 3.3V) se calentará un poco con uso continuo, pero está diseñado para eso. Asegúrate de que la placa esté ventilada y no encerrada en un espacio pequeño.
- Programación:
- Si subes código al ESP32 mientras está conectado al cargador, usa el mismo puerto USB (desconectando el cable del ordenador al cargador y viceversa). No hay riesgo si solo alimentas por USB.
Duración
Con un cargador USB conectado a la red eléctrica:
- Tiempo de funcionamiento: Infinito (o hasta que el cargador o el ESP32 fallen, lo cual puede ser años con un uso adecuado).
- Ya no dependes de la batería de 9V, así que el problema de agotamiento desaparece.