/*# =============================================================================
# UNIVERSIDAD INTERNACIONAL DE LA RIOJA (UNIR) - MAESTRÍA INDUSTRIA 4.0
# Autor: [Henry] - Versión: 10.1 Final - Fecha: [29/10/2025]
# =============================================================================*/
// ============ INCLUSIÓN DE BIBLIOTECAS ============
#include <Adafruit_Sensor.h> // Framework base de sensores Adafruit
#include <DHT.h> // Driver específico para la familia de sensores DHT
#include <DHT_U.h> // Capa de compatibilidad para el framework unificado (Unified)
// ============ CONFIGURACIÓN DE HARDWARE Y PINES ============
#define DHT_PIN 4 // GPIO4 para la línea de datos del sensor DHT22
#define TEMP_LED_PIN 14 // GPIO14 para indicador visual de alarma térmica
#define HUM_LED_PIN 15 // GPIO15 para indicador visual de alarma de humedad
#define TEMP_ACK_BUTTON_PIN 26 // GPIO26 para el pulsador de reconocimiento de temperatura
#define HUM_ACK_BUTTON_PIN 27 // GPIO27 para el pulsador de reconocimiento de humedad
// ============ UMBRALES Y PARÁMETROS DE OPERACIÓN ============
#define DHT_TYPE DHT22 // Define el modelo exacto de sensor utilizado
const float TEMP_ALARM_THRESHOLD = 45.0; // Umbral térmico base para activación de alarma (°C)
const float HUM_ALARM_MIN_THRESHOLD = 25.0; // Umbral mínimo de humedad para activación de alarma (%)
const float HUM_ALARM_MAX_THRESHOLD = 60.0; // Umbral máximo de humedad para activación de alarma (%)
const float TEMP_HYSTERESIS = 1.0; // Margen de histéresis para temperatura (evita oscilaciones)
const float HUM_HYSTERESIS = 2.0; // Margen de histéresis para humedad (evita oscilaciones)
const unsigned long SENSOR_READ_INTERVAL = 1000; // Intervalo entre lecturas del sensor (1000ms = 1s)
const unsigned long DEBOUNCE_DELAY = 200; // Tiempo de anti-rebote para los pulsadores (200ms)
// ============ VARIABLES DE ESTADO GLOBALES ============
float current_temperature = 0.0;
float current_humidity = 0.0;
bool temp_alarm_active = false;
bool hum_alarm_active = false;
bool temp_alarm_acknowledged = false;
bool hum_alarm_acknowledged = false;
unsigned long last_sensor_read_time = 0;
unsigned long last_temp_button_time = 0;
unsigned long last_hum_button_time = 0;
// ============ INSTANCIAS DE OBJETOS ============
DHT_Unified dht(DHT_PIN, DHT_TYPE);
// ============ FUNCIÓN DE CONFIGURACIÓN PRINCIPAL (setup) ============
void setup() {
Serial.begin(115200);
Serial.println("Iniciando Sistema de Monitoreo Ambiental...");
pinMode(TEMP_LED_PIN, OUTPUT);
pinMode(HUM_LED_PIN, OUTPUT);
digitalWrite(TEMP_LED_PIN, LOW);
digitalWrite(HUM_LED_PIN, LOW);
pinMode(TEMP_ACK_BUTTON_PIN, INPUT_PULLDOWN);
pinMode(HUM_ACK_BUTTON_PIN, INPUT_PULLDOWN);
dht.begin();
}
// ============ BUCLE DE EJECUCIÓN PRINCIPAL (loop) ============
void loop() {
handle_sensor_readings();
update_alarm_states();
handle_acknowledge_buttons();
update_led_indicators();
}
// ============ DEFINICIÓN DE FUNCIONES AUXILIARES ============
void handle_sensor_readings() {
if (millis() - last_sensor_read_time >= SENSOR_READ_INTERVAL) {
last_sensor_read_time = millis();
sensors_event_t event;
bool value_changed = false;
dht.temperature().getEvent(&event);
if (!isnan(event.temperature)) {
if (event.temperature != current_temperature) {
current_temperature = event.temperature;
value_changed = true;
}
}
dht.humidity().getEvent(&event);
if (!isnan(event.relative_humidity)) {
if (event.relative_humidity != current_humidity) {
current_humidity = event.relative_humidity;
value_changed = true;
}
}
if (value_changed) {
Serial.print("Cambio detectado -> ");
Serial.print("Temperatura: ");
Serial.print(current_temperature);
Serial.print(" °C | Humedad: ");
Serial.print(current_humidity);
Serial.println(" %");
}
}
}
/**
* @brief Evalúa las lecturas, actualiza el estado de las alarmas, y notifica
* tanto la activación como la normalización de las condiciones.
*/
void update_alarm_states() {
// --- Lógica de Temperatura ---
const float temp_turn_off_threshold = TEMP_ALARM_THRESHOLD - TEMP_HYSTERESIS;
if (!temp_alarm_active && current_temperature > TEMP_ALARM_THRESHOLD) {
temp_alarm_active = true;
Serial.println("*** ALARMA DE TEMPERATURA ACTIVADA ***");
} else if (temp_alarm_active && current_temperature < temp_turn_off_threshold) {
Serial.println("--- Condición de Temperatura Normalizada ---");
temp_alarm_active = false;
temp_alarm_acknowledged = false;
}
// --- Lógica de Humedad ---
const float hum_turn_off_low_threshold = HUM_ALARM_MIN_THRESHOLD + HUM_HYSTERESIS;
const float hum_turn_off_high_threshold = HUM_ALARM_MAX_THRESHOLD - HUM_HYSTERESIS;
if (!hum_alarm_active && (current_humidity < HUM_ALARM_MIN_THRESHOLD || current_humidity > HUM_ALARM_MAX_THRESHOLD)) {
hum_alarm_active = true;
Serial.println("*** ALARMA DE HUMEDAD ACTIVADA ***");
} else if (hum_alarm_active && (current_humidity > hum_turn_off_low_threshold && current_humidity < hum_turn_off_high_threshold)) {
Serial.println("--- Condición de Humedad Normalizada ---");
hum_alarm_active = false;
hum_alarm_acknowledged = false;
}
}
void handle_acknowledge_buttons() {
if (digitalRead(TEMP_ACK_BUTTON_PIN) == HIGH) {
if (millis() - last_temp_button_time > DEBOUNCE_DELAY) {
if (temp_alarm_active) {
temp_alarm_acknowledged = true;
Serial.println("===> ALARMA DE TEMPERATURA RECONOCIDA <===");
}
last_temp_button_time = millis();
}
}
if (digitalRead(HUM_ACK_BUTTON_PIN) == HIGH) {
if (millis() - last_hum_button_time > DEBOUNCE_DELAY) {
if (hum_alarm_active) {
hum_alarm_acknowledged = true;
Serial.println("===> ALARMA DE HUMEDAD RECONOCIDA <===");
}
last_hum_button_time = millis();
}
}
}
void update_led_indicators() {
if (temp_alarm_active && !temp_alarm_acknowledged) {
digitalWrite(TEMP_LED_PIN, HIGH);
} else {
digitalWrite(TEMP_LED_PIN, LOW);
}
if (hum_alarm_active && !hum_alarm_acknowledged) {
digitalWrite(HUM_LED_PIN, HIGH);
} else {
digitalWrite(HUM_LED_PIN, LOW);
}
}