Fallo en relé al actualizar datos DHT11en pantralla LCD

Buenas tardes, es mi primera consulta y gracias de antemano. Estoy haciendo un sistema para controlar la bañera de hidromasaje y tengo problemas con los relés. He puesto como accesorio, aunque no necesario, un DHT11 para saber temperatura y humedad del sitio donde va todo, mostrando los datos en un LCD por I2C. La cosa es que a través de pulsadores controlo la activación de los relés que ponen en marcha los diferentes elementos de la bañera, pero cuando tengo un relé activado, cada vez que el código entra en la función para leer el sensor y actualizar los datos en el LCD, los relés activados desconectan un instante y vuelven a conectar. En la función uso "millis()", para temporizar la actualización de lo datos. he probado muchas cosas y nada, no se si es por ruido, error de programación u otro que no logro descifrar.
Si quito la función que veréis para leer valores y mostrar en LCD, va bien. Los pulsadores están en Pull Down con resistencia de 10k y uso relés como el que muestro en la imagen. He probado a alimentar por separado con fuentes de alimentacion diferentes, unido GND's...

Pego el código a ver si me podéis ayudar:

//DHT sensor temperatura y humedad
#include <DHT.h>
#include <DHT_U.h>

//LCD_1602A_I2C
#include <Wire.h>		             	// libreria de comunicacion por I2C
#include <LCD.h>		            	// libreria para funciones de LCD
#include <LiquidCrystal_I2C.h>		// libreria para LCD por I2C

//Creamos el objeto "lcd"
LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7); // DIR, E, RW, RS, D4, D5, D6, D7

//Temperatura y humedad
#define sensor 17 //A3 analogico
int temperatura;
int humedad;
DHT dht(sensor, DHT11); //creamos el objeto "dht"

//Para lectura temperatura/humedad cada X tiempo
unsigned long tiempoAnterior = 0; //almacena ultima vez que lanzamos el evento
const unsigned long intervaloLectura = 30000; //establece cada cuando tiempo hace lectura

//funcion de lectura temperatura/humedad
int tempHumid(){
  
  unsigned long tiempoActual = millis();

   if(tiempoActual - tiempoAnterior >= intervaloLectura){
    temperatura = dht.readTemperature();
    humedad = dht.readHumidity();
    lcd.clear();
    lcd.setCursor(0, 0);		// ubica cursor en columna 0 y linea 0
    lcd.print("Temperatura:");	// escribe el texto
    lcd.setCursor(12, 0);   // ubica cursor en columna 14 y linea 0 
    lcd.print(temperatura);
    lcd.print((char)223);// pone el º de grados centígrados
    lcd.print("C");
    lcd.setCursor(0, 1);		
    lcd.print("Humedad:");	
    lcd.setCursor(9, 1);
    lcd.print(humedad);
    lcd.print("%");
    tiempoAnterior = tiempoActual;
  }
}

////////////////////////////// programa de control bañera hidromasaje////////////////////////////

//defino salidas para activar reles
#define agua 2
#define motorRecir 3
#define motorAire 4
#define aire1 5
#define aire2 6

//defino entradas de pulsadores
#define pulAgua 7
#define pulMotorRecir 8
#define pulMotorAire 9
#define pulAire1 10
#define pulAire2 11
#define pulStopTotal 12

//variables para uso con pulsadores
int estadoAgua = 0;
int anteriorAgua = 0;

int estadoMotorRecir = 0;
int anteriorMotorRecir = 0;

int estadoMotorAire = 0;
int anteriorMotorAire = 0;

int estadoAire1 = 0;
int anteriorAire1 = 0;

int estadoAire2 = 0;
int anteriorAire2 = 0;

int estadoStopTotal = 0;
int anteriorStopTotal = 0;


//Funcion para detectar pulsadores
int pulsador (int estadoPul, int estadoAnterior, int estadoActual){
	
  if(digitalRead(estadoPul)){   //if para evitar que entre (delay's) si no pulsamos 
    int pulsado = digitalRead(estadoPul);
    delay(300); //Para evitar cambio de estado repetidas veces al pulsar
    if(pulsado == 1 && estadoAnterior == 0){
		  estadoActual = 1;
	  } 
	  if(pulsado == 1 && estadoAnterior == 1){
		  estadoActual = 0;
	  }
  }
	return estadoActual;
}

