Control automatico de tanques

Hola, estoy modificando un codigo que sirve para controlar el llenado de un tanque por medio de otro tanque de reserva, tiene dos sensores ultrasonicos que dicen el porcentaje en cada tanque. Mis problemas son basicamente dos. Uno es que el display se "borra" por unos segundos, para despues aparecer de nuevo los datos y el segundo problema, es que no quiero que aparezcan decimales en el porcentaje de los tanques, alguna sugerencia por favor? dejo el codigo:

#include <LiquidCrystal_I2C.h>
#define triggertank 4
#define echotank 5
//tank
#define triggersump 2
#define echosump 3
//sump
LiquidCrystal_I2C lcd(0x38,20,4);

float time1=0, distance1=0, time2=0,
distance2=0, tankp=0;

float low=3;

const int MOTOR = 8;

String buf;

void setup ()

{

  pinMode (triggertank, OUTPUT) ;
  pinMode (triggersump, OUTPUT) ;
  pinMode (echosump,INPUT) ;
  pinMode (echotank,INPUT) ;
  pinMode (MOTOR, OUTPUT) ;
  
  lcd.init () ;
  lcd.backlight () ;
  lcd.setCursor (0,0) ;
  lcd.print ("Control automatico") ;
  lcd.setCursor (0,1) ;
  delay (100) ;
  lcd.print ("    de agua    ") ;
  delay (100) ;
  
}

void loop ()
{
  
  lcd.clear () ;
  digitalWrite (triggersump,LOW) ;
  delayMicroseconds (2) ;
  digitalWrite (triggersump,HIGH) ;
  delayMicroseconds (10) ;
  digitalWrite (triggersump,LOW) ;
  delayMicroseconds (2) ;
  time1=pulseIn (echosump,HIGH) ;
  distance1=time1*0.034/2;
  //SUMPSTUFF 
  digitalWrite(triggertank,LOW) ;
  delayMicroseconds(2) ;
  digitalWrite(triggertank,HIGH) ;
  delayMicroseconds(10) ;
  digitalWrite(triggertank,LOW) ;
  delayMicroseconds(2) ;
  time2=pulseIn(echotank,HIGH) ;
  distance2=time2*0.034/2;
  //TANKSTUFF
   
  if(distance1>=23)
  
  {
  
  digitalWrite(MOTOR, HIGH) ;
  lcd.setCursor (1,0) ;
  lcd.print ("SUMP : EMPTY") ;
  lcd.setCursor (1,1) ;
  lcd.print ("PUMP : OFF") ;
  delay (500) ;
  
}//00_01

else if (distance1<23)
  {
  
  lcd.setCursor (1,0) ;
  lcd.print ("SUMP : NOT EMPTY") ;
  if(distance2<low)
  {
  
  digitalWrite (MOTOR, HIGH) ;
  lcd.setCursor (1,1);
  lcd.print ("PUMP : OFF") ;
  low=15.00;
  delay (100) ;
  }//11
  else if (distance2>=low)
  {
  
  digitalWrite (MOTOR, LOW) ;
  lcd.setCursor (1,1) ;
  lcd.print ("PUMP : ON") ;
  delay (100) ;
  }//10
  
  }
  tankp=(1-distance1/9.52)*100 ;
  buf = String (tankp, 2) ;
  lcd.setCursor (1,3) ;
  lcd.print ("SUMP LEVEL: ") ;
  lcd.print(buf) ;
  lcd.print("%") ;
     
  tankp=(1-distance2/9.52)*100 ;
  buf = String (tankp, 2) ;
  lcd.setCursor (1,2) ;
  lcd.print ("TANK LEVEL: ") ;
  lcd.print(buf) ;
  lcd.print("%") ;
  delay (1200) ;
  }//ENDOFPROGRAM

Moderador:
Por favor, lee las Normas del foro y edita tu título retirando el comenario "ayuda por favor".
Lee el punto 5 de las normas sobre cómo debe ser un título.

Mira como se comporta esto.

/*
Mi problema son basicamente dos.
Uno es que el display se "borra" por unos segundos, para despues aparecer de nuevo los datos y
el segundo problema, es que no quiero que aparezcan decimales en el porcentaje de los tanques,
alguna sugerencia por favor? dejo el codigo:
*/

#include <Arduino.h>

