Automatización de un huerto. Problema con el tiempo

Buenos días, soy Pau. He buscado y buscado y no soluciono mi problema. Lo que intento hacer es la automatización de un huerto para regar si la tierra está seca. Para ello dispongo de:

  • un depósito con tres boyas y tres LED que me indican el nivel en el cuadro eléctrico
  • un pozo con una bomba
  • una electroválvula
  • sensor de humedad FC-28
  • placa arduino uno r3
  • transformadores externos para activar la bomba y la electroválvula
  • módulo de 8 relés
  • típico programador de ciclos a 230V para, por ejemplo, encender/apagar un radiador eléctrico en casa. Esté me da corriente al cuadro eléctrico donde está la placa y los trafos

Programo el “reloj” para que se encienda dos veces al día y me alimente la placa. El código (que es muy largo y, estoy casi seguro que se puede optimizar) hace el siguiente proceso:

  • Comprueba el valor que lee del FC-28.
  • Si está húmedo, con un delay espero el tiempo suficiente para no volver a activar el ciclo
  • Si está seco, compruebo el nivel del depósito usando las tres boyas y enciendo la bomba si es necesario.
  • Cuando el depósito está lleno, abro la electroválvula el tiempo programado.
  • Cuando el programador de ciclos deja de alimentar la caja eléctrica, todo queda parado: placa, bomba y electroválvula cerrada.

Todo el sistema funciona a la perfección excepto porqué quiero doble control del encendido de la bomba. Ahora mismo, cuando enciendo la bomba, lo hago hasta que la boya de nivel máximo está activa. En este momento paro la bomba y abro la electroválvula. También me funciona utilizar un delay() y después parar la bomba pero no me gusta. Lo que quiero conseguir es lo siguiente:

Encender la bomba mientras la boya de nivel máximo no esté activa O durante X minutos

El código simplificado (compruebo todas las combinaciones posibles de las 3 boyas) es el siguiente:

const int hu_min = 550; //Valor mínim de lectura del sensor per considerar moll
#define sensor_humitat_01 A0 //Inicialitzar el pin analògic -> Sensor d'humitat

#define boia_03 11 //Inicialitzar el pin digital -> Boia de dalt
#define LED_03 10 //Inicialitzar el pin digital -> Led nivell dalt ok

#define Bomba 3 //Inicialitzar el pin digital -> Relé bomba
#define Electroval_01 2 //Inicialitzar pin digital -> Relé electrovàlvola

unsigned long temps;
long temps_electroval = 1; //Temps (hora) d'obertura de l'electrovàlvola
long temps_espera = 1; //Temps (hora) que sobrepassi el temps programat per regar per no sortir del bucle
long temps_bomba = 1; //Temps (min) d'emplenar el dipòsit

#define SEC_PER_MIN (60UL)
#define SEC_PER_HOR (3600UL)

int moll = 0; //Constant per saber si ja s'ha comprovat la humitat
int ple = 0; //Constant per saber si ja ha funcionat la bomba
int regat = 0; //Constant per saber si ja s'ha regat
int funcionant = 0;
int cas01 = 0;

void setup() {
  pinMode(sensor_humitat_01, INPUT);

  pinMode(boia_03, INPUT);
  pinMode(LED_03, OUTPUT);

  pinMode(Bomba, OUTPUT);
  pinMode(Electroval_01, OUTPUT);

  digitalWrite(Bomba, HIGH);
  digitalWrite(Electroval_01, HIGH);

  Serial.begin(9600);
}

void loop() {
  temps = (millis() / 1000);
  delay(1000);
  Serial.print(temps);

  //Comprovar humitat del terra
  int humitat_01 = analogRead(sensor_humitat_01);
  Serial.print(humitat_01);

  //Comprovar nivell dipòsit
  int nivell_boia03 = digitalRead(boia_03);
  Serial.print(boia_03);
  


  if (moll == 0 && (regat == 0))
  {
    if (humitat_01 < hu_min)
    {
      Serial.println("Moll");

      digitalWrite(Electroval_01, HIGH);
      digitalWrite(Bomba, HIGH);
      delay(temps_espera * SEC_PER_HOR);
    }
    else
    {
      Serial.println("Sec");

      if (funcionant == 0)
      {
        if (nivell_boia03 == LOW)
        {
          Serial.println("Dipòsit buit");

          REGAR();
          int cas01 = 1;
        }
        else
        {
          Serial.println("Dipòsit ple");
          digitalWrite(LED_01, HIGH);
          digitalWrite(LED_02, HIGH);
          digitalWrite(LED_03, HIGH);

          int ple = 1;
          REGAR();
        }
      }
    }
    int funcionant = 1;
  }
}

void REGAR()
{
if (ple == 0)
  {
    do
    {
      delay(50);
      digitalWrite(Bomba, LOW);
    } while (digitalRead(boia_03) == LOW || (temps < temps_bomba * SEC_PER_MIN));
  }

  digitalWrite(Bomba, HIGH);

  int ple = 1;

  if (cas01 == 1)
  {
    CAS01();
  }
  
  delay(1000);
  
if (regat == 0)
  {
    do
    {
      digitalWrite(Electroval_01, LOW); //Obrir electrovàlvola
    } while (digitalRead(boia_01) == HIGH || (temps < temps_electroval * SEC_PER_HOR));
  }

  digitalWrite(Electroval_01, HIGH);
  int regat = 1;
}

void CAS01()
{
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}

Entiendo que el problema lo tengo en el siguiente trozo:

do
    {
      delay(50);
      digitalWrite(Bomba, LOW);
    } while (digitalRead(boia_03) == LOW || (temps < temps_bomba * SEC_PER_MIN));

La parada por boya me funciona bien. Lo que intento es tener una seguridad extra controlando el tiempo para no tener la bomba funcionando todo el tiempo que el programador alimente el cuadro eléctrico.

Muchas gracias por la ayuda

Hort_v4.ino (5.76 KB)

Hay al menos 2 o 3 hilos en este foro por citar los últimos.

Busca : Cultivo autonomo
Invernadero Hidroponico Automatizado con Arduino
Maceta con autorriego, alta autonomía y bajo coste. Y encima bonita