void setup() {
	Serial.begin(9600);
  dht.begin();

  //LCD I2C
  lcd.setBacklightPin(3,POSITIVE);	// puerto P3 de PCF8574 como positivo
  lcd.setBacklight(HIGH);		// habilita iluminacion posterior de LCD
  lcd.begin(16, 2);			// 16 columnas por 2 lineas para LCD 1602A
  lcd.clear();			// limpia pantalla

	pinMode(agua, OUTPUT);
	pinMode(motorRecir, OUTPUT);
	pinMode(motorAire, OUTPUT);
	pinMode(aire1, OUTPUT);
	pinMode(aire2, OUTPUT);

	digitalWrite(agua, LOW);
	digitalWrite(motorRecir, LOW);
	digitalWrite(motorAire, LOW);
	digitalWrite(aire1, LOW);
	digitalWrite(aire2, LOW);

	pinMode(pulAgua, INPUT);
	pinMode(pulMotorRecir, INPUT);
	pinMode(pulMotorAire, INPUT);
	pinMode(pulAire1, INPUT);
	pinMode(pulAire2, INPUT);
	pinMode(pulStopTotal, INPUT);
}

void loop() {
  ///////////////////////////////// medir temperatura y humedad ////////////////////////////////////////

  tempHumid();

	//////////////////////////// abrir/cerrar válvula de llenado bañera //////////////////////////////////////

  estadoAgua = pulsador(pulAgua,anteriorAgua,estadoAgua);
	anteriorAgua = estadoAgua;
    
  if(estadoAgua){
      
    if(digitalRead(aire1) == HIGH){ //comprobamos si la valvula de aire1 esta abierta para cerrarla
      
      digitalWrite(aire1, LOW);
      //Serial.println("cerrando valvula aire1...");
      delay(15000); //tiempo que tarda la valvula en cerrarse
    }

    digitalWrite(agua, HIGH);
    //Serial.println("La valvula de agua esta abierta");
  }

  if(!estadoAgua){
    
    digitalWrite(agua, LOW);
    //Serial.println("La valvula de agua esta cerrada");
    }
  
	////////////////////////////// marcha/paro motor recirculación ////////////////////////////////////

	estadoMotorRecir = pulsador(pulMotorRecir,anteriorMotorRecir,estadoMotorRecir);
	anteriorMotorRecir = estadoMotorRecir;

  if(estadoMotorRecir){

    digitalWrite(motorRecir, HIGH);
    //Serial.println("Chorro de hidromasaje en marcha");
  }

  if(!estadoMotorRecir){
    
    digitalWrite(motorRecir, LOW);
    //Serial.println("Chorro de hidromasaje parado");
  }

	/////////////////////////////// marcha/paro motor aire //////////////////////////////

  estadoMotorAire = pulsador(pulMotorAire,anteriorMotorAire,estadoMotorAire);
  anteriorMotorAire = estadoMotorAire;

  if(estadoMotorAire){
      
    if(digitalRead(aire1) == LOW && digitalRead(aire2) == LOW){ //comprobamos si las valvulas de aire1/aire2 estan cerradas
      
      digitalWrite(aire1, HIGH);
      //Serial.println("Abriendo valvula de aire de fondo");
      delay(15000); //tiempo que tarda la valvula en abrirse
    }

    digitalWrite(motorAire, HIGH);
    //Serial.println("Motor de soplador de aire en marcha");
  }

  if(!estadoMotorAire){
    
    digitalWrite(motorAire, LOW);
    //Serial.println("Motor de soplador de aire parado");
  }

	//////////////////////////////// abrir/cerrar vávula de aire1 (fondo) ////////////////////

  estadoAire1 = pulsador(pulAire1,anteriorAire1,estadoAire1);
  anteriorAire1 = estadoAire1;

  if(estadoAire1 && digitalRead(agua) == LOW){
    
    digitalWrite(aire1, HIGH);
    //Serial.println("Valvula de aire1 (fondo) abierta"); 
  }

  if(!estadoAire1){
    
    if(digitalRead(motorAire) == LOW  || digitalRead(aire2) == HIGH){
      
      digitalWrite(aire1, LOW);
      //Serial.println("Valvula de aire1 (fondo) cerrada");

    } else { Serial.println("No se puede cerrar (fondo), ya que el motor esta en marcha y aire2 cerrado"); }    
  }

	//////////////////////////////// abrir/cerrar vávula de aire2 (pared) ////////////////////

  estadoAire2 = pulsador(pulAire2,anteriorAire2,estadoAire2);
  anteriorAire2 = estadoAire2;

  if(estadoAire2){

    digitalWrite(aire2, HIGH);
    //Serial.println("Valvula de aire2 (pared) abierta"); 
  }

  if(!estadoAire2){

    if(digitalRead(motorAire) == LOW  || digitalRead(aire1) == HIGH){
    
      digitalWrite(aire2, LOW);
      //Serial.println("Valvula de aire2 (pared) cerrada");

    } else { Serial.println("No se puede cerrar (pared), ya que el motor esta en marcha y aire1 cerrado"); }
  }

  ///////////////////////// parada total ////////////////////////////////

  estadoStopTotal = pulsador(pulStopTotal,anteriorStopTotal,estadoStopTotal);
  anteriorStopTotal = estadoStopTotal;

  if(estadoStopTotal || !estadoStopTotal){

    digitalWrite(agua, LOW);
    digitalWrite(motorRecir, LOW);
    digitalWrite(motorAire, LOW);
    digitalWrite(aire1, LOW);
    digitalWrite(aire2, LOW);
  }

}//cierre de loop

