EL Sketch funciona pero se cuelga al rato.

Saludos y una ronda para tod@s!

Estoy haciendo una incubadora. Resumiendo, la arduino uno, me lee la temperatura y humedad exterior e interior y en base a las lecturas y al paso de los días, se activan 3 relés: uno que controla una resistencia, el otro un nebulizador de humedad y el último una bandeja de volteo de los huevos.

La tengo conectada a un display 20X4 con I2C, a un DHT22, un DHT11 y una fuente de 12v.

La cosa es que cuando inicio ,a veces me salen caracteres raros en el LCD y otras me sale todo bien. En cualquier caso, el programa se ejecuta correctamente, hace lo que yo quiero pero se acaba colgando, sin excepción. A veces tarda mas, otras menos. Se apaga la pantalla, se quedan las lecturas fijas sin variación.. en fin, que no se me ocurre qué mirar. Soy novato y es mi primer proyecto, así que si alguien puede echar un cable... Pues yo muy agradecido!!

Pego el código:

//CONTROL LCD
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7);

//CONTROL TEMPERATURA Y HUMEDAD INTERIOR Y EXTERIOR
#include <DHT.h>
#include <DHT_U.h>

DHT dht1(2, DHT22);
DHT dht2(3, DHT11);

float TI; // temperatura interior
int HI; // humedad interior
int TE; // temperatura exterior
int HE; // temperatura exterior

//CONTADOR DE DIAS
unsigned long days;

//Rotación

int RELE_ROTACION = 9;

//Temperatura

int RELE_TI = 5;


//Humedad

int RELE_HI = 10;

void setup() 
{
  
  lcd.setBacklightPin (3, POSITIVE);
  lcd.setBacklight (HIGH);
  lcd.begin(20, 4);
  lcd.clear();
  dht1.begin();
  dht2.begin();
  pinMode (RELE_TI, OUTPUT);
  pinMode (RELE_ROTACION, OUTPUT);
  pinMode (RELE_HI, OUTPUT);
  
}

void loop(){ 
  
  TI = dht1.readTemperature();
  HI = dht1.readHumidity();
  TE = dht2.readTemperature();
  HE = dht2.readHumidity();
  days = millis()/86400000;
  
 
 //Temperatura
                 
 if(days>18) {
                 
                 if (TI<=35.6) { digitalWrite(RELE_TI,HIGH); }
                 else { digitalWrite(RELE_TI,LOW); }
                
                }
 if(days<=18) {
    
                if (TI<=37.5) { digitalWrite(RELE_TI,HIGH); }
                else { digitalWrite(RELE_TI,LOW); }}


  // ROTACION
  
  if ((days > 3) && (days <= 18)) {digitalWrite(RELE_ROTACION, HIGH);}
  else {digitalWrite(RELE_ROTACION, LOW);}

  // HUMEDAD

    if(days>=18) {
                 
               if (HI<80) { digitalWrite(RELE_HI,HIGH); }
               else { digitalWrite(RELE_HI,LOW); }
                
                }
   if(days<18) {
    
            if (HI<60) { digitalWrite(RELE_HI,HIGH); }
            else { digitalWrite(RELE_HI,LOW); }}

                
  lcd.setCursor ( 0 , 0 ); 
  lcd.print (" DIAS INC. ");
  lcd.print (days);
  
  lcd.setCursor ( 0 , 1 ); 
  lcd.print (" TI:");
  lcd.print (TI);
  lcd.print ("\337C ");
  lcd.print (" TE:");
  lcd.print (TE);
  lcd.print ("\337C");
  
  lcd.setCursor ( 0 , 2 ); 
  lcd.print  ( " HI:" );
  lcd.print (HI);
  lcd.print  ( "%" ); 
  lcd.print  ( "      HE:" );
  lcd.print (HE);
  lcd.print  ( "%" );
  
  lcd.setCursor ( 0, 3 );  // Iniciar en la columa 1 fila 3
 
  lcd.print ( " C:" );

      if (digitalRead (RELE_TI) == (1)) { lcd.print("ON ");}
      else { lcd.print("OFF"); }

  lcd.print ( " H:" );

              if (digitalRead (RELE_HI) == (1)) { lcd.print("ON ");}
      else { lcd.print("OFF"); }

 lcd.print ( " R:" );
            
         if (digitalRead (RELE_ROTACION) == (1)) { lcd.print("ON ");}
      else { lcd.print("OFF"); }
  delay( 1000 ); 
}

Con que me podáis decir si el código está bien o tiene algún error evidente, de algo ya me serviría.