Este último esta dos hilos abajo.
Estos son 3 de los que encontré rápidamente.

Buenas noches,

Muchas gracias por la respuesta. He estado unos días leyendo los posts en español y en inglés y no he encontrado lo que yo busco.

El ejemplo del invernadero no me sirve porqué utilizan la función delay() para activar y desactivar la bomba/relés/servos/etc. Tu comentas usar millis() pero la cosa se queda aquí.

El ejemplo de la maceta no encuentro ningún código para darle una ojeada y comparar con el mío.

El que me parece más interesante es el cultivo autonomo pero tampoco le veo el uso al millis(). Por un lado la gestión de la bomba (encendido/apagado) lo realiza mediante el sensor del suelo:

  if (SoilSensor < 85) // Si el sensor detecta menos de 80%H
    {
      digitalWrite(RELAY_1, RELAY_ON);  // Activamos rele y bomba
    }
  if (SoilSensor > (85 + hysterisis))// Si detecta mas de 90%H
    {
      digitalWrite(RELAY_1, RELAY_OFF); // Apaga el rele y la bomba
    }

Por otro lado he visto un millis() utilizado que me parece interesante pero creo que a mi no me funcionaría.

  if (millis() - moistureTest > 3000UL) // Sondeamos la humedad de la tierra cada 5 segundos
    {
      moistureSampling();
      moistureTest = millis();
    }

Utilizar el millis con un if en mi caso no me parece correcto porqué lo que yo quiero es que pare la bomba cuando la boia esté activa (depósito lleno) o hayan pasado X minutos des de la activación de la bomba.
No se si en mi caso sería viable utilizar directamente el while en lugar del do/while… pero creo que estaría más o menos en la misma situación.

Creo que tengo el error en la parte de definir y utilizar el millis() para leer el tiempo.

Muchas gracias por vuestro tiempo

Te voy a dar un consejo.

Hay una librería que esta en el foro Internacional Francés de este, y yo la uso, de los millis es lo mas bueno. El usuario se llama bricoleau y en este enlace prueba a ver si esto es lo que buscas.

Muchas gracias,

voy a echarle un vistazo.

Por otra parte se me ha ocurrido utilizar dos while:

while (tiempo < tiempodeseado)
{
  while (boya == LOW)
  {
     Encender bomba
  }
}

Pero me da miedo que, igualmente, si la boya deja de funcionar, no salga nunca del bucle. O que si el tiempo no funciona (como me pasa ahora) tampoco salga nunca del bucle.

Muchas gracias por la respuesta, en cuanto pueda mirarme el enlace y probarlo os contaré.

En el punto de depuración en el que estás, debes dar un par de pasos atrás. Has incorporado las mejoras conforme has avanzado en la instalación de piezas, veo que le has dejado todo el control a tu arduino. Algo le falta a tu pregunta.

El punto débil en el sistema creo que ya te lo has planteado: que tal si falla una boya, por ende también debes considerar: que tal si falla algún sensor...

Necesitas un monitor para ver el estado de las variables: una EEPROM (puede ser la del RTC que estas usando), una memoria SD, un lcd, una matriz de leds; no necesitas algo complicado, solo algo que funcione en tu arduino UNO.

Como siempre lo he dicho: el experto eres tú, ya que tienes las piezas a la mano, acá solo podemos intentar ayudarte a depurar una función o una parte del código. Esto me lleva a mi pregunta: ¿cómo sabes los valores de los sensores?

TFTLCDCyg:
Necesitas un monitor para ver el estado de las variables: una EEPROM (puede ser la del RTC que estas usando), una memoria SD, un lcd, una matriz de leds; no necesitas algo complicado, solo algo que funcione en tu arduino UNO.

Como siempre lo he dicho: el experto eres tú, ya que tienes las piezas a la mano, acá solo podemos intentar ayudarte a depurar una función o una parte del código. Esto me lleva a mi pregunta: ¿cómo sabes los valores de los sensores?

Buenos días,

realmente no me había preocupado demasiado por el si falla el sensor de humedad ya que iré varias veces a la semana a comprobar el estado del sistema. Por el mismo motivo, la boya me preocupa más por dejarla funcionando descontroladamente que no por no regar por falta de agua en el depósito.

De todas formas, no me había planteado la posibilidad de registrar los fallos porqué quiero programar las horas de funcionamiento cuando yo no estoy allí. Por este motivo había descartado la pantalla LCD (que ya la tengo) y los LED ya que cuando voy a comprobar, el sistema no tiene porqué estar funcionando. Dicho esto, el módulo SD me parece una idea fenomenal y será la primera evolución del sistema una vez funcione correctamente. Lo de la EEPROM tendré que leer qué es, para que sirve y como se utiliza porqué ahora mismo no sé que es :-P. Muchas gracias por las ideas.

Respondiendo a la otra pregunta: no se qué valores está dando el sensor de humedad... Las boyas son digitales por lo que no me preocupan (a menos que sea posible, mediante lectura del valor, saber si están fallando... ¡Interesante! Ya investigaré). Para programar el valor umbral del sensor de humedad, lo tenía en el suelo e iba probando valores con el portátil hasta que me habría la electroválvula; sabía que el sensor lee 0 sumergido, 1023 en aire y valores cercanos a les 700-800 cuando el suelo está poco mojado... Prueba y error!

Encender la bomba mientras la boya de nivel máximo no esté activa O durante X minutos

El programa tiene multimples errores, asi que hasta tanto te de mi versión te pregunto esto?

  1. moll nunca es modificado, porqué?
    Debería cambiar de valor cuando la humedad del suelo esta por debajo de 550.

  2. regado es inicializado como global al comienzo y luego vuelves a hacerlo en la ultima línea pero como local

int regado = 1;

y ese mismo error se repite varias veces.
Al final no se sabe que comportamiento tiene el programa.

Buenas noches!

Gracias por la respuesta! La verdad es que llevo desde la semana pasada, cada noche haciendo modificaciones al programa y probandolo por la mañana (tema de horarios de trabajo hehe) sin conseguir que funcione como a mi me gustaría.

