Caso práctico: Detector de fugas de agua con ESP32

Caso práctico: Detector de fugas de agua con ESP32 — hero

case-device-block-diagram,
.prometeo-educational-note,
.prometeo-device-postcode-section,
.prometeo-device-section-card {
margin: 2.4rem 0;
padding: 1.45rem 1.55rem;
border: 1px solid rgba(148, 163, 184, 0.30);
border-radius: 14px;
background:
linear-gradient(135deg, rgba(30, 41, 59, 0.50), rgba(15, 23, 42, 0.18)),
rgba(17, 24, 39, 0.48);
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.20);
}
.case-objective > h2:first-of-type,
.case-device-block-diagram > h2:first-of-type,
.prometeo-device-postcode-section > h2:first-of-type,
.prometeo-device-section-card > h2:first-of-type {
margin-top: 0;
}
.prometeo-device-section-card > :last-child,
.case-objective > :last-child,
.case-device-block-diagram > :last-child,
.prometeo-device-postcode-section > :last-child {
margin-bottom: 0;
}
.prometeo-device-section-card.prometeo-device-section-card-code {
border-left: 4px solid rgba(56, 189, 248, 0.86);
background:
linear-gradient(135deg, rgba(8, 47, 73, 0.42), rgba(15, 23, 42, 0.18)),
rgba(15, 23, 42, 0.58);
}
.prometeo-device-section-card.prometeo-device-section-card-compact {
padding: 1.2rem 1.35rem;
}
.prometeo-device-section-card pre,
.case-objective pre,
.case-device-block-diagram pre,
.prometeo-device-postcode-section pre {
max-width: 100%;
}
.prometeo-device-postcode-section .prometeo-device-flow-item {
background:
linear-gradient(135deg, rgba(15, 23, 42, 0.50), rgba(30, 41, 59, 0.28)),
rgba(15, 23, 42, 0.28);
}
@media print {
.case-objective,
.case-device-block-diagram,
.prometeo-educational-note,
.prometeo-device-postcode-section,
.prometeo-device-section-card {
background: #fff;
color: #111827;
box-shadow: none;
break-inside: avoid;
page-break-inside: avoid;
}
}


Objetivo y caso de uso

Qué vas a construir: Un dispositivo inteligente de detección de fugas de agua basado en ESP32 que activa una alarma audiovisual local continua de forma inmediata, mientras aloja un Punto de Acceso (SoftAP) autónomo con un panel web en vivo y una API JSON para informar su estado a dispositivos locales.

Por qué es importante / Casos de uso

  • Prevención de inundaciones industriales y residenciales: Detecta filtraciones de agua subterránea o fallos en válvulas de forma temprana, permitiendo la intervención antes de que ocurran daños graves.
  • Monitorización de salas de servidores: Colocado debajo de unidades de aire acondicionado de precisión (CRAC) para detectar desbordamientos de condensación que podrían amenazar la infraestructura crítica.
  • Dispositivo IoT de borde autónomo: Al operar en modo SoftAP, el dispositivo no depende de la infraestructura WiFi del edificio, garantizando que la red de alerta local y la API JSON permanezcan operativas incluso durante cortes de red del router principal.

Resultado esperado

  • El ESP32 inicializa un Punto de Acceso WiFi autónomo y muestra su dirección IP en el monitor serie.
  • En estado seco, los indicadores de hardware permanecen apagados y el panel web informa un estado «SECO» (DRY).
  • Cuando el agua puentea los contactos del sensor, el dispositivo activa una alarma local continua (tiempo de respuesta del hardware de <100ms) y actualiza instantáneamente el panel web/JSON a un estado de «FUGA» (WET) con una latencia de red de <500ms.

Audiencia: Desarrolladores de IoT y automatización industrial; Nivel: Intermedio

Arquitectura/flujo: Sensor de agua analógico/digital → GPIO del ESP32 → Alarma de hardware de estado sólido (zumbador/LED) + Servidor web asíncrono sobre SoftAP → API JSON / Panel en vivo

Diagrama de bloques conceptual

Vista de alto nivel: qué entra, qué procesa cada bloque y qué sale del sistema.

Arquitectura funcional

Sonda de agua

GPIO/ADC ESP32

Lógica de umbral

LED/buzzer

Alerta Wi-Fi

Flujo conceptual: detección de humedad, decisión local y aviso al usuario.

Ruta de validación

Código fuente

PlatformIO build

Flash

Monitor serie

Resumen conceptual de las herramientas usadas para comprobar el proyecto ESP32 publicado.