#include <LiquidCrystal_I2C.h>
#define triggertank 4
#define echotank    5
//tank
#define triggersump 2
#define echosump    3
//sump
LiquidCrystal_I2C lcd(0x38, 20, 4);

float distancia1, distancia2;
float low_distancia_distancia = 3.0;
const int MOTOR = 8;

float mido_ultrasonico(int trig, int echo) {
  float tmp;
  long time1;
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  time1 = pulseIn(echo, HIGH);
  //tmp = time1 * 0.034 / 2;
  tmp = time1 * 0.017;
  return tmp;
}

void porcentaje(float dist, String msg) {
  float tankp;
  String buf;
  tankp = (1 - dist / 9.52) * 100;
  buf = String(tankp, 0);
  lcd.setCursor(1, 3);
  lcd.print(msg);
  lcd.print(buf);
  lcd.print("%");
}

void setup() {
  pinMode(triggertank, OUTPUT);
  pinMode(triggersump, OUTPUT);
  pinMode(echosump, INPUT);
  pinMode(echotank, INPUT);
  pinMode(MOTOR, OUTPUT);

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Control automatico");
  lcd.setCursor(0, 1);
  delay(100);
  lcd.print("    de agua    ");
  delay(100);
}

void loop() {

  distancia1 = mido_ultrasonico(triggersump, echosump); // SUMPSTUFF
  distancia2 = mido_ultrasonico(triggersump, echosump); // TANKSTUFF

  if (distancia1 >= 23.0) {
    digitalWrite(MOTOR, HIGH);
    lcd.setCursor(1, 0);
    //         01234567890123456
    lcd.print("SUMP : EMPTY    ");
    lcd.setCursor(1, 1);
    //         01234567890123456
    lcd.print("PUMP : OFF      ");
    delay(500);
  } // 00_01
  else if (distancia1 < 23.0) {
    lcd.setCursor(1, 0);
    //         01234567890123456
    lcd.print("SUMP : NOT EMPTY");
    if (distancia2 < low_distancia) {
      digitalWrite(MOTOR, HIGH);
      lcd.setCursor(1, 1);
      //         01234567890123456
      lcd.print("PUMP : OFF      ");
      low_distancia = 15.00;
      delay(100);
    }//11
    else if (distancia2 >= low_distancia) {

      digitalWrite(MOTOR, LOW);
      lcd.setCursor(1, 1);
      //         01234567890123456
      lcd.print("PUMP : ON       ");
      delay(100);
    } // 10
  }
  porcentaje(distancia1, "SUMP LEVEL: ");
  porcentaje(distancia2, "TANK LEVEL: ");

  delay(1200);
} // ENDOFPROGRAM

El gran cambio esta en que todos los carteles tienen la misma longitud salvo estos últimos dos que si muestran problemas tendras que ajustar.

Gracias por su tiempo, trato de compilar pero me dice: 'low_distancia' was not declared in this scope.

Fijate que se deslizó un error

float low_distancia_distancia = 3.0;

debería ser

float low_distancia = 3.0;

Muchas gracias, ya compilo sin problemas! solo que ahora se enciman los datos en pantalla de SUMP y TANK. Busco el problema pero no lo encuentro, soy novato y aunque entiendo un poco como funciona por bloques, me pierdo a la hora de entender todo el programa en su conjunto. Sigo probando...

El problema es que porcentaje() imprime siempre en la misma línea.
Modifícala de esta forma

void porcentaje(float dist, String msg, int linea) { 
  float tankp; 
  String buf; 
  tankp = (1 - dist / 9.52) * 100; 
  buf = String(tankp, 0); 
  lcd.setCursor(1, linea); 
  lcd.print(msg); 
  lcd.print(buf); 
  lcd.print("%"); 
} 

Y luego modifica las 2 líneas donde la llamas de esta forma

porcentaje(distancia1, "SUMP LEVEL: ", 3); 
porcentaje(distancia2, "TANK LEVEL: ", 2);

Fíjate que agregué un parámetro (linea) con el que indicas en cual línea del LCD se imprimen msg y dist.

Saludos

Gracias, ya hice los cambios y funciona! seguire con las pruebas ya que tambien quiero implementar un sensor "dry run" para que en caso de falla de la valvula de la cisterna, la bomba de agua no trabaje en seco. Dejo el codigo actualizado hasta el momento:

#include <Arduino.h>