surbyte:

  1. moll nunca es modificado, porqué?
    Debería cambiar de valor cuando la humedad del suelo esta por debajo de 550.

Pues he hecho tantas modificaciones al programa y lo he reescrito tantas veces sin conseguir que funcione correctamente, que en algun cambio me olvidé algunas variables… Ya está solucionado. Esto puede ir relacionado con el siguiente punto que comentas.

surbyte:
2. regado es inicializado como global al comienzo y luego vuelves a hacerlo en la ultima línea pero como local

int regado = 1;

y ese mismo error se repite varias veces.
Al final no se sabe que comportamiento tiene el programa.

Tienes toda la razón. Alguna vez me dió error de compilación (quizás tenía mal algun nombre) y así se me solucionó ese problema y pensaba que se tenía que definirla cada vez (contra toda lógica que yo pensaba). Eso explica porqué tengo algunos de los problemas que tengo en el comportamiento del programa. Gracias

La verdad, que con estas nuevas correcciones que me son super útiles, voy a volver a probar la versión 6 del programa que reescribí. (Hoy he descartado la 7… :’( )

Mirad si soy novato que hasta el domingo por la tarde no descubrí que tenía la consola “Monitor serie”. Antes trabajaba a ciegas sin saber NADA del porqué no funcionaba… En cambio ahora puedo ver donde me quedo clavado del programa…

Estos días he estado trabajando con la librería “simpleMinuteur” que me comentó lightcalamar sin acabar de conseguir los resultados tan deseados. He centrado mis esfuerzos en reescribir todo el programa para poder utilizar la librería como he entendido que funciona y haciendo el control de tiempo para parar la bomba en caso necesario.

Cuelgo la versión que voy a probar mañana! Gracias por la ayuda!

Hort_v6.1.ino (7.29 KB)

Este es tu código. Mas fácil verlo asi que tener que descargarlo.
Ahora es una pena que este en catalán. No voy a volver a traducirlo asi que paso…

#include <simpleMinuteur.h>

const int hu_min = 300; //Valor minim de lectura del sensor per considerar moll
#define sensor_humitat_01 A0 //Inicialitzar el pin analogic -> Sensor d'humitat

#define boia_01 A5 //Inicialitzar el pin analogic (digital) -> Boia de baix
#define LED_01 A4 //Inicialitzar el pin analogic (digital) -> Led nivell baix ok
#define boia_02 13 //Inicialitzar el pin digital -> Boia del mig
#define LED_02 12 //Inicialitzar el pin digital -> Led nivell mig ok

#define boia_03 11 //Inicialitzar el pin digital -> Boia de dalt
#define LED_03 10 //Inicialitzar el pin digital -> Led nivell dalt ok

#define Bomba 3 //Inicialitzar el pin digital -> Rele bomba
#define Electroval_01 2 //Inicialitzar pin digital -> Rele electrovalvola

unsigned long temps_espera = 1.5; //Temps (hora) que sobrepassi el temps programat per regar per no sortir del bucle
unsigned long temps_bomba = 0.5; //Temps (min) d'emplenar el diposit
unsigned long temps_electrovalvula = 1; //Temps (hora) que es deixa l'electrovalvula oberta

#define MSEC_PER_MIN (60000UL)
#define MSEC_PER_HOR (3600000UL)

simpleMinuteur temp_BOMBA(temps_bomba * MSEC_PER_MIN); //Definir el comptador de temps de la bomba
simpleMinuteur temp_ELECTROVALVULA(temps_electrovalvula * MSEC_PER_HOR); //Definir el comptador de temps de l'electrovalvula
simpleMinuteur temp_ESPERA(temps_espera * MSEC_PER_HOR); //Definir el comptador de temps d'espera

int moll = 0; //Constant per saber si ja s'ha comprovat la humitat
int ple = 0; //Constant per saber si ja ha funcionat la bomba
int funcionant = 0; //Constant per saber si esta emplenant el diposit o regant
int boies = 0; //Constant per saber si les boies han estat comprovades
int cas01 = 0;
int cas02 = 0;
int cas03 = 0;
int cas04 = 0;
int cas05 = 0;

void setup() {
  pinMode(sensor_humitat_01, INPUT);

  pinMode(boia_01, INPUT);
  pinMode(LED_01, OUTPUT);
  pinMode(boia_02, INPUT);
  pinMode(LED_02, OUTPUT);
  pinMode(boia_03, INPUT);
  pinMode(LED_03, OUTPUT);

  pinMode(Bomba, OUTPUT);
  pinMode(Electroval_01, OUTPUT);

  digitalWrite(Bomba, HIGH);
  digitalWrite(Electroval_01, HIGH);

  Serial.begin(9600);

  temp_BOMBA.demarrer();
  temp_ELECTROVALVULA.demarrer();
  temp_ESPERA.demarrer();
}

void loop() {
  //Comprovar humitat del terra
  int humitat_01 = analogRead(sensor_humitat_01);
  Serial.print("Humitat: ");
  Serial.println(humitat_01);

  //Comprovar nivell diposit
  int nivell_boia01 = digitalRead(boia_01);
  int nivell_boia02 = digitalRead(boia_02);
  int nivell_boia03 = digitalRead(boia_03);
  Serial.print("Nivell boia 1: ");
  Serial.println(nivell_boia01);
  Serial.print("Nivell boia 2: ");
  Serial.println(nivell_boia02);
  Serial.print("Nivell boia 3: ");
  Serial.println(nivell_boia03);

  Serial.print("Funcionant: ");
  Serial.println(funcionant);
  Serial.print("Boies: ");
  Serial.println(boies);
  Serial.print("Moll: ");
  Serial.println(moll);
  Serial.print("Ple: ");
  Serial.println(ple);

  while (funcionant == 0 && moll == 0 && boies == 0)
  {
    if (humitat_01 < hu_min)
    {
      Serial.println("Moll");

      if (temp_ESPERA.estTermine())
      {
        Serial.println("Cal reiniciar temporitzador espera");
        temp_ESPERA.redemarrer();
      }
      else
      {
        Serial.println("Comprovar bomba i electrovalvula. Ja és moll");
        digitalWrite(Electroval_01, HIGH);
        digitalWrite(Bomba, HIGH);
        moll = 1;
      }
    }
    else
    {
      Serial.println("Sec. Cal regar");
      COMPR_BOIES();
    }
  }

  if (temp_BOMBA.estTermine())
  {
    Serial.println("La bomba para per temps!");
    
    digitalWrite(Bomba, HIGH);
    ple = 1;
    ENGEGAR_LED();
  }

  if (temp_ELECTROVALVULA.estTermine())
  {
    Serial.println("Ja hem regat durant tota l'estona");
    
    digitalWrite(Electroval_01, HIGH);
    digitalWrite(Bomba, HIGH);
    moll = 1;
  }

  Serial.println("");
  Serial.println("");
  delay(2000);
}

void COMPR_BOIES()
{
  while (funcionant == 0 && ple == 0)
  {
    if (digitalRead(boia_03) == LOW)
    {
      if (digitalRead(boia_02) == LOW)
      {
        if (digitalRead(boia_01) == LOW)
        {
          Serial.println("Diposit buit (Cas 01)");

          cas01 = 1;
          BOMBA_ON();
        } //1
        else
        {
          Serial.println("Diposit quasi buit (Cas 02)");
          digitalWrite(LED_01, HIGH);

          cas02 = 1;
          BOMBA_ON();
        }
      }
      else
      {
        if (digitalRead(boia_01) == LOW)
        {
          Serial.println("Diposit buit. ERROR boia 2! (Cas 03)");

          cas03 = 1;
          BOMBA_ON();
        } //3
        else
        {
          Serial.println("Diposit mig ple. (Cas 04)");
          digitalWrite(LED_01, HIGH);
          digitalWrite(LED_02, HIGH);

          cas04 = 1;
          BOMBA_ON();
        } //4
      }
    }
    else
    {
      if (digitalRead(boia_02) == LOW)
      {
        if (digitalRead(boia_01) == LOW)
        {
          Serial.println("Diposit buit. ERROR boia 3! (Cas 05)");

          cas05 = 1;
          BOMBA_ON();
        } //5
        else
        {
          Serial.println("Diposit ple. ERROR boia 2! (Cas 06)");

          digitalWrite(LED_01, HIGH);
          digitalWrite(LED_03, HIGH);

          ple = 1;
          REGAR();
        } //6
      }
      else
      {
        if (digitalRead(boia_01) == LOW)
        {
          Serial.println("Diposit ple. ERROR boia 1! (Cas 07)");

          digitalWrite(LED_02, HIGH);
          digitalWrite(LED_03, HIGH);

          digitalWrite(boia_01, HIGH); //L'he d'imposar activa perquè sinó no rega

          ple = 1;
          REGAR();
        } //7
        else
        {
          Serial.println("Diposit ple (Cas 08)");

          digitalWrite(LED_01, HIGH);
          digitalWrite(LED_02, HIGH);
          digitalWrite(LED_03, HIGH);

          ple = 1;
          REGAR();
        } //8
      }
    }
  }

  boies = 1;
}

void BOMBA_ON()
{
  Serial.println("Engegar bomba. on");

  if (moll == 0 && boies == 1 && ple == 0)
  {
    do
    {
      funcionant = 1;
      digitalWrite(Bomba, LOW);
    } while (digitalRead(boia_03) == LOW);
  }
  digitalWrite(Bomba, HIGH);
  ple = 1;

  ENGEGAR_LED();
}

void ENGEGAR_LED()
{
  Serial.println("Engegar LEDs");
  funcionant = 0;

  if (cas01 == 1)
  {
    CAS01();
  }
  else
  {
    if (cas02 == 1)
    {
      CAS02();
    }
    else
    {
      if (cas03 == 1)
      {
        CAS03();
      }
      else
      {
        if (cas04 == 1)
        {
          CAS04();
        }
        else
        {
          if (cas05 == 1)
          {
            CAS05();
          }
        }
      }
    }
  }
}

void REGAR()
{
  Serial.println("Regant");

  while (ple == 1 && funcionant == 0 && moll == 0)
  {
    do
    {
      digitalWrite(Electroval_01, LOW); //Obrir electrovalvola
    } while (digitalRead(boia_01) == HIGH);
  }

  digitalWrite(Electroval_01, HIGH);
}

void CAS01()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS02()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS03()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS04()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS05()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
}