Muchas gracias,

No veo ningún error aparente en el código.

La aleatoriedad del funcionamiento del display y del cuelgue del Arduino sugiere que hay algún tipo de ruido eléctrico.

Para poder ayudarte mejor necesitamos saber como has hecho las conexiones de todos los elementos.

Muchísimas gracias por tu respuesta. No sabes la ilusión que me ha hecho verla.

Pues voy a hacer un esquema sencillo a ver si puede orientar en algo.

Insisto, muchas gracias,

No entiendo por qué estás usando tres librerías distintas para el display ( LCD, LiquidCrystal y LiquidCrystal_I2C ). Esto es peligroso porque pueden tener comandos en común y al incluir las tres en tu scketch el programa puede entrar en conflicto. Si tu lcd2004 tiene el adaptador I2C dejá la última de las que declaraste, sinó podés dejar la anterior.

Hola! Muchas gracias por tu mensaje.
Verás, como digo soy principiante y a veces me lío un poco. Al principio cuando conecté el 20x4 por I2C, me dió problemas y tuve que probar con varias librerías hasta que me funcionó. Voy a hacer lo que propones, se o no la causa del problema, evitaré conflictos como bien dices.

Muchas gracias de nuevo!

victorjam:
No veo ningún error aparente en el código.

La aleatoriedad del funcionamiento del display y del cuelgue del Arduino sugiere que hay algún tipo de ruido eléctrico.

Para poder ayudarte mejor necesitamos saber como has hecho las conexiones de todos los elementos.

Las conexiones a nivel de pines de entrada y salida son las que salen en el código. Luego tengo una fuente conectada a la protoboard y de ahí cojo +5 y GND. Hay un relé conectado a una resistencia de 80w, otro a una fuente de 24v que alimenta del nebulizador y otro conectado a un motor de rotación lenta que va directamente a 220v. Los tres relés se alimentan de la protoboard. El GND de el DHT22 lo tengo conectado en un GND aparte directamente a la arduino. Calor no he detectado que se genere tanta como para bloquearla.

Después de tu comentario, he distanciado todos los elementos para intentar evitar el "ruido" que mencionabas.

Lo que si he comprobado después de muchas pruebas es que mientras estan activos 1 o 2 relés, no parece haber problema y funciona bien. Es cuando se conectan los 3 a la vez cuando la tarjeta peta y se reinicia. Sin excepción...

Los relés siempre llevan conectados un diodo shottky ( 1N4148 ) en antiparalelo con la bobina. Esto no sólo elimina parte del ruido sino que protege al transistor que lo alimenta de sobretensiones

Pablo_Lucini:
Los relés siempre llevan conectados un diodo shottky ( 1N4148 ) en antiparalelo con la bobina. Esto no sólo elimina parte del ruido sino que protege al transistor que lo alimenta de sobretensiones

Se te ocurre por qué motivo colapsa y se reinicia cuando se activan los 3 relés simultáneamente?

Ahora el error siempre es el mismo, cuando se activan los 3 a la vez.

En cuanto a la resistencia no dices que tensión utiliza, pero al ser un elemento resistivo no debería dar problemas de ruido.

El nebulizador hay que ver que corta: la tensión de 220VAC de la fuente (es decir paras la fuente y la enciendes) o por el contrario lo que cortas es la tensión de 24V. Dicho nebulizador funcionará con un motor de corriente continua o similar, si no dispone de diodo antiparalelo deberías de ponerlo ya. Si la fuente es relativamente buena tendrá filtros a la entrada.

El motor de rotación lenta es de 220VAC, aquí si debes de colocar un filtro RC-Snubber o un varistor, como bien recomendará #Tauro coloca un varistor en la entrada del motor.

Creo que hay algún problema en el programa. He hecho pruebas con un programa sencillo que me active todos los relés y los dispositivos sin mas y lo hace sin ningún problema. Creo que he cometido un error en el programa, pero no sé ver dónde. Solo que cuando se activan los tres hay un error que lo reinicia...

Aparte de lo que comentó Pablo_Lucini sobre el uso de la libreria LiquidCrystal no encuentro nada.

Si estás usando el código este:

//CONTROL LCD
#include <LCD.h>
// #include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

//CONTROL TEMPERATURA Y HUMEDAD INTERIOR Y EXTERIOR
#include <DHT.h>
#include <DHT_U.h>

LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7);

DHT dht1(2, DHT22);
DHT dht2(3, DHT11);

float TI; // temperatura interior
int   HI; // humedad interior
int   TE; // temperatura exterior
int   HE; // temperatura exterior


