No hay manera...llevo todo el día y nada...While do

Nada gente, llevo todo el día metido con el maldito while....

A ver...ya tengo el código para que un dos tuppers llenos de agua midan, mediante cuatro cables, la altura máxima y la mínima (dos para cada altura). Cuando los cables del mínimo dejan de tocar agua, se activa el relé de la bomba de agua para que se rellene.

Hasta aquí todo bien...El problema viene al final del código, cuando le doy un while (mientras se activa la bomba de agua NO quiero que empiece de nuevo el código...quiero que se quede fijo ahí esperando hasta que se llene el tupper , detener el relé y lanzar un goto a la lectura del tupper 2.

A ver si me podéis echar una mano porfa!!!

//Relé en el pin 13
const int RELAY =13;

//Ahora establecemos dos pines para cada tupper.
const int pintupper1 = 1; //este se coloca arriba del recipiente de agua, altura máxima que deseo
const int pintupper2 = 2; //este se coloca abajo del recipiente de agua, altura mínima que deseo
const int pintupper3 = 3; //Primer cable del segundo tupper (altura máxima)
const int pintupper4 = 4; //Segundo cable del segundo tupper (altura mínima)


//Variables para almacenar el estado de los niveles
int estadoNivelAguaARRIBA = 0;
int estadoNivelAguaABAJO = 0;

void setup()
{
  
//Iniciamos los pines de los sensores como entrada:
pinMode(pintupper1, INPUT);
pinMode(pintupper2, INPUT);
pinMode(pintupper3, INPUT);
pinMode(pintupper4, INPUT);

//Iniciamos el pin 13 del relay como salida:
pinMode(RELAY, OUTPUT);


//Inicio serial en 9600
Serial.begin(9600);
}

void loop()
{

  Serial.println("INICIO VOID LOOP");  //Esto lo pongo solo para verificar que no empieza otra vez antes de comprobar el tupper 2
  delay(200);

// Leemos los pines del tupper 1
LEETUPPER1: 
estadoNivelAguaARRIBA = digitalRead(pintupper1);  
estadoNivelAguaABAJO = digitalRead(pintupper2);
delay(1000);

//Si toca agua en ambos sensores...
if (estadoNivelAguaARRIBA == HIGH && estadoNivelAguaABAJO == HIGH) {
Serial.println("DEPÓSITO 1 LLENO: Paso a leer depósito 2");
delay(1000);
goto DEPOSITO2;
}

//Si solo toca en el de abajo...(no activo ninguna bomba de momento hasta que no le falte agua al sensor de abajo)
if (estadoNivelAguaARRIBA == LOW && estadoNivelAguaABAJO == HIGH) {
Serial.println("DEPÓSITO 1 A MEDIAS. pasamos a lectura del 2");
delay(2000);
goto DEPOSITO2;
}

////////////// HASTA AQUI TODO BIEN...AHORA ES CUANDO LA LÍO///////////////////////


//SI los dos sensores no tocan agua...Activar relay (bomba).
if (estadoNivelAguaARRIBA == LOW && estadoNivelAguaABAJO == LOW) {
      Serial.println("DEPÓSITO 1 VACÍO: ACTIVAR BOMBA DE AGUA EN 5 SEGUNDOS...");
      delay (5000); //Esperamos 5 segundos para leer el mensaje
digitalWrite(RELAY, HIGH);

if(pintupper1 ==LOW && pintupper2 ==LOW)

{
  digitalWrite(RELAY, HIGH);
   
}


do
{
  delay(300); //esperar 300 milisegundos
  Serial.println(":::::ACTIVANDO BOMBA::::");
  delay(5000);
   
}
while (pintupper1 == HIGH && pintupper2 == HIGH); 
delay(300);
}

DEPOSITO2:
Serial.println("Si el tupper 1 está con nivel aceptable, empieza a leer tupper 2");


}

Bueno otro código lleno de delay y GOTO.

Realmente entender como funciona eso y pretender que lo haga correctamente es para que te frustres.

Mas alla que considero todo codigo lleno de delay realmente algo que no me gusta, mira esto

		do {
		  delay(300); //esperar 300 milisegundos
		  Serial.println(":::::ACTIVANDO BOMBA::::");
		  delay(5000);
		}
		while (pintupper1 == HIGH && pintupper2 == HIGH);

Dime como esperas que algo salga de ese while do?

Quien le dice a pintupper1 y pintupper2 que estan en HIGH si entraran en LOW o solo 1.
Pues nadie

Eso pasa por programar del modo que lo haces, usando delay() para empezar, y con un flujo que detiene el micro cada vez que encuentra un delay. Ejemplo, esa rutina sirve solo para mostrar ACTIVANDO BOMBA que ya lo hizo antes porque ahi no activas nada durante 5.3 segundos. Solo muestras ACTIVANDO BOMBA cada 5.3 segundos y nada mas.
Hasta ahi llega tu codigo.

Quieres hacerlo bien, pues sigue esta recomendación
Ve a Documentación => Indice de temas tutoriales => millis() y también lee máquina de estados.

Ademas de lo que te ha dicho @surbyte, veo algunos detalles mas:
1.- El uso de GOTO puede ocasionar mas problemas que beneficios. La misma documentación oficial desaconseja su uso. Te dejo aqui el enlace
2.- Veo esto:

const int pintupper1 = 1; //este se coloca arriba del recipiente de agua, altura máxima que deseo

luego esto:

//Inicio serial en 9600
Serial.begin(9600);

Si vas a utilizar la comunicación Serial debes dejar libres los pines 0 y 1

3.-Dices tener 2 depositos "tupper" pero solo tienes:

estadoNivelAguaARRIBA = digitalRead(pintupper1);  
estadoNivelAguaABAJO = digitalRead(pintupper2);

No tienes nada para verificar el nivel del segundo tupper
y las ultimas 2 cosas:
¿como tienes conectados los cables que usas para medir el nivel? y ¿les conectaste resistencia pull-down?
¿como llenas el segundo tupper? porque solo veo un relay conectado al pin 13, por lo que supongo que solo tienes una bomba

surbyte:
Bueno otro código lleno de delay y GOTO.

Realmente entender como funciona eso y pretender que lo haga correctamente es para que te frustres.

Mas alla que considero todo codigo lleno de delay realmente algo que no me gusta

El tema de los delays, los pongo para que me dé tiempo de seguir el programa desde el monitor. La intención es quitarlos una vez funcione todo.

Ok quito los goto y los delay.

surbyte:
Quieres hacerlo bien, pues sigue esta recomendación
Ve a Documentación => Indice de temas tutoriales => millis() y también lee máquina de estados.

Muchas gracias @surbyte , así lo haré a ver si saco algo en claro.

RIG:
Ademas de lo que te ha dicho @surbyte, veo algunos detalles mas:
2.- Veo esto:

const int pintupper1 = 1; //este se coloca arriba del recipiente de agua, altura máxima que deseo

luego esto:

//Inicio serial en 9600

Serial.begin(9600);



Si vas a utilizar la comunicación Serial debes dejar libres los pines 0 y 1

Ostras no lo sabía!!! Muchas gracias!

RIG:
3.-Dices tener 2 depositos “tupper” pero solo tienes:

estadoNivelAguaARRIBA = digitalRead(pintupper1);  

estadoNivelAguaABAJO = digitalRead(pintupper2);



No tienes nada para verificar el nivel del segundo tupper

Pongo pintupper 3 y 4 para el segundo verdad? Gracias.

RIG:
y las ultimas 2 cosas:
¿como tienes conectados los cables que usas para medir el nivel? y ¿les conectaste resistencia pull-down?
¿como llenas el segundo tupper? porque solo veo un relay conectado al pin 13, por lo que supongo que solo tienes una bomba

Así es, tengo la resistencia pull down.

Así tengo las conexiones:

/* Conexiones: 
Ground a 10kohm.
La otra punta de la resistencia conectada a pin1 y también al cable que va directo al agua. 
5v al agua

Las conexiones funcionan bien, por eso no hay problema. El problema es que no tengo mucha idea de hacer funcionar el while a pesar de haber pasado horas y horas leyendo los tutoriales de esta función.

Quisiera que se accione la bomba y siga midiendo el sensor y NO CONTINÚE leyendo código hasta que cumpla (estadoNivelAguaARRIBA == HIGH && estadoNivelAguaABAJO == HIGH). El resto ya iré investigando. 

Gracias!

Gracias a vosotros he simplificado código sin delays ni gotos ni activaciones de Relays. Sólo lectura.

4 cables leen dos tuppers diferentes y te dicen si no hay nada de agua, si está a medias o bien si están llenos. Es el comienzo.

El código va perfecto de momento, aunque me cuesta leer en Monitor ya que va súper rápido sin delays…XD

/* Conexiones: 
Ground conectado a una patilla de la resist 10kohm.
La otra punta de la resistencia conectada a pin3 y también al cable que va al agua. 
El otro cable que va al agua directo a 5v
Repetir lo mismo con el otro cable. Pero al pin4.

***El sensor del PIN4 va ABAJO del tupper. El sensor del PIN3 se coloca arriba, para que cuando llegue el agua, se pare la bomba***

*/



//Pin que nos dan los niveles
const int pinNivel3 = 3;
const int pinNivel4 = 4;
const int pinNivel5 = 5;
const int pinNivel6 = 6;
const int RELAY =13;

//Variables para almacenar el estado de los niveles
int estadoNivelAgua3 = 0;
int estadoNivelAgua4 = 0;
int estadoNivelAgua5 = 0;
int estadoNivelAgua6 = 0;

void setup()
{
//Iniciamos los pines en los que tenemos los niveles
pinMode(pinNivel3, INPUT);
pinMode(pinNivel4, INPUT);
pinMode(pinNivel5, INPUT);
pinMode(pinNivel6, INPUT);
pinMode(RELAY, OUTPUT);


Serial.begin(9600);
}
void loop()
{

estadoNivelAgua3 = digitalRead(pinNivel3);
estadoNivelAgua4 = digitalRead(pinNivel4);
estadoNivelAgua5 = digitalRead(pinNivel5);
estadoNivelAgua6 = digitalRead(pinNivel6);

if (estadoNivelAgua3 == HIGH && estadoNivelAgua4 == HIGH) {
Serial.println("DEPÓSITO 1 LLENO: TOCA AGUA EN AMBOS");
}
if (estadoNivelAgua5 == HIGH && estadoNivelAgua6 == HIGH) {
Serial.println("DEPÓSITO 2 LLENO: TOCA AGUA EN AMBOS");
}
if (estadoNivelAgua3 == LOW && estadoNivelAgua4 == HIGH) {
Serial.println("DEPÓSITO 1 A MEDIAS. AGUA EN SENSOR DE ABAJO");
}
if (estadoNivelAgua5 == LOW && estadoNivelAgua6 == HIGH) {
Serial.println("DEPÓSITO 2 A MEDIAS. AGUA EN SENSOR DE ABAJO");
}
if (estadoNivelAgua3 == LOW && estadoNivelAgua4 == LOW) {
Serial.println("DEPÓSITO 1 VACÍO: ACTIVAR BOMBA DE AGUA YA MISMO");
delay(5000);
}
if (estadoNivelAgua5 == LOW && estadoNivelAgua6 == LOW) {
Serial.println("DEPÓSITO 2 VACÍO: ACTIVAR BOMBA DE AGUA YA MISMO");
delay(5000);
}


}

Ahora intentaré meter un while (mientras los dos estados se encuentren en low, osea vacíos, que se active el relay del pin 13).

El ejemplo del código para el while:

do {
  i = i + 1;
  result = result + i;
} while (i < 5);

Podría hacerlo así?

do {digitalWrite(RELAY, HIGH);
 } while (estadoNivelAgua3 == LOW && estadoNivelAgua4 == LOW);

Alguna ayudita?

Gracias !!!

Dime porque tu inquietud de usar un while()?

Ahora intentaré meter un while (mientras los dos estados se encuentren en low, osea vacíos, que se active el relay del pin 13).

para hacer eso yo no lo veo necesario.
Ademas no me contestaste la pregunta de como llenas de agua el segundo tupper ¿es con la misma bomba? si es con la misma bomba ¿entonces quieres que la bomba trabaje solo cuando los 2 depósitos estén vacíos o como?

Tío!!! Muchas gracias!!! @RIG

Me has hecho pensar…soy retrasado… mejor que while le meto un IF para que SOLO active la bomba cuando deje de tocar el sensor de abajo (cuando baja del mínimo de agua) y otro IF para que desactive la bomba cuando toque arriba y abajo. Cuando solo toque abajo no haga nada.

if (estadoNivelAgua3 == HIGH && estadoNivelAgua4 == HIGH) {
Serial.println("DEPÓSITO 1 LLENO: Apagar bomba de agua");
digitalWrite(RELAY, LOW);

}
if (estadoNivelAgua5 == HIGH && estadoNivelAgua6 == HIGH) {
Serial.println("DEPÓSITO 2 LLENO: Apagar bomba de agua");
digitalWrite(RELAY, LOW);
}
if (estadoNivelAgua3 == LOW && estadoNivelAgua4 == HIGH) {
Serial.println("DEPÓSITO 1 A MEDIAS. No hacer nada");
}
if (estadoNivelAgua5 == LOW && estadoNivelAgua6 == HIGH) {
Serial.println("DEPÓSITO 2 A MEDIAS. No hacer nada");
}
if (estadoNivelAgua3 == LOW && estadoNivelAgua4 == LOW) {
Serial.println("DEPÓSITO 1 VACÍO: ACTIVAR BOMBA DE AGUA YA MISMO");
//Primero mover el motor a pasos hacia la posición del depósito 1. Esperar unos segundos y activar la bomba.
digitalWrite(RELAY, LOW);
delay(5000);
}
if (estadoNivelAgua5 == LOW && estadoNivelAgua6 == LOW) {
Serial.println("DEPÓSITO 2 VACÍO: ACTIVAR BOMBA DE AGUA YA MISMO");
delay(5000);
//Primero mover el motor a pasos hacia la posición del depósito 2. Esperar unos segundos y activar la bomba.
digitalWrite(RELAY, HIGH);
}

ASÍ MUCHO MEJOR!!!

A ver te respondo…la bomba en realidad es una electroválvula. Debajo de la electroválvula quiero poner un vasito que decante el agua por un tubo, que a su vez decantará en una tubería u otra, hacia la izquierda y/o derecha. Y cómo pienso mover ese vasito a izquierda y derecha?

Debajo del vasito irá un motor a pasos que indicará los grados exactos para que decante el agua hacia una tubería u otra.

La idea es hacer un reloj de 12 horas y poder poner 12 tuppers. Una idea sencilla para evitar comprar 12 electroválvulas.

Qué te parece? Habría alguna solución más sencilla? XD

Gracias de veras, sin tu comentario no se me había ocurrido lo más simple! XD