Buenas,

lo subía porqué es muy largo… Ya lo copiaré en pantalla :wink:

He vuelto a una modificación anterior a la versión subida porqué me gusta más el proceso de comprobar/Activar/Desactivar sensores.

Código en el siguiente post porqué no me cabe todo

El código entero me funciona porqué he probado a puentear la boya cuando el relé está activado y sale del bucle y sigue con todo el código. El problema viene que espero los 30 segundos programados (y hasta un minuto) y el relé no se para…

He probado sustituyendo la librería “simpleMinuteur” por un simple millis() y tampoco lo consigo hacer funcionar (modificando las variables necesarias):

temps = millis();
while (funcionant == 0 && moll == 0 && boies == 0)
  {
    if (humitat_01 < hu_min)
    {
      Serial.println("La terra està humida");

      if (temps >= temp_ESPERA)
      {
        Serial.println("S'ha acabat el temps d'espera");
      }
      else
      {
        Serial.println("Esperant que s'acabi el temps d'espera");
        digitalWrite(Electroval_01, HIGH);
        digitalWrite(Bomba, HIGH);
      }

      moll = 1;
    }
    else
    {
      Serial.println("Sec. Cal regar");
      COMPR_BOIES();
    }
  }

Y tampoco me funciona…

Necesitaría otra ayudita, por favor! He traducido la mayoría del código a la espera de una alma caritativa que le de un vistazo más.

Muchas gracias por vuestros conocimientos y ayuda.

#include <simpleMinuteur.h>

const int hu_min = 300; //Valor minimo de lectura del sensor para considerar mojado -- Valor minim de lectura del sensor per considerar moll
#define sensor_humitat_01 A0 //Inicializar el pin analogico -> Sensor de humedad -- Inicialitzar el pin analogic -> Sensor d'humitat