unsigned long days;    //CONTADOR DE DIAS
int RELE_ROTACION = 9; //Rotación
int RELE_TI = 5;       //Temperatura
int RELE_HI = 10;      //Humedad

void setup()
{
  lcd.setBacklightPin (3, POSITIVE);
  lcd.setBacklight (HIGH);
  lcd.begin(20, 4);
  lcd.clear();
  dht1.begin();
  dht2.begin();
  pinMode (RELE_TI, OUTPUT);
  pinMode (RELE_ROTACION, OUTPUT);
  pinMode (RELE_HI, OUTPUT);

}

void loop() {

  TI = dht1.readTemperature();
  HI = dht1.readHumidity();
  TE = dht2.readTemperature();
  HE = dht2.readHumidity();
  days = millis() / 86400000;


  //Temperatura
  if (days > 18) {
    if (TI <= 35.6) {
      digitalWrite(RELE_TI, HIGH);
    }
    else {
      digitalWrite(RELE_TI, LOW);
    }
  }
  if (days <= 18) {
    if (TI <= 37.5) {
      digitalWrite(RELE_TI, HIGH);
    }
    else {
      digitalWrite(RELE_TI, LOW);
    }
  }

  // ROTACION
  if ((days > 3) && (days <= 18)) {
    digitalWrite(RELE_ROTACION, HIGH);
  }
  else {
    digitalWrite(RELE_ROTACION, LOW);
  }

  // HUMEDAD
  if (days >= 18) {
    if (HI < 80) {
      digitalWrite(RELE_HI, HIGH);
    }
    else {
      digitalWrite(RELE_HI, LOW);
    }
  }
  if (days < 18) {
    if (HI < 60) {
      digitalWrite(RELE_HI, HIGH);
    }
    else {
      digitalWrite(RELE_HI, LOW);
    }
  }


  lcd.setCursor ( 0 , 0 );
  lcd.print (" DIAS INC. ");
  lcd.print (days);

  lcd.setCursor ( 0 , 1 );
  lcd.print (" TI:");
  lcd.print (TI);
  lcd.print ("\337C ");
  lcd.print (" TE:");
  lcd.print (TE);
  lcd.print ("\337C");

  lcd.setCursor ( 0 , 2 );
  lcd.print  ( " HI:" );
  lcd.print (HI);
  lcd.print  ( "%" );
  lcd.print  ( "      HE:" );
  lcd.print (HE);
  lcd.print  ( "%" );

  lcd.setCursor ( 0, 3 );  // Iniciar en la columa 1 fila 3

  lcd.print ( " C:" );

  if (digitalRead (RELE_TI) == (1)) {
    lcd.print("ON ");
  }
  else {
    lcd.print("OFF");
  }

  lcd.print ( " H:" );

  if (digitalRead (RELE_HI) == (1)) {
    lcd.print("ON ");
  }
  else {
    lcd.print("OFF");
  }

  lcd.print ( " R:" );

  if (digitalRead (RELE_ROTACION) == (1)) {
    lcd.print("ON ");
  }
  else {
    lcd.print("OFF");
  }
  delay( 1000 );
}

No se aprecia a simple vista, quizás se pueda optimizar la programación, pero en lo que es errores yo no lo veo.

Si muestras unas fotos del montaje podremos ver si hay algun fallo.

alfinger77:
Se te ocurre por qué motivo colapsa y se reinicia cuando se activan los 3 relés simultáneamente?

Ahora el error siempre es el mismo, cuando se activan los 3 a la vez.

En el instante en que quitás la alimentación de la bobina de un relé se genera en ésta una tensión inducida cuyo valor es el doble de la de alimentación. La bobina funciona acumulando energía parecido a lo que hace un capacitor. Esta tensión puede quemarte el transistor o bien meter ruido de muy alta frecuencia en la alimentación , por eso se la bloquea con un diodo muy rápido ( shottky) en antiparalelo con la bobina que " apaga" ese transitorio. Si encima tenés tres relés vas a tener tres transitorios seguidos, ( nunca suelen ser simultáneos aunque desconectes al mismo tiempo los tres ), que si se reflejan en la alimentación pueden colgarte el Arduino.

Hi,
De que voltaje usas para energizar la resistencia, el humedizador y la bandeja de volteo. Aqui podrias usar un snubber que es una resisencia de 50 homios en serie con un condesaador de .1ufd en paralelo a los contactos o puedes usar un varistor.. Para decirte cual debes de usar necesito el voltaje que alimentas los equipos.