#include <LiquidCrystal_I2C.h>
#define triggertank 4
#define echotank    5
//tank
#define triggersump 2
#define echosump    3
//sump
LiquidCrystal_I2C lcd(0x38, 20, 4);

float distancia1, distancia2;
float low_distancia = 3.0;
const int MOTOR = 8;

float mido_ultrasonico(int trig, int echo) {
  float tmp;
  long time1;
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  time1 = pulseIn(echo, HIGH);
  //tmp = time1 * 0.034 / 2;
  tmp = time1 * 0.017;
  return tmp;
}

void porcentaje(float dist, String msg, int linea) { 
  float tankp; 
  String buf; 
  tankp = (1 - dist / 9.52) * 100; 
  buf = String(tankp, 0); 
  lcd.setCursor(1, linea); 
  lcd.print(msg); 
  lcd.print(buf); 
  lcd.print("%"); 
}

void setup() {
  pinMode(triggertank, OUTPUT);
  pinMode(triggersump, OUTPUT);
  pinMode(echosump, INPUT);
  pinMode(echotank, INPUT);
  pinMode(MOTOR, OUTPUT);

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 1);
  lcd.print("*CONTROL AUTOMATICO*");
  lcd.setCursor(0, 2);
  delay(100);
  lcd.print("-TINACO Y CISTERNA-");
  delay(1000);
  lcd.setCursor (0,1) ;
  lcd.print ("                    ") ;
  lcd.setCursor (0,2) ;
  lcd.print ("                    ") ;
  delay (1000) ;
  }

void loop() {

  distancia1 = mido_ultrasonico(triggersump, echosump); // SUMPSTUFF
  distancia2 = mido_ultrasonico(triggertank, echotank); // TANKSTUFF

  if (distancia1 >= 23.0) {
    digitalWrite(MOTOR, HIGH);
    lcd.setCursor(1, 0);
    //         01234567890123456
    lcd.print("SUMP : EMPTY    ");
    lcd.setCursor(1, 1);
    //         01234567890123456
    lcd.print("PUMP : OFF      ");
    delay(500);
  } // 00_01
  else if (distancia1 < 23.0) {
    lcd.setCursor(1, 0);
    //         01234567890123456
    lcd.print("SUMP : NOT EMPTY");
    if (distancia2 < low_distancia) {
      digitalWrite(MOTOR, HIGH);
      lcd.setCursor(1, 1);
      //         01234567890123456
      lcd.print("PUMP : OFF      ");
      low_distancia = 15.00;
      delay(100);
    }//11
    else if (distancia2 >= low_distancia) {

      digitalWrite(MOTOR, LOW);
      lcd.setCursor(1, 1);
      //         01234567890123456
      lcd.print("PUMP : ON       ");
      delay(100);
    } // 10
  }
  porcentaje(distancia1, "SUMP LEVEL: ",3);
  porcentaje(distancia2, "TANK LEVEL: ",2);

  delay(1200);
} // ENDOFPROGRAM

Hola, ya escribi un pequeño codigo agregando un sensor "dry run protection" y un buzzer para que sirva de alarma, pero no se como integrarlo al codigo anterior. Me pueden orientar? aqui dejo el codigo:

//Si la bomba se activa, pero no sube agua, 
//el sensor "dry" lo detecta y la bomba
//se desactiva a los 5 segundos y
//activa el buzzer como alarma
//beep cada segundo.



#define dry 6
#define buzzer 7