#define boia_01 A5 //Inicialitzar el pin analogic (digital) -> Boya inferior -- Boia de baix
#define LED_01 A4 //Inicialitzar el pin analogic (digital) -> LED de nivel bajo ok -- Led nivell baix ok
#define boia_02 13 //Inicialitzar el pin digital -> Boya del medio -- Boia del mig
#define LED_02 12 //Inicialitzar el pin digital -> LED de nivel medio ok -- Led nivell mig ok

#define boia_03 11 //Inicialitzar el pin digital -> Boya de arriba -- Boia de dalt
#define LED_03 10 //Inicialitzar el pin digital -> LED de nivel alto ok -- Led nivell dalt ok

#define Bomba 3 //Inicialitzar el pin digital -> Rele bomba -- Rele bomba
#define Electroval_01 2 //Inicialitzar pin digital -> Rele electrovalvula -- Rele electrovalvola

unsigned long temps;
unsigned long temps_espera = 1.5; //Tiempo (hora) que sobrepase el tiempo programado para regar para no salir del bucle -- Temps (hora) que sobrepassi el temps programat per regar per no sortir del bucle
unsigned long temps_bomba = 0.5; //Tiempo (min) de llenado del deposito -- Temps (min) d'emplenar el diposit
unsigned long temps_electrovalvula = 1; //Tiempo (hora) que se deja la electrovalvula abierta -- Temps (hora) que es deixa l'electrovalvula oberta

#define MSEC_PER_MIN (60000UL)
#define MSEC_PER_HOR (3600000UL)

simpleMinuteur temp_BOMBA(temps_bomba * MSEC_PER_MIN); //Definir el contador de tiempo de la bomba -- Definir el comptador de temps de la bomba
simpleMinuteur temp_ELECTROVALVULA(temps_electrovalvula * MSEC_PER_HOR); //Definir el contador de tiempo de la electrovalvula -- Definir el comptador de temps de l'electrovalvula
simpleMinuteur temp_ESPERA(temps_espera * MSEC_PER_HOR); //Definir el contador de tiempo de espera -- Definir el comptador de temps d'espera

int moll = 0; //Constante para saber si se ha comprobado la humedad -- Constant per saber si ja s'ha comprovat la humitat
int ple = 0; //Constante para saber si ha funcionado la bomba -- Constant per saber si ja ha funcionat la bomba
int funcionant = 0; //Constante para saber si se ha llenado el deposito -- Constant per saber si esta emplenant el diposit
int boies = 0; //Constante para saber si las boyas han sido comprobadas -- Constant per saber si les boies han estat comprovades
int cas01 = 0;
int cas02 = 0;
int cas03 = 0;
int cas04 = 0;
int cas05 = 0;

void setup() {
  pinMode(sensor_humitat_01, INPUT);

  pinMode(boia_01, INPUT);
  pinMode(LED_01, OUTPUT);
  pinMode(boia_02, INPUT);
  pinMode(LED_02, OUTPUT);
  pinMode(boia_03, INPUT);
  pinMode(LED_03, OUTPUT);

  pinMode(Bomba, OUTPUT);
  pinMode(Electroval_01, OUTPUT);

  digitalWrite(Bomba, HIGH);
  digitalWrite(Electroval_01, HIGH);

  Serial.begin(9600);

  temp_BOMBA.demarrer();
  temp_ELECTROVALVULA.demarrer();
  temp_ESPERA.demarrer();
}

void loop() {
  //Comprobar humedad del suelo -- Comprovar humitat del terra
  int humitat_01 = analogRead(sensor_humitat_01);
  Serial.print("Humitat: ");
  Serial.println(humitat_01);

  //Comprobar nivel deposito -- Comprovar nivell diposit
  int nivell_boia01 = digitalRead(boia_01);
  int nivell_boia02 = digitalRead(boia_02);
  int nivell_boia03 = digitalRead(boia_03);
  Serial.print("Nivell boia 1: ");
  Serial.println(nivell_boia01);
  Serial.print("Nivell boia 2: ");
  Serial.println(nivell_boia02);
  Serial.print("Nivell boia 3: ");
  Serial.println(nivell_boia03);

  Serial.print("Funcionant: ");
  Serial.println(funcionant);
  Serial.print("Boies: ");
  Serial.println(boies);
  Serial.print("Moll: ");
  Serial.println(moll);
  Serial.print("Ple: ");
  Serial.println(ple);

  while (funcionant == 0 && moll == 0 && boies == 0)
  {
    if (humitat_01 < hu_min)
    {
      Serial.println("La terra està  humida");

      if (temp_ESPERA.estTermine())
      {
        Serial.println("S'ha acabat el temps d'espera");
        temp_ESPERA.redemarrer();
      }
      else
      {
        Serial.println("Esperant que s'acabi el temps d'espera");
        digitalWrite(Electroval_01, HIGH);
        digitalWrite(Bomba, HIGH);
      }

      moll = 1;
    }
    else
    {
      Serial.println("Sec. Cal regar");
      COMPR_BOIES();
    }
  }

  while (ple == 0 && boies == 1 && moll == 0) //No se si el ple m'emprenyara
  {
    do
    {
      Serial.println("Cal engegar la bomba");
      BOMBA_ON();
    } while (!temp_BOMBA.estTermine() && ple == 0); //Afegit el ple

    digitalWrite(Bomba, HIGH);
  }

  if (ple == 1 && funcionant == 0 && moll == 0)
  {
    if (!temp_ELECTROVALVULA.estTermine())
    {
      Serial.println("S'ha acabat el temps de regar");
      REGAR();
    }
    else
    {
      do
      {
        Serial.println("A regar!!");
        digitalWrite(Electroval_01, HIGH);
        digitalWrite(Bomba, HIGH);
      } while (!temp_ESPERA.estTermine());
    }
  }
}