Nota educativa de validación

Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. Para este perfil ESP32 DevKitC, el proyecto se comprobó como proyecto PlatformIO: el validador extrajo platformio.ini y src/main.cpp, creó un proyecto temporal y ejecutó pio run contra platform = espressif32, board = esp32dev y framework = arduino. También revisó la estructura del artículo, que los comandos sean copiables con guiones ASCII, y que no aparezcan stacks no soportados como ESP-IDF directo o placas ESP32 no acotadas.

Evidencia de validación publicada

  • Resultado automático: PASS.
  • Estructura parseada: 4 apartados, 4 tablas y 2 bloques de código detectados antes de publicar.
  • Código comprobado: 1 PlatformIO config + 1 ESP32 source/pio run.
  • Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo y los stacks no soportados bloquean la publicación.
  • Hallazgos del informe: sin hallazgos bloqueantes.

Esta validación confirma compatibilidad sintáctica y de herramientas para el código publicado, pero no sustituye la prueba física sobre tu placa ESP32 DevKitC exacta, tu cableado, alimentación y entorno WiFi local.

Nota educativa de seguridad

Peligro eléctrico e hídrico: este proyecto interactúa con agua y debe mantenerse siempre como prototipo educativo de baja tensión. No lo coloques cerca de enchufes expuestos ni de cableado de 110/220 V, alimenta el ESP32 DevKitC desde USB o una batería aislada, mantén sus GPIO a 3,3 V y desconecta siempre la alimentación antes de manipular sensores, cambiar cables o reubicar el dispositivo.

Requisitos previos

Para completar con éxito este tutorial, necesitarás:
* Software: Visual Studio Code con la extensión PlatformIO IDE instalada.
* Conocimientos: Comprensión de la sintaxis de C++, lógica de hardware (estados HIGH/LOW) y manejo básico de redes locales.
* Sistema: Un ordenador con un puerto USB disponible y los controladores USB a UART adecuados instalados (CP210x o CH34x, dependiendo de tu variante específica de ESP32 DevKitC).

Materiales

Necesitarás los siguientes componentes de hardware. Asegúrate de estar utilizando el modelo de dispositivo exacto especificado.

ComponenteDescripción / EspecificaciónCantidad
ESP32 DevKitCPlaca de desarrollo estándar ESP32 de 38 o 30 pines.1
Sensor de fuga de aguaMódulo sensor de agua (módulo comparador con sondas de trazas expuestas). Usaremos el pin de salida digital (DO).1
Zumbador activoMódulo de zumbador activo de 3.3V (suena continuamente cuando se le proporciona una señal HIGH).1
LED de estadoLED estándar de 5 mm (rojo para alertas críticas).1
ResistenciaResistencia de 220 ohmios para limitar la corriente del LED.1
ProtoboardPlaca de pruebas estándar para la creación de prototipos.1
Cables puenteCables Dupont variados.1 juego
Cable Micro-USBCable USB con capacidad de datos.1

Configuración/Conexión

Cablea cuidadosamente los componentes en tu protoboard de acuerdo con la siguiente tabla. Asegúrate de que el ESP32 esté desconectado de tu ordenador mientras realizas las conexiones.

Mapeo de pines

Pin ESP32 DevKitCComponentePin del componenteNotas
3V3Sensor de fuga de aguaVCCAlimenta la lógica del sensor.
GNDSensor de fuga de aguaGNDTierra común.
GPIO 32Sensor de fuga de aguaDO (Salida digital)Cambia a HIGH cuando se detecta agua.
3V3Zumbador activoVCCAlimenta el zumbador.
GNDZumbador activoGNDTierra común.
GPIO 26Zumbador activoI/O (Señal)Activa el zumbador continuamente cuando es HIGH.
GPIO 27LED de estadoÁnodo (Pata larga)Conectar a través de la resistencia de 220 ohmios.
GNDLED de estadoCátodo (Pata corta)Tierra común.

Nota de hardware: Los zumbadores activos generan su propio tono continuo cuando se aplica una señal lógica HIGH. Esto es ideal para alarmas industriales simples y evita la necesidad de generar señales PWM por software.

Código validado

Crea un nuevo proyecto en PlatformIO, seleccionando el Espressif ESP32 Dev Module como tu placa y Arduino como el framework. Reemplaza el contenido de los archivos generados automáticamente con el código a continuación. El código utiliza el modo SoftAP para evitar depender de redes WiFi externas, garantizando que el código sea 100% funcional y reproducible sin modificaciones.

platformio.ini

Este archivo configura el entorno de compilación de PlatformIO, especificando la placa, el framework y la velocidad del monitor serie.

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200

