#include <Wire.h> // Comunicación I2C
#include <LiquidCrystal_I2C.h> // Pantalla LCD I2C
#include <DHTesp.h> // Sensor de temperatura y humedad DHT22
#include <ESP32Servo.h> // Control de servo con ESP32
// Pines asignados a sensores y actuadores
#define ACS712_PIN 34 // Sensor de corriente
#define ZMPT101B_PIN 35 // Sensor de voltaje
#define DHT_PIN 32 // Sensor DHT22
#define BUZZER_PIN 25 // Buzzer (alarma sonora)
#define SERVO_PIN 15 // Servo motor
#define POT_FIRE_PIN 33 // Potenciómetro simula sensor de fuego
#define RED_LED_PIN 2 // LED rojo (alerta fuego)
#define BLUE_LED_PIN 4 // LED azul (activa "extintor")
// Parámetros de conversión ADC
#define ADC_RESOLUTION 4095.0
#define ADC_VREF_mV 5000.0
#define SENSITIVITY 125.0 // No se usa pero podría servir para el sensor ACS712
// Instancias de los dispositivos
LiquidCrystal_I2C lcd(0x27, 20, 4);
DHTesp dhtSensor;
Servo servoMotor;
// Variables para controlar evento de fuego
unsigned long fireStartTime = 0;
bool fuegoActivo = false;
void setup() {
Serial.begin(115200);
lcd.init(); // Inicializa LCD
lcd.backlight(); // Enciende retroiluminación
// Configura pines
pinMode(ACS712_PIN, INPUT);
pinMode(ZMPT101B_PIN, INPUT);
pinMode(DHT_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(POT_FIRE_PIN, INPUT);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);
// Inicializa sensor DHT22
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
// Mensaje inicial
lcd.setCursor(2, 0);
lcd.print("SISTEMA MONITOREO");
delay(2000);
lcd.clear();
}
// Activa el buzzer con tono de 500 Hz
void activarBuzzer() {
tone(BUZZER_PIN, 500);
}
// Desactiva el buzzer
void desactivarBuzzer() {
noTone(BUZZER_PIN);
}
// Mueve el servo motor de 0 a 180 y de regreso
void activarServo() {
servoMotor.detach(); // Evita conflictos de canal
servoMotor.setPeriodHertz(50); // Frecuencia estándar
servoMotor.attach(SERVO_PIN, 500, 2400);
for (int pos = 0; pos <= 180; pos += 5) {
servoMotor.write(pos);
delay(10);
}
delay(500);
for (int pos = 180; pos >= 0; pos -= 5) {
servoMotor.write(pos);
delay(10);
}
servoMotor.write(0);
delay(100);
servoMotor.detach(); // Libera canal PWM
}
// Detecta y maneja situación de fuego
void manejarFuego() {
int valorPot = analogRead(POT_FIRE_PIN);
float porcentaje = (valorPot / 4095.0) * 100;
if (porcentaje > 50.0) { // Umbral de fuego
if (!fuegoActivo) {
fireStartTime = millis(); // Registra inicio
fuegoActivo = true;
}
digitalWrite(RED_LED_PIN, millis() / 200 % 2); // Parpadeo
activarBuzzer();
// Si el fuego persiste por más de 4 segundos, activar extintor
if (millis() - fireStartTime >= 4000) {
digitalWrite(BLUE_LED_PIN, HIGH);
Serial.println("🚨 Extintor activado");
} else {
digitalWrite(BLUE_LED_PIN, LOW);
}
Serial.println("🔥 FUEGO DETECTADO - Alarmas activadas");
} else {
if (fuegoActivo) {
Serial.println("✅ Fuego controlado");
}
fuegoActivo = false;
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, LOW);
}
}
void loop() {
// Lecturas de sensores
int adcValue_V = analogRead(ZMPT101B_PIN);
int adcValue_A = analogRead(ACS712_PIN);
float voltaje = (0.0148 * adcValue_V) + 80.0; // Estimación de voltaje
float voltage_mV = adcValue_A * (ADC_VREF_mV / ADC_RESOLUTION);
float corriente = ((voltage_mV - 2500) / 2500.0) * 40.0; // Estimación de corriente
TempAndHumidity data = dhtSensor.getTempAndHumidity();
float temp = data.temperature;
float humidity = data.humidity;
// Muestra los valores por serial
Serial.print("Voltaje: "); Serial.print(voltaje, 2);
Serial.print(" V | Corriente: "); Serial.print(corriente, 2);
Serial.print(" A | Temp: "); Serial.print(temp, 2);
Serial.print(" °C | Humedad: "); Serial.print(humidity, 1);
Serial.println(" %");
// Muestra en pantalla LCD
lcd.setCursor(0, 0);
lcd.print("Volt: ");
lcd.print(voltaje, 2);
lcd.print("V ");
lcd.setCursor(0, 1);
lcd.print("Amp: ");
lcd.print(corriente, 2);
lcd.print("A ");
lcd.setCursor(0, 2);
lcd.print("Temp: ");
lcd.print(temp, 2);
lcd.print("C ");
lcd.setCursor(0, 3);
lcd.print("Humedad: ");
lcd.print(humidity, 1);
lcd.print("% ");
// Variables de estado de alerta
bool alertaElectrica = false;
bool alertaClimatica = false;
// Indicadores de alerta en pantalla LCD y por Serial
lcd.setCursor(14, 0);
if (voltaje < 100.0) {
lcd.print("BAJO ");
Serial.println("⚠️ ALERTA: Voltaje bajo!");
alertaElectrica = true;
} else if (voltaje > 110.0) {
lcd.print("ALTO ");
Serial.println("⚠️ ALERTA: Voltaje alto!");
alertaElectrica = true;
} else {
lcd.print(" ");
}
lcd.setCursor(14, 1);
if (corriente > 15.0) {
lcd.print("ALTO ");
Serial.println("⚠️ ALERTA: Corriente alta!");
alertaElectrica = true;
} else {
lcd.print(" ");
}
lcd.setCursor(14, 2);
if (temp > 27.0) {
lcd.print("CALOR");
Serial.println("⚠️ ALERTA: Temperatura alta!");
alertaClimatica = true;
} else if (temp < 18.0) {
lcd.print("FRIO ");
Serial.println("⚠️ ALERTA: Temperatura baja!");
alertaClimatica = true;
} else {
lcd.print(" ");
}
lcd.setCursor(14, 3);
if (humidity < 40.0) {
lcd.print("BAJA ");
Serial.println("⚠️ ALERTA: Humedad baja!");
alertaClimatica = true;
} else if (humidity > 60.0) {
lcd.print("ALTA ");
Serial.println("⚠️ ALERTA: Humedad alta!");
alertaClimatica = true;
} else {
lcd.print(" ");
}
// Manejo de alertas climatológicas
if (alertaClimatica) {
Serial.println("🔔 Alerta clima: Buzzer por alerta de clima.");
activarBuzzer();
delay(500);
desactivarBuzzer();
activarServo(); // Simula activación de sistema
Serial.println("🔁 Servo en operación.");
}
// Manejo de alertas eléctricas
if (alertaElectrica) {
Serial.println("🔔 Alerta eléctrica: Buzzer por alerta eléctrica.");
activarBuzzer(); // Buzzer permanece activo
}
// Si no hay alertas, apagar todo
if (!alertaClimatica && !alertaElectrica && !fuegoActivo) {
desactivarBuzzer();
Serial.println("✅ Condiciones óptimas del sistema.");
}
// Verificación de fuego
manejarFuego();
Serial.println("----------------------");
delay(2000); // Espera antes de siguiente lectura
}