void COMPR_BOIES()
{
  if (digitalRead(boia_03) == LOW)
  {
    if (digitalRead(boia_02) == LOW)
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit buit");

        cas01 = 1;
        boies = 1;
      } //1
      else
      {
        Serial.println("Diposit quasi buit");
        digitalWrite(LED_01, HIGH);

        cas02 = 1;
        boies = 1;
      }
    }
    else
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit buit. ERROR boia 2!");

        cas03 = 1;
        boies = 1;
      } //3
      else
      {
        Serial.println("Diposit mig ple");
        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_02, HIGH);

        cas04 = 1;
        boies = 1;
      } //4
    }
  }
  else
  {
    if (digitalRead(boia_02) == LOW)
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit buit. ERROR boia 3!");

        cas05 = 1;
        boies = 1;
      } //5
      else
      {
        Serial.println("Diposit ple. ERROR boia 2!");

        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_03, HIGH);

        ple = 1;
        boies = 1;
      } //6
    }
    else
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit ple. ERROR boia 1!");

        digitalWrite(LED_02, HIGH);
        digitalWrite(LED_03, HIGH);

        ple = 1;
        boies = 1;
      } //7
      else
      {
        Serial.println("Diposit ple");

        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_02, HIGH);
        digitalWrite(LED_03, HIGH);

        ple = 1;
        boies = 1;
      } //8
    }
  }
}

void BOMBA_ON()
{
  funcionant = 1;
  do
  {
    digitalWrite(Bomba, LOW);
  } while (digitalRead(boia_03) == LOW);

  digitalWrite(Bomba, HIGH);

  if (cas01 == 1)
  {
    CAS01();
    cas01 = 0;
  }
  else
  {
    if (cas02 == 1)
    {
      CAS02();
      cas02 = 0;
    }
    else
    {
      if (cas03 == 1)
      {
        CAS03();
        cas03 = 0;
      }
      else
      {
        if (cas04 == 1)
        {
          CAS04();
          cas04 = 0;
        }
        else
        {
          if (cas05 == 1)
          {
            CAS05();
            cas05 = 0;
          }
        }
      }
    }
  }

  funcionant = 0;
  ple = 1;
}

void REGAR()
{
  do
  {
    digitalWrite(Electroval_01, LOW); //Abrir electrovalvula -- Obrir electrovalvola
  } while (digitalRead(boia_01) == HIGH);

  digitalWrite(Electroval_01, HIGH);
  moll = 1;
}

void CAS01()
{
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS02()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS03()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS04()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS05()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
}

Buenas de nuevo!

He encontrado un modo que me funcione, aún que no es mi código preferido. He visto que el problema lo tenía en:

  • Bucles de if/while En algún bucle se quedaba la placa trabajando y no salía de él porqué no me leía el tiempo/sensores como yo esperaba
  • Cálculo del tiempo de encendido/trabajo no sé porqué el cálculo del tiempo (temps_bomba * MSEC_PER_MIN) daba valor 0… poniendo el valor directamente y usando millis() directamente en la fórmula del bucle me ha funcionado

Dejo el código entero que me ha funcionado para si a alguien le puede ayudar. Algún día supongo que lo evolucionaré un poco pero ahora tengo trabajo físico en el huerto :wink:

const int hu_min = 550; //Valor minim de lectura del sensor per considerar moll
#define sensor_humitat_01 A0 //Inicialitzar el pin analogic -> Sensor d'humitat

#define boia_01 A5 //Inicialitzar el pin analogic (digital) -> Boia de baix
#define LED_01 A4 //Inicialitzar el pin analogic (digital) -> Led nivell baix ok
#define boia_02 13 //Inicialitzar el pin digital -> Boia del mig
#define LED_02 12 //Inicialitzar el pin digital -> Led nivell mig ok
#define boia_03 11 //Inicialitzar el pin digital -> Boia de dalt
#define LED_03 10 //Inicialitzar el pin digital -> Led nivell dalt ok

#define Bomba 3 //Inicialitzar el pin digital -> Rele bomba
#define Electroval_01 2 //Inicialitzar pin digital -> Rele electrovalvola

int moll = 0; //Constant per saber si ja s'ha comprovat la humitat
int ple = 0; //Constant per saber si ja ha funcionat la bomba
int funcionant = 0; //Constant per saber si esta emplenant el diposit o regant
int boies = 0; //Constant per saber si les boies han estat comprovades
int cas01 = 0;
int cas02 = 0;
int cas03 = 0;
int cas04 = 0;
int cas05 = 0;

void setup() {
  pinMode(sensor_humitat_01, INPUT);

  pinMode(boia_01, INPUT);
  pinMode(LED_01, OUTPUT);
  pinMode(boia_02, INPUT);
  pinMode(LED_02, OUTPUT);
  pinMode(boia_03, INPUT);
  pinMode(LED_03, OUTPUT);

  pinMode(Bomba, OUTPUT);
  pinMode(Electroval_01, OUTPUT);

  digitalWrite(Bomba, HIGH);
  digitalWrite(Electroval_01, HIGH);

  Serial.begin(9600);
}

void loop() {

  //Comprovar humitat del terra
  int humitat_01 = analogRead(sensor_humitat_01);
  Serial.print("Humitat: ");
  Serial.println(humitat_01);

  //Comprovar nivell diposit
  int nivell_boia01 = digitalRead(boia_01);
  int nivell_boia02 = digitalRead(boia_02);
  int nivell_boia03 = digitalRead(boia_03);
  Serial.print("Nivell boia 1: ");
  Serial.println(nivell_boia01);
  Serial.print("Nivell boia 2: ");
  Serial.println(nivell_boia02);
  Serial.print("Nivell boia 3: ");
  Serial.println(nivell_boia03);

  Serial.print("Funcionant: ");
  Serial.println(funcionant);
  Serial.print("Boies: ");
  Serial.println(boies);
  Serial.print("Moll: ");
  Serial.println(moll);
  Serial.print("Ple: ");
  Serial.println(ple);

  if (funcionant == 0 && moll == 0 && boies == 0)
  {
    if (humitat_01 < hu_min)
    {
      Serial.println("La terra està  humida");
      digitalWrite(Electroval_01, HIGH);
      digitalWrite(Bomba, HIGH);

      moll = 1;
    }
    else
    {
      Serial.println("Sec. Cal regar");
      COMPR_BOIES();
    }
  }

  if (ple == 0 && boies == 1 && moll == 0) //No se si el ple m'emprenyara
  {
    Serial.println("Cal engegar la bomba");
    BOMBA_ON();
  }

  if (ple == 1 && funcionant == 0 && moll == 0)
  {
    Serial.println("S'ha acabat el temps de regar");
    REGAR();
  }
}

