#define BLYNK_TEMPLATE_ID "TMPL2p7xiWejH" // ID de plantilla de Blynk
#define BLYNK_TEMPLATE_NAME "Detección de nivel de agua" // Nombre de plantilla de Blynk
#define BLYNK_AUTH_TOKEN "Sdx3tCL8Q5KHxoaD1p9QFDqGgIFWIOV9" // Token de autenticación de Blynk
#define BLYNK_PRINT Serial // Se habilita salida de depuración para Blynk por el puerto serial
/* Se importan bilbiotecas para manejar conexiones Wi-Fi,
así como también integraciones de Blynk con ESP32 y
una biblioteca para manejo de servomotores con ESP32 */
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>
#define trig 15 // Se define Pin 15 para Trigger del sensor HC-SR04
#define echo 26 // Se define Pin 26 para Echo del sensor HC-SR04
char ssid[] = "Wokwi-GUEST"; // Nombre de la red Wi-Fi a la que se conectará el proyecto
char pass[] = ""; // Contraseña de la red Wi-Fi
int tankdepth = 400; // Se define la profundidad del tanque en centímetros
float distance = 0; // Se inicializa variable de distancia medida por el sensor en centímetros
float waterLevel = 0; // Se inicializa variable de nivel porcentual de agua en el tanque
Servo servoMotor; // Se inicializa objeto de clase Servo
int servoPin = 18; // Se define el Pin 18 para accionar el servomotor
bool servoOpened = false; // Se establece valor booleano para la posición inicial del servomotor
BlynkTimer timer; // Se define un temporizador para actualizaciones regulares
char auth[] = BLYNK_AUTH_TOKEN; // Se define el token de autentificación para conectarse a blynk.cloud
float measureDistance(); // Se define función para medir distancia
void setup() {
Serial.begin(115200); // Se inicializa comunicación serie
// Configuración de pines del sensor ultrasónico
pinMode(trig, OUTPUT); // Pin Trigger como salida
pinMode(echo, INPUT); // Pin Echo como entrada
// Configuración de servomotor
servoMotor.attach(servoPin, 500, 2500); // Configuración del Pin para el servo y límites de pulso
servoMotor.write(0); // Servomotor colocado en posición inicial (cerrado)
Blynk.begin(auth, ssid, pass); // Se inicializa la conexión con Blynk
// Configuración para envío de datos a Blynk cada 1000 ms
timer.setInterval(1000L, sendWaterLevelToBlynk);
}
void loop() {
Blynk.run(); // Ejecución del ciclo principal de Blynk para mantener la conexión
timer.run(); // Ejecución de temporizador
}
void sendWaterLevelToBlynk() {
distance = measureDistance(); // Obtención de distancia mediante sensor HC-SR04
waterLevel = (tankdepth - distance) / tankdepth * 100; // Cálculo de nivel de agua en tanque (porcentaje)
waterLevel = constrain(waterLevel, 0, 100); // Restricción de nivel de agua entre 0% y 100%
// Despliegue de información en consola para la distancia medida del sensor hasta el agua
Serial.print("Distancia medida: ");
Serial.print(distance);
Serial.println(" cm");
// Despliegue de información en consola para el nivel de agua detectado en el depósito
Serial.print("Nivel de agua: ");
Serial.print(waterLevel);
Serial.println("%");
/* Sentencia if para accionar apertura del servomotor en caso de que el nivel de agua llegue y/o sobrepase
el 80% de la capacidad total del tanque y se cierre cuando este valor sea menor a 80% */
if (waterLevel >= 80 && !servoOpened) {
Serial.println("Nivel del agua al 80% o más. Abriendo el servo...");
servoMotor.write(90); // Apertura de servomotor
servoOpened = true; // Se marca el servomotor como abierto
} else if (waterLevel < 80 && servoOpened) {
Serial.println("Nivel del agua por debajo del 80%. Cerrando el servo...");
servoMotor.write(0); // Cierre del servomotor
servoOpened = false; // Se marca el servomotor como cerrado
}
Blynk.virtualWrite(V1, waterLevel); // Envío de nivel de agua a plataforma Blynk a widget (V1)
// Envío de distancia en cm a widget (V2)
Blynk.virtualWrite(V2, String("Distancia: ") + String(distance) + " cm");
// Envío de nivel de agua en porcentaje a widget (V3)
Blynk.virtualWrite(V3, String("Nivel: ") + String(waterLevel) + "%");
}
float measureDistance() {
// Envío de pulso de 10 microsegundos al Trigger
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
long duration = pulseIn(echo, HIGH, 30000); // Lectura de pulso en Echo enviado por Trigger
// En caso de no recibir una respuesta se despliega mensaje de error por consola
if (duration == 0) {
Serial.println("Error: no se recibió respuesta del sensor.");
}
float distanceCm = (duration * 0.0343) / 2; // Cálculo de distancia en centímetros (velocidad del sonido en cm/us = 0.0343)
/* Si la distancia es mayor a la profundiad del tanque, se asumirá
que este se encuentra vacío */
if (distanceCm > tankdepth) {
Serial.println("Distancia mayor que la profundidad máxima del tanque. Asumiendo tanque vacío.");
return tankdepth;
}
return distanceCm; // Se retorna valor de distancia medida
}