/*
* Sistema de Riego Automatizado IoT - ESP32
* Monitoreo de Humedad de Suelo y Temperatura/Humedad Ambiental
* Autor: Jennifer Astudillo - Carlos Velasquez
* Asignatura: Aplicaciones Móviles para IoT
*/
#include "DHTesp.h"
// ===== CONFIGURACIÓN DE PINES =====
const int SOIL_SENSOR_PIN = 34; // GPIO34 - Sensor humedad suelo (ADC)
const int DHT_PIN = 4; // GPIO4 - Sensor DHT11
const int RELAY_PIN = 5; // GPIO5 - Módulo relé
const int LED_PIN = 2; // GPIO2 - LED indicador
// ===== PARÁMETROS DEL SISTEMA =====
const int HUMIDITY_THRESHOLD_MIN = 30; // Umbral mínimo humedad (%)
const int HUMIDITY_THRESHOLD_MAX = 60; // Umbral máximo humedad (%)
const int WATERING_TIME = 10000; // Tiempo de riego (10 seg)
const int CHECK_INTERVAL = 30000; // Intervalo de lectura (30 seg)
// ===== CALIBRACIÓN SENSOR SUELO =====
const int SOIL_DRY_VALUE = 4095; // Valor ADC suelo seco
const int SOIL_WET_VALUE = 1500; // Valor ADC suelo húmedo
// ===== VARIABLES GLOBALES =====
DHTesp dht;
int soilMoisturePercent = 0;
float temperature = 0;
float humidity = 0;
bool pumpRunning = false;
unsigned long lastCheckTime = 0;
unsigned long pumpStartTime = 0;
int soilRawValue = 0;
// ===== CONFIGURACIÓN INICIAL =====
void setup() {
Serial.begin(115200);
delay(1000);
// Configurar pines
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Relé apagado (HIGH)
digitalWrite(LED_PIN, LOW); // LED apagado
// Inicializar DHT11
dht.setup(DHT_PIN, DHTesp::DHT11);
// Mensaje de inicio
Serial.println("\n╔═══════════════════════════════════════════╗");
Serial.println("║ SISTEMA DE RIEGO AUTOMÁTICO IoT v1.0 ║");
Serial.println("║ Agricultura de Precisión - ESP32 ║");
Serial.println("╚═══════════════════════════════════════════╝\n");
printConfiguration();
Serial.println("Sistema inicializado correctamente\n");
}
// ===== BUCLE PRINCIPAL =====
void loop() {
unsigned long currentTime = millis();
// Verificar sensores en intervalos regulares
if (currentTime - lastCheckTime >= CHECK_INTERVAL || lastCheckTime == 0) {
lastCheckTime = currentTime;
readSensors();
printSensorData();
controlIrrigation();
}
// Detener bomba después del tiempo configurado
if (pumpRunning && (currentTime - pumpStartTime >= WATERING_TIME)) {
stopPump();
}
delay(100);
}
// ===== FUNCIONES DE LECTURA DE SENSORES =====
void readSensors() {
// Leer sensor de humedad del suelo
soilRawValue = analogRead(SOIL_SENSOR_PIN);
soilMoisturePercent = map(soilRawValue, SOIL_DRY_VALUE, SOIL_WET_VALUE, 0, 100);
soilMoisturePercent = constrain(soilMoisturePercent, 0, 100);
// Leer DHT11 (temperatura y humedad ambiental)
TempAndHumidity data = dht.getTempAndHumidity();
temperature = data.temperature;
humidity = data.humidity;
}
// ===== CONTROL DE RIEGO =====
void controlIrrigation() {
if (soilMoisturePercent < HUMIDITY_THRESHOLD_MIN && !pumpRunning) {
Serial.println("\n⚠️ ALERTA: Humedad del suelo baja");
startPump();
} else if (soilMoisturePercent >= HUMIDITY_THRESHOLD_MAX && pumpRunning) {
Serial.println("\n✓ Humedad óptima alcanzada");
stopPump();
}
}
void startPump() {
digitalWrite(RELAY_PIN, LOW); // Activar relé
digitalWrite(LED_PIN, HIGH); // Encender LED
pumpRunning = true;
pumpStartTime = millis();
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println("💧 BOMBA ACTIVADA - Iniciando riego");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
void stopPump() {
digitalWrite(RELAY_PIN, HIGH); // Desactivar relé
digitalWrite(LED_PIN, LOW); // Apagar LED
pumpRunning = false;
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println("⏹️ BOMBA DESACTIVADA - Riego completado");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
delay(2000);
readSensors();
printSensorData();
}
// ===== VISUALIZACIÓN DE DATOS =====
void printSensorData() {
Serial.println("┌─────────────────────────────────────────┐");
Serial.println("│ LECTURAS DE SENSORES EN TIEMPO REAL │");
Serial.println("├─────────────────────────────────────────┤");
// Humedad del suelo
Serial.print("│ 🌱 Humedad Suelo: ");
Serial.print(soilMoisturePercent);
Serial.print("% (");
Serial.print(soilRawValue);
Serial.println(" ADC)");
// Estado del suelo
Serial.print("│ 📊 Estado: ");
if (soilMoisturePercent < HUMIDITY_THRESHOLD_MIN) {
Serial.println("SECO ❌");
} else if (soilMoisturePercent > HUMIDITY_THRESHOLD_MAX) {
Serial.println("HÚMEDO 💧");
} else {
Serial.println("ÓPTIMO ✅");
}
// Temperatura ambiental
Serial.print("│ 🌡️ Temperatura: ");
Serial.print(temperature, 1);
Serial.println(" °C");
// Humedad ambiental
Serial.print("│ 💨 Humedad Ambiente: ");
Serial.print(humidity, 1);
Serial.println(" %");
// Estado de la bomba
Serial.print("│ 🔧 Estado Bomba: ");
Serial.println(pumpRunning ? "ACTIVA 🟢" : "INACTIVA 🔴");
Serial.println("└─────────────────────────────────────────┘\n");
}
void printConfiguration() {
Serial.println("⚙️ CONFIGURACIÓN DEL SISTEMA:");
Serial.println("─────────────────────────────────────");
Serial.print("• Umbral mínimo: ");
Serial.print(HUMIDITY_THRESHOLD_MIN);
Serial.println("%");
Serial.print("• Umbral máximo: ");
Serial.print(HUMIDITY_THRESHOLD_MAX);
Serial.println("%");
Serial.print("• Tiempo de riego: ");
Serial.print(WATERING_TIME / 1000);
Serial.println(" segundos");
Serial.print("• Intervalo de verificación: ");
Serial.print(CHECK_INTERVAL / 1000);
Serial.println(" segundos\n");
}