void COMPR_BOIES()
{
  if (digitalRead(boia_03) == LOW)
  {
    if (digitalRead(boia_02) == LOW)
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit buit");

        cas01 = 1;
        boies = 1;
      } //1
      else
      {
        Serial.println("Diposit quasi buit");
        digitalWrite(LED_01, HIGH);

        cas02 = 1;
        boies = 1;
      }
    }
    else
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit buit. ERROR boia 2!");

        cas03 = 1;
        boies = 1;
      } //3
      else
      {
        Serial.println("Diposit mig ple");
        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_02, HIGH);

        cas04 = 1;
        boies = 1;
      } //4
    }
  }
  else
  {
    if (digitalRead(boia_02) == LOW)
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit buit. ERROR boia 3!");

        cas05 = 1;
        boies = 1;
      } //5
      else
      {
        Serial.println("Diposit ple. ERROR boia 2!");

        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_03, HIGH);

        ple = 1;
        boies = 1;
      } //6
    }
    else
    {
      if (digitalRead(boia_01) == LOW)
      {
        Serial.println("Diposit ple. ERROR boia 1!");

        digitalWrite(LED_02, HIGH);
        digitalWrite(LED_03, HIGH);

        ple = 1;
        boies = 1;
      } //7
      else
      {
        Serial.println("Diposit ple");

        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_02, HIGH);
        digitalWrite(LED_03, HIGH);

        ple = 1;
        boies = 1;
      } //8
    }
  }
}

void BOMBA_ON()
{
  Serial.println("Bomba engegada!");

  while (millis() <= 360000 && digitalRead(boia_03) == LOW) // Temps que estarà  la bomba engegada: 0.5min = 30000 - 6min = 360000
  {
    funcionant = 1;
    digitalWrite(Bomba, LOW);
  }

  digitalWrite(Bomba, HIGH);

  if (cas01 == 1)
  {
    CAS01();
    cas01 = 0;
  }
  else
  {
    if (cas02 == 1)
    {
      CAS02();
      cas02 = 0;
    }
    else
    {
      if (cas03 == 1)
      {
        CAS03();
        cas03 = 0;
      }
      else
      {
        if (cas04 == 1)
        {
          CAS04();
          cas04 = 0;
        }
        else
        {
          if (cas05 == 1)
          {
            CAS05();
            cas05 = 0;
          }
        }
      }
    }
  }
  funcionant = 0;
  ple = 1;
}

void REGAR()
{
  while (millis() <= 3600000 && digitalRead(boia_01) == HIGH) // Temps que estarà  la bomba engegada: 1h = 3600000
  {
    digitalWrite(Electroval_01, LOW); //Obrir electrovalvola
  } while (digitalRead(boia_01) == HIGH);

  digitalWrite(Electroval_01, HIGH);
  moll = 1;
}

void CAS01()
{
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS02()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS03()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS04()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS05()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
}

Gracias por vuestro tiempo y ayuda!

Esto esta mal

while (millis() <= 3600000 && digitalRead(boya_01) == HIGH)

una vez superado las 3600000 msesg = 3600 seg = 1 hora, el sistema siempre hará lo que indicas si la boya 01 esta en HIGH.

millis() debe compararse contra una variable que tenga el valor anterior de millis() mas 3600000
de este modo
te falta una variable como esta

unsigned long start;

Necesitas algo que inicie la cuenta y que luego no vuelva a accionarse hasta cumplir tu tiempo de accionamiento.
Basicamente todo pasa por aca mira

if (lleno == 0 && boies == 1 && moll == 0) //No se si el lleno m'emprenyara
  {
    Serial.println("Cal engegar la bomba");
    BOMBA_ON();
  }

  if (lleno == 1 && funcionant == 0 && moll == 0)
  {
    Serial.println("Se ha terminado el tiempo de regado");
    REGAR();
  }

o activas BOMBA_ON o activas REGAR según los flags.
Entonces deberías cuando activas tener otro flag para cada caso para que no vuelva a activarse BOMBA_ON o REGAR hasta cumplir el tiempo indicado.

Prueba con estas modificaciones

const int hu_min = 550;   //Valor minim de lectura del sensor per considerar moll
#define sensor_humitat_01 A0 //Inicialitzar el pin analogic -> Sensor d'humitat

#define boya_01   A5  //Inicialitzar el pin analogic (digital) -> Boia de baix
#define LED_01    A4  //Inicialitzar el pin analogic (digital) -> Led nivell baix ok
#define boya_02   13  //Inicialitzar el pin digital -> Boia del mig
#define LED_02    12  //Inicialitzar el pin digital -> Led nivell mig ok
#define boya_03   11  //Inicialitzar el pin digital -> Boia de dalt
#define LED_03    10  //Inicialitzar el pin digital -> Led nivell dalt ok

#define Bomba     3   //Inicialitzar el pin digital -> Rele bomba
#define Electroval_01 2 //Inicialitzar pin digital -> Rele electrovalvola

int moll = 0; //Constant per saber si ja s'ha comprovat la humitat
int lleno = 0; //Constant per saber si ja ha funcionat la bomba
int funcionant = 0; //Constant per saber si esta emllenonant el diposit o regant
int boies = 0; //Constant per saber si les boies han estat comprovades
int cas01 = 0;
int cas02 = 0;
int cas03 = 0;
int cas04 = 0;
int cas05 = 0;
unsigned long startBombaOn, startRegar;
bool fbombaON = false;  // flags para controlar la carga de la variable start contra millis()
bool fregar   = false;   