Y por supuesto en el LCD no se muestra nada. ¿Verdad?.

Si, se muestra los datos en el LCD perfectamente y he probado a soplar en el sensor para variar los datos y se actualizan bien. Digamos que todo funciona como ha de ser, excepto en esa desconexión que hace el relé al entrar a la función temphumid. Con tester he visto que el pin de activacion pasa low momentaneamente.

Por cierto uso un Arduino Nano.
Pongo foto de montaje por si puede aclarar algo.

Pues no me lo explico. ¿Seguro que el código que has subido es el que esta funcionando?. Para mi por mas que lo toco no logro que compile y tiene errores graves, compruébalo.

Bien, en principio estas cargando dos librerías para tu LCD , la primera:

#include <LCD.h>

Que no es para una LCD I2C y una segunda:

#include <LiquidCrystal_I2C.h>

Que si es para una LCD I2C, pero la estas llamando erróneamente como si no fuera I2C:

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

Y le estas pasando unos pines innecesarios que casualmente algunos te coinciden con los que controlan los relés. No tengo muy claro porque pero en algún momento te esta funcionando la no I2C y te anda toqueteando los relés.

Quita la libreria no I2C y crea bien el objeto Lcd I2C:

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

Y en el setup lo que actualmente tienes como:

//LCD I2C
  lcd.setBacklightPin(3,POSITIVE);  // puerto P3 de PCF8574 como positivo
  lcd.setBacklight(HIGH);   // habilita iluminacion posterior de LCD
  lcd.begin(16, 2);     // 16 columnas por 2 lineas para LCD 1602A
  lcd.clear();      // limpia pantalla

Lo cambias a:

 lcd.init(); // initialize the lcd 
 lcd.backlight(); // habilita iluminación posterior de LCD
 lcd.clear();      // limpia pantalla

Creo que no me olvido de nada y con estos cambios todo debería funcionar.

Buenas noches! En efecto el fallo venía de la libreria y como implementaba el objeto "lcd". Ahora va perfecto y el resto del codigo funcona sin problemas. Lo que si he visto, al hacerlo como me has dicho, es que la librería que tenia, era una version distinta y no funcionaba. Por ejemplo init(), esta declarada como "private". Busque la correcta y wala todo bien. Aunque como te dije ante ir el lcd iba... Cosa rara cierto. Muchísimas gracias por tu ayuda! A seguir aprendiendo. Saludos!

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