#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <PubSubClient.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pines
const int trigPin = 19;
const int echoPin = 23;
const int relayBombaPin = 18;
const int relayLed1Pin = 14;
const int relayLed2Pin = 27;
const int botonStartPin = 13;
const int botonStopPin = 25;
const int buzzerPin = 26;
const int ledAlarmaPin = 33;
// Estado del sistema
bool sistemaActivo = false;
bool bombaEncendida = false;
bool alarmaActiva = false;
// Umbrales del tanque (15 cm alto)
const float nivelCritico = 15.0;
const float nivelBajo = 10.0;
const float nivelMedio = 5.0;
// Wi‑Fi & MQTT
const char* ssid = "Wokwi-GUEST"; // Cambia esto si usas ESP32 físico
const char* password = "";
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_topic = "esp32/wokwi/nivel";
WiFiClient espClient;
PubSubClient client(espClient);
float medirDistanciaCM() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duracion = pulseIn(echoPin, HIGH, 30000);
if (duracion == 0) return -1;
return (duracion / 2.0) * 0.0343;
}
void conectarWiFi() {
Serial.print("Conectando a WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" conectado!");
}
void conectarMQTT() {
while (!client.connected()) {
Serial.print("MQTT connect…");
if (client.connect("ESP32-Wokwi")) {
Serial.println(" listo!");
} else {
Serial.print("falló rc=");
Serial.print(client.state());
Serial.println(", retry en 5 s");
delay(5000);
}
}
}
// 🔴 NUEVA FUNCIÓN MODIFICADA
void publicarMQTT(float dist) {
char payload[128];
const char* estadoBomba = bombaEncendida ? "ENCENDIDA" : "APAGADA";
const char* estadoAlarma = alarmaActiva ? "ACTIVA" : "INACTIVA";
snprintf(payload, sizeof(payload),
"{\"nivel\": %.2f, \"bomba\": \"%s\", \"alarma\": \"%s\"}",
dist, estadoBomba, estadoAlarma);
client.publish(mqtt_topic, payload);
}
void setup() {
Serial.begin(115200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(relayBombaPin, OUTPUT);
pinMode(relayLed1Pin, OUTPUT);
pinMode(relayLed2Pin, OUTPUT);
pinMode(botonStartPin, INPUT_PULLUP);
pinMode(botonStopPin, INPUT_PULLUP);
pinMode(buzzerPin, OUTPUT);
pinMode(ledAlarmaPin, OUTPUT);
digitalWrite(relayBombaPin, LOW);
digitalWrite(relayLed1Pin, LOW);
digitalWrite(relayLed2Pin, LOW);
digitalWrite(buzzerPin, LOW);
digitalWrite(ledAlarmaPin, LOW);
lcd.init();
lcd.backlight();
lcd.print("Iniciando...");
conectarWiFi();
lcd.setCursor(0, 1);
lcd.print("WiFi listo");
delay(1000);
lcd.clear();
client.setServer(mqtt_server, mqtt_port);
conectarMQTT();
}
void loop() {
if (!client.connected()) conectarMQTT();
client.loop();
float distancia = medirDistanciaCM();
bool btnStart = digitalRead(botonStartPin) == LOW;
bool btnStop = digitalRead(botonStopPin) == LOW;
if (btnStart) { sistemaActivo = true; alarmaActiva = false; }
if (btnStop) { sistemaActivo = false; bombaEncendida = false; alarmaActiva = false; }
if (sistemaActivo) {
if (distancia < 0 || distancia >= nivelCritico) {
bombaEncendida = false;
digitalWrite(relayLed1Pin, LOW);
digitalWrite(relayLed2Pin, LOW);
alarmaActiva = true;
}
else if (distancia > nivelBajo && distancia < nivelCritico) {
bombaEncendida = true;
digitalWrite(relayLed1Pin, LOW);
digitalWrite(relayLed2Pin, HIGH);
alarmaActiva = false;
}
else if (distancia > nivelMedio && distancia <= nivelBajo) {
bombaEncendida = true;
digitalWrite(relayLed1Pin, HIGH);
digitalWrite(relayLed2Pin, LOW);
alarmaActiva = false;
}
else {
bombaEncendida = false;
digitalWrite(relayLed1Pin, HIGH);
digitalWrite(relayLed2Pin, HIGH);
alarmaActiva = false;
}
} else {
bombaEncendida = false;
digitalWrite(relayLed1Pin, LOW);
digitalWrite(relayLed2Pin, LOW);
alarmaActiva = false;
}
digitalWrite(relayBombaPin, bombaEncendida ? LOW : HIGH);
digitalWrite(buzzerPin, alarmaActiva ? HIGH : LOW);
digitalWrite(ledAlarmaPin, alarmaActiva ? HIGH : LOW);
lcd.setCursor(0, 0);
lcd.print("Dist: ");
if (distancia < 0) lcd.print("Error ");
else {
lcd.print(distancia);
lcd.print(" cm ");
}
lcd.setCursor(0, 1);
if (!sistemaActivo) lcd.print("Sistema OFF ");
else if (distancia < 0 || distancia >= nivelCritico) lcd.print("VACIO ");
else if (distancia > nivelBajo) lcd.print("BAJO ");
else if (distancia > nivelMedio) lcd.print("MEDIO ");
else lcd.print("ALTO ");
// Publicar MQTT cada 1 segundo
static unsigned long lastEnvio = 0;
if (millis() - lastEnvio > 1000) {
publicarMQTT(distancia);
lastEnvio = millis();
}
delay(500);
}