void setup() {
  pinMode(sensor_humitat_01, INPUT);

  pinMode(boya_01, INPUT);
  pinMode(LED_01, OUTPUT);
  pinMode(boya_02, INPUT);
  pinMode(LED_02, OUTPUT);
  pinMode(boya_03, INPUT);
  pinMode(LED_03, OUTPUT);

  pinMode(Bomba, OUTPUT);
  pinMode(Electroval_01, OUTPUT);

  digitalWrite(Bomba, HIGH);
  digitalWrite(Electroval_01, HIGH);

  Serial.begin(9600);
}

void loop() {

  //Comprovar humitat del terra
  int humitat_01 = analogRead(sensor_humitat_01);
  Serial.print("Humitat: ");
  Serial.println(humitat_01);

  //Comprovar nivell diposit
  int nivell_boya01 = digitalRead(boya_01);
  int nivell_boya02 = digitalRead(boya_02);
  int nivell_boya03 = digitalRead(boya_03);
  Serial.print("Nivel boya 1: ");
  Serial.println(nivell_boya01);
  Serial.print("Nivel boya 2: ");
  Serial.println(nivell_boya02);
  Serial.print("Nivel boya 3: ");
  Serial.println(nivell_boya03);

  Serial.print("Funcionamiento: ");
  Serial.println(funcionant);
  Serial.print("Boyas: ");
  Serial.println(boies);
  Serial.print("Moll: ");
  Serial.println(moll);
  Serial.print("Ple: ");
  Serial.println(lleno);

  if (funcionant == 0 && moll == 0 && boies == 0)
  {
    if (humitat_01 < hu_min)
    {
      Serial.println("La tierra esta humeda");
      digitalWrite(Electroval_01, HIGH);
      digitalWrite(Bomba, HIGH);

      moll = 1;
    }
    else
    {
      Serial.println("Sec. Cal regar");
      COMPR_BOYAS();
    }
  }

  if (lleno == 0 && boies == 1 && moll == 0) //No se si el lleno m'emprenyara
  {
    Serial.println("Cal engegar la bomba");
    if (fbombaON == false) {                // Ojo que no es una hora 360*1000 mseg = 6 minutos
        startBombaOn = millis()+360000UL;  // cargo valor de millis() + 1hora
        fbombaON == true;                  // me aseguro que no entrará mas hasta rearmar BOMBA_ON superada la hora
    }
    BOMBA_ON();
  }

  if (lleno == 1 && funcionant == 0 && moll == 0)
  {
    Serial.println("Se ha terminado el tiempo de regado");
    if (fregar == false) {
        startRegar = millis()+3600000UL; // cargo valor de millis() + 1hora
        fregar == true;                  // me aseguro que no entrará mas hasta rearmar REGAR superada la hora
    }
    REGAR();
  }
}

void COMPR_BOYAS() {

  if (digitalRead(boya_03) == LOW)
  {
    if (digitalRead(boya_02) == LOW)
    {
      if (digitalRead(boya_01) == LOW)
      {
        Serial.println("Depósito vacío");

        cas01 = 1;
        boies = 1;
      } //1
      else
      {
        Serial.println("Deposito casi vacio");
        digitalWrite(LED_01, HIGH);

        cas02 = 1;
        boies = 1;
      }
    }
    else
    {
      if (digitalRead(boya_01) == LOW)
      {
        Serial.println("Deposito vacio. ERROR boya 2!");

        cas03 = 1;
        boies = 1;
      } //3
      else
      {
        Serial.println("Deposito medio lleno");
        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_02, HIGH);

        cas04 = 1;
        boies = 1;
      } //4
    }
  }
  else
  {
    if (digitalRead(boya_02) == LOW)
    {
      if (digitalRead(boya_01) == LOW)
      {
        Serial.println("Deposito vacio. ERROR boya 3!");

        cas05 = 1;
        boies = 1;
      } //5
      else
      {
        Serial.println("Deposito lleno. ERROR boya 2!");

        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_03, HIGH);

        lleno = 1;
        boies = 1;
      } //6
    }
    else
    {
      if (digitalRead(boya_01) == LOW)
      {
        Serial.println("Deposito lleno. ERROR boya 1!");

        digitalWrite(LED_02, HIGH);
        digitalWrite(LED_03, HIGH);

        lleno = 1;
        boies = 1;
      } //7
      else
      {
        Serial.println("Deposito lleno");

        digitalWrite(LED_01, HIGH);
        digitalWrite(LED_02, HIGH);
        digitalWrite(LED_03, HIGH);

        lleno = 1;
        boies = 1;
      } //8
    }
  }
}

void BOMBA_ON()
{
  Serial.println("Bomba activada!");

  while (millis() <= startBombaOn  && digitalRead(boya_03) == LOW) // Temps que estarà la bomba engegada: 0.5min = 30000 - 6min = 360000
  {
    funcionant = 1;
    digitalWrite(Bomba, LOW);
  }

  digitalWrite(Bomba, HIGH);

  if (cas01 == 1)
  {
    CAS01();
    cas01 = 0;
  }
  else
  {
    if (cas02 == 1)
    {
      CAS02();
      cas02 = 0;
    }
    else
    {
      if (cas03 == 1)
      {
        CAS03();
        cas03 = 0;
      }
      else
      {
        if (cas04 == 1)
        {
          CAS04();
          cas04 = 0;
        }
        else
        {
          if (cas05 == 1)
          {
            CAS05();
            cas05 = 0;
          }
        }
      }
    }
  }
  funcionant = 0;
  lleno = 1;
}

void REGAR()
{
  while (millis() <= startRegar && digitalRead(boya_01) == HIGH) // Temps que estarà la bomba engegada: 1h = 3600000
  {
    digitalWrite(Electroval_01, LOW); //Obrir electrovalvola
  } while (digitalRead(boya_01) == HIGH);

  digitalWrite(Electroval_01, HIGH);
  moll = 1;
}

void CAS01()
{
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS02()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_02, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS03()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS04()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_03, HIGH);
}
void CAS05()
{
  digitalWrite(Bomba, HIGH);
  digitalWrite(LED_01, HIGH);
  digitalWrite(LED_02, HIGH);
}