src/main.cpp

Este es el código principal de la aplicación. Implementa la lógica de control de hardware en tiempo real y el servidor web asíncrono sobre un Punto de Acceso dedicado.

Vista pública parcial del archivo validado. El código completo se muestra a miembros y en PDF/Print.

#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>

// ---------------------------------------------------------
// SoftAP Network Credentials
// ---------------------------------------------------------
const char* ssid = "ESP32_Water_Alert";
const char* password = "wateradmin";

// ---------------------------------------------------------
// Pin Definitions
// ---------------------------------------------------------
const int SENSOR_PIN = 32;  // Digital input from water sensor
const int BUZZER_PIN = 26;  // Output to active buzzer
const int LED_PIN = 27;     // Output to status LED

// ---------------------------------------------------------
// Global State Variables
// ---------------------------------------------------------
bool isLeakDetected = false;

// ---------------------------------------------------------
// Web Server Initialization (Port 80)
// ---------------------------------------------------------
WebServer server(80);

// Function to generate the HTML dashboard
void handleRoot() {
    String html = "<!DOCTYPE html><html><head>";
    html += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
    html += "<meta http-equiv=\"refresh\" content=\"2\">";
    html += "<title>Water Leak Monitor</title>";
    html += "<style>";
    html += "body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; background-color: #f4f4f9; }";
    html += "h1 { color: #333; }";
    html += ".status-box { display: inline-block; padding: 40px; border-radius: 10px; font-size: 24px; font-weight: bold; color: white; }";
    html += ".dry { background-color: #4CAF50; }"; // Green for safe
    html += ".leak { background-color: #F44336; }"; // Solid Red for danger
    html += "</style></head><body>";

    html += "<h1>Industrial Water Leak Monitor</h1>";

    if (isLeakDetected) {
        html += "<div class=\"status-box leak\">CRITICAL ALARM: LEAK DETECTED</div>";
        html += "<p>Immediate intervention required.</p>";
    } else {
        html += "<div class=\"status-box dry\">SYSTEM STATUS: DRY</div>";
        html += "<p>No water detected. Monitoring active.</p>";
    }

    html += "</body></html>";

    server.send(200, "text/html", html);
}

// Function to provide a JSON API endpoint for system integration
void handleStatusJSON() {
    String json = "{";
    json += "\"leak_detected\": " + String(isLeakDetected ? "true" : "false") + ",";
    json += "\"sensor_pin\": " + String(SENSOR_PIN) + ",";
    json += "\"device_mode\": \"SoftAP\"";
    json += "}";

    server.send(200, "application/json", json);
}
// ...

🔒 Este contenido es premium. Con la suscripción mensual (7 días gratis) podrás desbloquear el material didáctico completo y el pack PDF listo para imprimir.🔓 Desbloquéalo — 7 días gratis
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>

// ---------------------------------------------------------
// SoftAP Network Credentials
// ---------------------------------------------------------
const char* ssid = "ESP32_Water_Alert";
const char* password = "wateradmin";

// ---------------------------------------------------------
// Pin Definitions
// ---------------------------------------------------------
const int SENSOR_PIN = 32;  // Digital input from water sensor
const int BUZZER_PIN = 26;  // Output to active buzzer
const int LED_PIN = 27;     // Output to status LED

// ---------------------------------------------------------
// Global State Variables
// ---------------------------------------------------------
bool isLeakDetected = false;

// ---------------------------------------------------------
// Web Server Initialization (Port 80)
// ---------------------------------------------------------
WebServer server(80);

// Function to generate the HTML dashboard
void handleRoot() {
    String html = "<!DOCTYPE html><html><head>";
    html += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
    html += "<meta http-equiv=\"refresh\" content=\"2\">";
    html += "<title>Water Leak Monitor</title>";
    html += "<style>";
    html += "body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; background-color: #f4f4f9; }";
    html += "h1 { color: #333; }";
    html += ".status-box { display: inline-block; padding: 40px; border-radius: 10px; font-size: 24px; font-weight: bold; color: white; }";
    html += ".dry { background-color: #4CAF50; }"; // Green for safe
    html += ".leak { background-color: #F44336; }"; // Solid Red for danger
    html += "</style></head><body>";

    html += "<h1>Industrial Water Leak Monitor</h1>";

    if (isLeakDetected) {
        html += "<div class=\"status-box leak\">CRITICAL ALARM: LEAK DETECTED</div>";
        html += "<p>Immediate intervention required.</p>";
    } else {
        html += "<div class=\"status-box dry\">SYSTEM STATUS: DRY</div>";
        html += "<p>No water detected. Monitoring active.</p>";
    }

    html += "</body></html>";

    server.send(200, "text/html", html);
}

