Hola chicos, muy buenos días, tengo un problema con mi proyecto, estoy realizando un sistema de riego, y sucede que el Sensor de flujo de agua YF-S201, me mide correctamente pero no regresa a 0 cuando deja de pasar agua, siempre queda en algun valor aleatorio menor al que llego a medir. Creo que el problema es en mi codigo, porque lo he probado con otros codigos y si funciona, me he guiado de aquellos para hacer este, pero me da ese error, no consigo donde está el problema. Recurro a ustedes solicitando una ayuda, tengo que entregar el trabajo la proxima semana y ya no encuentro que hacer. Aca mi codigo:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define I2C_ADDR 0x27
LiquidCrystal_I2C lcd(I2C_ADDR, 16, 2);
int distance;
int BombRiegoPin = 8;
int HumedadSensor = A0;
int lectura = 0;
int BombLlenadoPin = 5;
volatile int NumPulsos;
int waterFlowSensorPin = 2;
float factor_conversion = 7.5;
const int ultrasonicTrigPin = 12;
const int ultrasonicEchoPin = 13;
const int nivelMaximoTanque = 3;
const int nivelMinimoTanque = 10;
int porcentajeTanque;
int pantallaActual;
const int cantPantallas = 4;
unsigned long tiempo_previo = 0; // Tiempo previo para el conteo de pulsos
int frecuencia = 0;
void ContarPulsos() {
if (millis() - tiempo_previo >= 500) {
frecuencia = NumPulsos; // Guarda los pulsos por segundo en Hz
NumPulsos = 0; // Reinicia el contador de pulsos
tiempo_previo = millis(); // Guarda el tiempo actual
}
NumPulsos++;
}
int ObtenerFrecuencia() {
return frecuencia;
}
int calcularPorcentajeTanque(int distancia) {
// Mapeo la distancia a un porcentaje
return map(distancia, nivelMinimoTanque, nivelMaximoTanque, 0, 100);
}
void mostrarCaudal() {
frecuencia = ObtenerFrecuencia();
float caudal_L_m = frecuencia / factor_conversion; //ecuaciones para calcular el caudal
float caudal_L_h = caudal_L_m * 60;
lcd.setCursor(0, 0);
lcd.print("Caudal: ");
lcd.print(caudal_L_m, 2);
lcd.print(" L/m");
}
void mostrarNivelTanque() {
lcd.setCursor(0, 0);
lcd.print("Nivel: ");
lcd.print(porcentajeTanque);
lcd.print("%");
}
void mostrarEstadoBombas() {
lcd.setCursor(0, 0);
lcd.print("Riego: ");
lcd.print(digitalRead(BombRiegoPin) == LOW ? "ON" : "OFF");
lcd.setCursor(0, 1);
lcd.print("Llenado: ");
lcd.print(digitalRead(BombLlenadoPin) == LOW ? "ON" : "OFF");
}
void mostrarEstadoSuelo() {
lectura = analogRead(HumedadSensor);
lcd.setCursor(0, 0);
lcd.print("Suelo: ");
if (lectura >= 800) {
lcd.print("Seco");
} else if (lectura >= 500) {
lcd.print("Humedo");
} else {
lcd.print("Mojado");
}
}
void mostrarPantalla(int pantalla) {
lcd.clear();
switch (pantalla) {
case 0: mostrarCaudal(); break;
case 1: mostrarNivelTanque(); break;
case 2: mostrarEstadoBombas(); break;
case 3: mostrarEstadoSuelo(); break;
}
}
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(BombRiegoPin, OUTPUT);
pinMode(waterFlowSensorPin, INPUT);
pinMode(BombLlenadoPin, OUTPUT);
pinMode(ultrasonicTrigPin, OUTPUT);
pinMode(ultrasonicEchoPin, INPUT);
attachInterrupt(digitalPinToInterrupt(waterFlowSensorPin), ContarPulsos, RISING); //Uso de la interrupcion con flanco ascendente
}
void loop() {
int frecuencia = ObtenerFrecuencia(); // Obtener frecuencia una vez
float caudal_L_m = frecuencia / factor_conversion;
float caudal_L_h = caudal_L_m * 60;
Serial.print("FrecuenciaPulsos: ");
Serial.print(frecuencia, 0);
Serial.print("Hz\tCaudal: ");
Serial.print(caudal_L_m, 3);
Serial.print("L/m\t");
Serial.print(caudal_L_h, 3);
Serial.println("L/h");
digitalWrite(ultrasonicTrigPin, LOW);
delayMicroseconds(2);
digitalWrite(ultrasonicTrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(ultrasonicTrigPin, LOW);
long duration = pulseIn(ultrasonicEchoPin, HIGH);
distance = duration * 0.034 / 2;
Serial.print("Distancia: ");
Serial.print(distance);
Serial.println(" cm");
porcentajeTanque = calcularPorcentajeTanque(distance); // Calcular porcentaje del tanque
Serial.print("Porcentaje del tanque: ");
Serial.print(porcentajeTanque);
Serial.println("%");
lectura = analogRead(HumedadSensor);
Serial.print("La lectura es:");
Serial.println(lectura);
// lecturas entre 300-1023
if (lectura >= 800) {
Serial.println(">> SUELO COMPLETAMENTE SECO <<");
} else if (lectura < 800 && lectura >= 600) {
Serial.println(">> SUELO LIGERAMENTE HUMEDO <<");
} else if (lectura < 599 && lectura >= 501) {
Serial.println(">> SUELO HUMEDO <<");
} else if (lectura <= 500) {
Serial.println(">> SUELO MUY MOJADO");
}
// Control de la bomba de riego //
if (lectura >= 600 && distance < 10) { // Se puede regar, porque el tanque esta a un buen nivel
digitalWrite(BombRiegoPin, LOW); // Enciende la bomba
} else {
digitalWrite(BombRiegoPin, HIGH); // Apaga la bomba si no se cumplen las condiciones
}
// Control de la bomba de llenado //
if (caudal_L_m >= 2.0 && distance > nivelMaximoTanque) { // Se necesita llenar porque esta vacio
digitalWrite(BombLlenadoPin, LOW); // Enciende la bomba
} else {
digitalWrite(BombLlenadoPin, HIGH); // Apaga la bomba
}
mostrarPantalla(pantallaActual);
delay(2000);
pantallaActual = (pantallaActual + 1) % cantPantallas; // Cambia a la siguiente pantalla
}