if(digitalRead(6) == HIGH){
  delay (5000);
  (digitalWrite(MOTOR, LOW);
  (digitalWrite(buzzer, HIGH);
  delay(1000);
  (digitalWrite(buzzer, LOW);
  delay (1000);
}
else {
  digitalWrite(MOTOR,HIGH);
  (digitalWrite(buzzer, LOW);
  
}

pinMode(dry,INPUT);
pinMode(buzzer,OUTPUT);

No entendí...
¿Escribiste un segmento de código que no sabes cómo integrar a tu propio código?

Asi es. es que veo que hay que seguir cierta secuencia y aun no capto como deben integrarse los bloques y mas cuando son if ó else.

Actualizo... revise el codigo, ajuste lo mas que pude (lo que da mi conocimiento) y probe en real con el circuito. y trabaja todo bien. Me falta integrar el pequeño codigo para las cosas que le quiero agregar, solo que antes de eso, veo que el porcentaje se pasa de 0% y 100%, estuve investigando y es decirle a una variable que no pase de ahi, <=0 =0 y >=100 =100 pero no encuentro cual es la variable que me cambia eso, pues probe con casi todas y en unas me presenta error de compilacion y en otras simplemente no hace nada. Que tengo que cambiar?

#include <Arduino.h>

#include <LiquidCrystal_I2C.h>
#define triggertank 4
#define echotank    5
//tank
#define triggersump 2
#define echosump    3
//sump
LiquidCrystal_I2C lcd(0x3F, 20, 4);

float distancia1, distancia2;
float low_distancia = 3.0;
const int MOTOR = 8;

float mido_ultrasonico(int trig, int echo) {
  float tmp;
  long time1;
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  time1 = pulseIn(echo, HIGH);
  //tmp = time1 * 0.034 / 2;
  tmp = time1 * 0.017;
  return tmp;
}

void porcentaje(float dist, String msg, int linea) { 
  float tankp; 
  String buf; 
  tankp = (1 - dist / 130) * 150; //29*100 para distancia corta,130*150 distancia larga, 9.52 original
  buf = String(tankp, 0); 
  lcd.setCursor(1, linea); 
  lcd.print(msg); 
  lcd.print(buf); 
  lcd.print("%"); 
} 

void setup() {
  pinMode(triggertank, OUTPUT);
  pinMode(triggersump, OUTPUT);
  pinMode(echotank, INPUT);
  pinMode(echosump, INPUT);
  pinMode(MOTOR, OUTPUT);

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 1);
  lcd.print("*CONTROL AUTOMATICO*");
  lcd.setCursor(0, 2);
  delay(100);
  lcd.print("-TINACO Y CISTERNA-");
  delay(1000);
  lcd.setCursor (0,1) ;
  lcd.print ("                    ") ;
  lcd.setCursor (0,2) ;
  lcd.print ("                    ") ;
  delay (1000) ;
  }

void loop() {

  distancia1 = mido_ultrasonico(triggertank, echotank); // TANKSTUFF
  distancia2 = mido_ultrasonico(triggersump, echosump); // SUMPSTUFF

  if (distancia2 >= 23.0) {
    digitalWrite(MOTOR, HIGH);
    lcd.setCursor(1, 0);
    //         01234567890123456
    lcd.print("SUMP : EMPTY    ");
    lcd.setCursor(1, 1);
    //         01234567890123456
    lcd.print("PUMP : OFF      ");
    delay(500);
  } // 00_01
  else if (distancia2 < 23.0) {
    lcd.setCursor(1, 0);
    //         01234567890123456
    lcd.print("SUMP : NOT EMPTY");
    if (distancia1 < low_distancia) {
      digitalWrite(MOTOR, HIGH);
      lcd.setCursor(1, 1);
      //         01234567890123456
      lcd.print("PUMP : OFF      ");
      low_distancia = 15.00;
      delay(100);
    }//11
    else if (distancia1 >= low_distancia) {

      digitalWrite(MOTOR, LOW);
      lcd.setCursor(1, 1);
      //         01234567890123456
      lcd.print("PUMP : ON       ");
      delay(100);
    } // 10
  }
  porcentaje(distancia1, "TANK LEVEL: ",2);
  porcentaje(distancia2, "SUMP LEVEL: ",3);

  delay(1200);
} // ENDOFPROGRAM
tankp = (1 - dist / 130) * 150;

Por más que tankp sea float el resultado de la operación es un entero.
Si dist es menor a 130 la división da como resultado 0.
Lo correcto seria

tankp = (1 - dist / 130.0) * 150.0;

No entiendo...

Esto

String buf;
...
buf = String(tankp, 0); 
...
lcd.print(buf); 

es mal usar la memoria (más con lo ineficiente que son los String al respecto).
Con

lcd.print(tankp, 0); 

obtienes el mismo resultado y es más eficiente.

Gracias, tomo en cuenta esos cambios. A lo que me referia de lo demás, es que como estoy viendo en la pantalla el porcentaje, de acuerdo a la distancia que toma el sensor ultrasonico, se sale del rango 0% a 100%, es decir: por ejemplo sale una lectura de -7% quiero que solo llegue a 0%, en caso contrario, si muestra una lectura de 108%, quiero que llegue solo a 100% aun cuando la lectura de la distancia, vaya mas alla, no se si me estoy explicando bien...

Ahora si entendí.

El % es tankp.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.