// Function to provide a JSON API endpoint for system integration
void handleStatusJSON() {
    String json = "{";
    json += "\"leak_detected\": " + String(isLeakDetected ? "true" : "false") + ",";
    json += "\"sensor_pin\": " + String(SENSOR_PIN) + ",";
    json += "\"device_mode\": \"SoftAP\"";
    json += "}";

    server.send(200, "application/json", json);
}

// ---------------------------------------------------------
// Setup Function
// ---------------------------------------------------------
void setup() {
    // Initialize Serial Monitor
    Serial.begin(115200);
    delay(1000);
    Serial.println("\nInitializing Water Leak Monitor...");

    // Configure GPIO Pins
    pinMode(SENSOR_PIN, INPUT_PULLDOWN); // Ensure pin doesn't float
    pinMode(BUZZER_PIN, OUTPUT);
    pinMode(LED_PIN, OUTPUT);

    // Ensure alarm is off at boot
    digitalWrite(BUZZER_PIN, LOW);
    digitalWrite(LED_PIN, LOW);

    // Initialize WiFi SoftAP
    Serial.print("Configuring Access Point: ");
    Serial.println(ssid);
    WiFi.softAP(ssid, password);

    IPAddress IP = WiFi.softAPIP();
    Serial.print("AP IP Address: ");
    Serial.println(IP);

    // Define Web Server Routes
    server.on("/", handleRoot);
    server.on("/status", handleStatusJSON);

    // Start the Web Server
    server.begin();
    Serial.println("HTTP server started.");
}

// ---------------------------------------------------------
// Main Loop
// ---------------------------------------------------------
void loop() {
    // 1. Handle incoming HTTP client requests
    server.handleClient();

    // 2. Read the water sensor
    int sensorValue = digitalRead(SENSOR_PIN);

    // 3. Evaluate state and trigger hardware alarm
    if (sensorValue == HIGH) {
        if (!isLeakDetected) {
            Serial.println("CRITICAL: Water Leak Detected!");
            isLeakDetected = true;

            // Solid alarm activation
            digitalWrite(LED_PIN, HIGH);
            digitalWrite(BUZZER_PIN, HIGH);
        }
    } else {
        if (isLeakDetected) {
            Serial.println("INFO: Sensor is dry. System normalized.");
            isLeakDetected = false;

            // Deactivate alarm
            digitalWrite(LED_PIN, LOW);
            digitalWrite(BUZZER_PIN, LOW);
        }
    }
}

Comandos de compilación/flasheo/ejecución

Usa la CLI principal de PlatformIO (o la terminal integrada en VS Code) para ejecutar los siguientes comandos.

ComandoPropósito
pio runCompila el proyecto para asegurar que no haya errores de sintaxis en el entorno.
pio run --target uploadCompila y flashea el firmware al ESP32 a través del puerto USB.
pio device monitorAbre el monitor serie para ver las salidas de registro y confirmar la inicialización del SoftAP.

Flujo de trabajo:
1. Abre la terminal de PlatformIO.
2. Ejecuta pio run para verificar que tu código se compile correctamente.
3. Conecta tu ESP32 DevKitC a través de USB.
4. Ejecuta pio run --target upload. (Si la carga no logra conectarse, mantén presionado el botón «BOOT» en el ESP32 mientras la terminal dice «Connecting…»).
5. Ejecuta pio device monitor para observar la secuencia de arranque y confirmar que la dirección IP del AP es 192.168.4.1 (predeterminada de ESP32).

Validación paso a paso

Sigue estos puntos de control para verificar que el sistema industrial funciona exactamente como está previsto.

  1. Comprobación de compilación
  2. Acción: Ejecuta pio run.
  3. Observación esperada: La terminal muestra SUCCESS sin errores de compilación.
  4. Condición de aprobación: El binario del firmware se genera con éxito.
  5. Comprobación del Punto de Acceso (SoftAP)
  6. Acción: Ejecuta pio device monitor. Busca redes WiFi desde tu ordenador o teléfono.
  7. Observación esperada: El monitor serie imprime «AP IP Address: 192.168.4.1». La red ESP32_Water_Alert aparece en tu lista de WiFi.
  8. Condición de aprobación: El ESP32 está transmitiendo su propia red de forma autónoma.
  9. Verificación en estado seco
  10. Acción: Conéctate a la red ESP32_Water_Alert (contraseña: wateradmin). Abre http://192.168.4.1 en tu navegador.
  11. Observación esperada: El LED está apagado, el zumbador está en silencio. La página web muestra un cuadro verde con el texto «SYSTEM STATUS: DRY».
  12. Condición de aprobación: El sistema permanece estable y el servidor web responde correctamente.
  13. Verificación en estado de alarma (Fuga)
  14. Acción: Sumerge las sondas del sensor en agua o puentea los contactos metálicos con un cable.
  15. Observación esperada: El monitor serie imprime «CRITICAL: Water Leak Detected!». El LED rojo y el zumbador se encienden de forma continua y sólida al instante.
  16. Condición de aprobación: La alarma de hardware se activa de forma inmediata e ininterrumpida.
  17. Verificación de latencia de red y API
  18. Acción: Mientras el sensor está mojado, recarga la página web o visita http://192.168.4.1/status. Abre las herramientas de desarrollo del navegador (F12) en la pestaña de Red.
  19. Observación esperada: La página principal muestra un bloque rojo «CRITICAL ALARM: LEAK DETECTED». El endpoint /status devuelve {"leak_detected": true, "sensor_pin": 32, "device_mode": "SoftAP"}. El TTFB en la pestaña de red es inferior a 500ms.
  20. Condición de aprobación: La API JSON refleja el estado físico en tiempo real cumpliendo con el objetivo de latencia.

Solución de problemas

SíntomaCausa probableSolución
El código falla al cargarse (Tiempo de espera)El ESP32 no entra en modo bootloader automáticamente.Mantén presionado el botón «BOOT» en el DevKitC cuando la consola muestre «Connecting…». Suéltalo una vez que comience la carga.
La red WiFi no apareceInterferencia de energía o inicialización fallida.Presiona el botón EN (Reset) en el ESP32. Asegúrate de que el cable USB proporcione suficiente corriente (mínimo 500mA).
El sensor se activa cuando está seco (Falsos positivos)Pin de entrada flotante o humedad ambiental extrema.Verifica que la resistencia pull-down interna esté actuando, o añade una resistencia externa de 10k ohmios entre el GPIO 32 y GND.
El zumbador hace un sonido de clic, no un tono continuoEstás utilizando un zumbador pasivo en lugar de un zumbador activo.Reemplázalo con un zumbador activo de 3.3V, o reescribe la lógica para usar la biblioteca ledc del ESP32 para generar una señal PWM.
La página web tarda en cargar o agota el tiempo de esperaDesconexión de la red SoftAP.Algunos sistemas operativos se desconectan de redes sin internet. Asegúrate de que tu dispositivo esté configurado para «mantener la conexión» a ESP32_Water_Alert.

Mejoras

Una vez implementado el dispositivo base, considera estas mejoras para un entorno de producción:

  • Integración de interrupciones de hardware (ISR):
    • Reemplaza el sondeo continuo (digitalRead en el loop) con una interrupción de hardware (attachInterrupt) para garantizar que la detección ocurra estrictamente a nivel de hardware independientemente de la carga del servidor web.
  • Gestión de energía industrial:
    • Alimenta el sistema a través del pin VIN utilizando un convertidor buck industrial de 24V a 5V, permitiendo su integración directa en armarios de control de automatización (PLCs).
  • Protección ambiental:
    • Aplica un revestimiento conformado (conformal coating) de silicona a la placa ESP32 y aloja el sistema en una caja con clasificación IP65, dejando únicamente las sondas del sensor expuestas al entorno.

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Cuál es el microcontrolador principal utilizado para construir el dispositivo de detección de fugas?




Pregunta 2: ¿Qué tipo de red inalámbrica aloja el dispositivo de forma autónoma?




Pregunta 3: ¿Qué tipo de alarma activa el dispositivo al detectar una fuga de agua?




Pregunta 4: ¿Qué formato utiliza la API del dispositivo para informar su estado a otros dispositivos locales?




Pregunta 5: ¿Cuál es uno de los casos de uso mencionados para este dispositivo en salas de servidores?




Pregunta 6: ¿Por qué es una ventaja que el dispositivo opere en modo SoftAP?




Pregunta 7: ¿Qué permite prevenir este dispositivo en entornos industriales y residenciales?




Pregunta 8: ¿Qué interfaz proporciona el dispositivo para visualizar su estado en vivo?




Pregunta 9: ¿Qué sucede con la red de alerta local si hay un corte de red en el router principal del edificio?




Pregunta 10: Según el resultado esperado, ¿dónde muestra el ESP32 su dirección IP al inicializarse?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio