Problema con valores en LCD.

Muy buenas a todos, he realizado una maqueta de jardún automatizado y el funcionamiento obtenido se corresponde con el deseado; pero hay un pequeño problema que no logro entender por qué sucede. Os comento:

Tengo una LCD 16x2 en la que muestro los valores de temperatura y luminosidad, alternando mediante un pulsador para que me muestre los valores de humedad del suelo y relativa del aire.

El problema viene que cuando cambio drásticamente (en funcionamiento normal no hay ningún problema) el valor de alguna de esas variables, la otra que se esta mostrando también cambia y de forma desproporcionada sin deber hacerlo (las otras dos variables que no muestro en ese instante no sufren modificación). Por ejemplo:

Si estamos a 25ºC y un porcentaje de luminosidad del 2%, si hago que la luminosidad pase al 70% la temperatura también aumenta y de forma fluctuada sin tener que hacerlo. Las otras dos variables que no se están mostrando nos sufren modificación, por eso intuyo que el problema pueda estar relacionado con la programación de la LCD.

¿Alguien puede saber por qué sucede esto?

Código:

#include <DHT11.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

#define sensorLl 4
#define sensorHR 5
#define bomba 9                       //TIENE LOGICA NEGADA, CON UN CERO LO HAGO CONMUTAR AL RELE.
#define ventilador 10                 //TIENE LOGICA NEGADA, CON UN CERO LO HAGO CONMUTAR AL RELE.
#define rojo 11
#define verde 12
#define azul 13

volatile bool situacion1 = LOW;
volatile bool situacion2 = LOW;
unsigned long tiempo = 0;

boolean comprobacion; //PARA VER SI ESTA O NO LLOVIENDO.

unsigned int humedadSuelo;

float temp;

DHT11 dht11(sensorHR);
LiquidCrystal_I2C  lcd(0x27, 2, 1, 0, 4, 5, 6, 7);      //Dirección del LCD para usarse en el protocolo I2C y números que indican que pines debe usar la librería para el LCD.

//SCL -> A5
//SDA -> A4

byte grado[8] =       //Array para añadir el caracter 'º' en el LCD.
{
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};


void setup() {

 //DECLARACIÓN DE INTERRUPCIÓN PARA LOS DOS PULSADORES:
 
 attachInterrupt(0, lecturaPulsador2, RISING);    //SE DISPARA CUANDO PASO DE LOW A HIGH, ES DECIR, CUANDO PULSO.  INTERRUPCION CERO QUE CORRESPONDE AL PIN 2
 attachInterrupt(1, lecturaPulsador1, RISING);    //SE DISPARA CUANDO PASO DE LOW A HIGH, ES DECIR, CUANDO PULSO.  INTERRUPCION CERO QUE CORRESPONDE AL PIN 3

 //NO DEFINIMOS EL PIN 3 COMO ENTRADA PUESTO QUE EN EL DATA SHEET VEMOS QUE EL PIN DATA DEL SENSOR ES BIDIRECCIONAL, PUESTO QUE ES EL MICRO QUIEN DA LA SEÑAL CUANDO HAY ERROR.

//Entradas:

 pinMode(A2, INPUT);          //Leeré LDR.
 pinMode(A1, INPUT);          //Leeré el sensor de Humedad del Suelo.
 pinMode(A0, INPUT);          //Leeré el LM35  
 pinMode(sensorLl, INPUT);

//bomba:

 pinMode(bomba, OUTPUT);

 //Ventilador:

 pinMode(ventilador, OUTPUT);

 //RGB:

 pinMode(rojo, OUTPUT);
 pinMode(verde, OUTPUT);
 pinMode(azul, OUTPUT);

 Serial.begin(9600);

 //INICIALIZACIÖN DEL LCD:

 lcd.begin (16,2);                    // Inicializar el display con 16 caraceres 2 lineas
 lcd.clear();                         //Borramos lo que pueda haber anteriormente.
 lcd.setBacklightPin(3,POSITIVE);     
 lcd.setBacklight(HIGH);              //Estas dos últimas líneas son para darle luz a la pantalla.
 lcd.createChar(1, grado);            //Para el caracter grado.
}

void loop() {


 lcd.clear();    //Para limpiar lo que estaba antes y no se escriba lo nuevo a mostrar encima de lo que estaba..
   
 //Pulsador 1:                             //VOY A HACERLO CON UNA INTERRUPCIÓN, PUESTO QUE EL CAMBIO ES BASTANTE MÁS RÁPIDO.

 //Pulsador 2:                             //ESTE PULSADOR TIENE PRIORIDAD, PUESTO QUE CON EL VAMOS A REALIZAR UNA PARADA DEL SISTEMA.

 //Ventilador:

 LM35();
 
 if (temp >= 25) digitalWrite(ventilador, LOW);
 else digitalWrite(ventilador, HIGH);
 
 //Comprobamos si esta lloviendo y vemos que si esta lloviendo es seguro que desactivo la bomba. Si no llueve la activaré dependiendo del valor de la humedad del suelo.
   
 HSuelo();
 
 if ((comprobacion == HIGH) && (humedadSuelo <= 50)) digitalWrite(bomba, LOW);       //SI NO ESTA LLOVIENDO Y LA HUMEDAD ES INFERIOR AL 50%, ACTIVO LA BOMBA.
 else digitalWrite(bomba, HIGH);

   if (situacion2 == LOW){

     if (situacion1 == LOW){   //Si no pulso pulsador 1, comenzaré mostrando la temperatura.

       //Ya hice la llamda a la función LM_35() arriba.

            lcd.setCursor ( 0, 0 ); 
            lcd.print("Temp:");      //Por defecto escribo en la columna 0, fila 0
            lcd.setCursor ( 6, 0 );        //Columna 0, fila 1.
            lcd.print(temp);
            lcd.setCursor ( 11, 0 );
            lcd.write(1);  
            lcd.print("C");

       //Ahora muestro el porcentaje de humedad relativa del aire en el LCD.

            Luminosidad();
       
     }
     
     else {  
                         //Simplemente vamos a mostrar los valores.
     
            
           HumedadRelativa();
           
       //Para representar la humedad del suelo en el LCD:
        
            lcd.setCursor (0, 1);
            lcd.print("HumedadSuelo: ");
            lcd.setCursor (13, 1);
            lcd.print(humedadSuelo);
            lcd.setCursor(15, 1);
            lcd.print("%");

     }
   }
   
   else {      //EN ESTA SITUACION TENGO QUE PARAR LOS ACTUADORES.
     
            lcd.setCursor ( 3, 0 ); 
            lcd.print("SOLUCIONAR");           //ESTO NO ES NECESARIO QUE LO META DENTRO DEL WHILE PORQUE MIENTRAS NO LIMPIE LA PANTALLA DEL LCD SE QUEDA LO ULTIMO MOSTRADO.
            lcd.setCursor ( 3, 1);        
            lcd.print("EMERGENCIA");
            
            digitalWrite(bomba, HIGH);       //LO APAGO POR SI EN EL MOMENTO DE PULSAR EL BOTÓN DE EMERGENCIA ESTABA ENCENDIDO.
            digitalWrite(ventilador, HIGH);
            
            while (situacion2 == HIGH){RGB();} //MIENTRAS ESTÉ EN LA SITUACIÓN DE EMERGENCIA NO QUIERO RECOGER EL ESTADO DEL PULSADOR 1, ASÍ CUANDO SALGA DE LA EMERGENCIA SEGUIRE MOSTRANDO LO QUE ESTABA EN EL LCD ANTES DE PRODUCIRSE AUNQUE MIENTRAS TANTO PULSE P1.
         
   }

   delay(1000);


}


void lecturaPulsador1() {

  if ( millis() > tiempo  + 250){
       
       situacion1 = !situacion1;
       tiempo = millis();
   }
 
}


void lecturaPulsador2() {         //RUTINA DE SERVICIO DE INTERRUPCION. CUANDO PULSO EL BOTON DE EMERGENCIA ES CUANDO ENTRO.

  if ( millis() > tiempo  + 250){
       
       situacion2 = !situacion2;
       tiempo = millis();
   }
   
}

void LM35() {

 unsigned int lectura = analogRead(A0);    //Leo entre 0 y 1023.

 float voltaje = ((lectura * 5.0) / 1023) * 1000;  //lectura en mV
 
 temp = voltaje / 10; //En grados centígrados.

 //VISUALIZACIÓN POR EL MONITOR SERIE:

 Serial.print("Temperatura: ");
 Serial.print(temp);
 Serial.println();

}

void HumedadRelativa(){

 float humedad, temperatura;
 int error = dht11.read(humedad, temperatura);  //La lectura será correcta cuando el error sea cero.

 unsigned long HR = humedad;       //LO HAGO ASI PARA QUITARME LA PARTE DECIMAL QUE SON TODO CEROS.

 if (error == 0){

   //LCD:
   lcd.setCursor(0, 0);
   lcd.print("HumedadAire: ");      //Por defecto escribo en la columna 0, fila 0
   lcd.setCursor ( 13, 0 );        //Columna 0, fila 1.
   lcd.print(HR);
   lcd.setCursor ( 15, 0 );
   lcd.print("%");

   //Puerto Serie:

   //Serial.print("Temperatura: ");
   //Serial.println(temperatura);
   Serial.print("Humedad Aire: ");
   Serial.println(humedad);

 }
 else Serial.println("Error en la medicion");
}

void Luminosidad(){   //DIVISOR DE TENSION CON RESISTENCIA PULL DOWN.

 unsigned int LDR = analogRead(A2);

 float porcentaje = (LDR * 100.0) / 1023;

 //LCD:

 lcd.setCursor(0, 1);
 lcd.print("Lux: ");      //Por defecto escribo en la columna 0, fila 0
 lcd.setCursor ( 5, 1 );        //Columna 0, fila 1.
 lcd.print(porcentaje);
 lcd.setCursor ( 9, 1 );
 lcd.print("%");

 //Puerto Serie:

 Serial.print("Porcentaje: ");
 Serial.print(porcentaje);
 Serial.println("%");


}

void sensorLluvia(){

 comprobacion = digitalRead(sensorLl);     //TIENE LÓGICA INVERSA. DA LOW CUANDO DETECTA LLUVIA.

 if (comprobacion == LOW)  Serial.println("Está lloviendo");
 else Serial.println("No está lloviendo");
 
}

void HSuelo(){

  sensorLluvia();      //HAGO LA LLAMADA AQUI PORQUE LA ACTIVACIÓN DE LA BOMBA ME DEPENDERÁ DE SI ESTA LLOVIENDO O NO, Y EN FUNCION DEL VALOR DE LA HUMEDAD.

  //SI EL SUELO ESTA COMPLETAMENTE SECO, LA LECTURA ES DE 1023. SI ESTA COMPLETAMENTE MOJADO, LA LECTURA ES DE 0.
  
  unsigned int leido = analogRead(A1);
  
  //VAMOS A DAR EL PORCENTAJE DE HUMEDAD DEL SUELO:
  
  humedadSuelo = (100.0 * leido) / 1023;
  humedadSuelo = 100 - humedadSuelo;                     //LO HAGO ASÍ PORQUE ME INTERESA EL PORCENTAJE DE HUMEDAD, NO DE SEQUEDAD.

  Serial.print("Humedad del suelo: ");
  Serial.print(humedadSuelo);
  Serial.println("%");

}

void RGB(){

 digitalWrite(rojo, HIGH);
 delay(500);
 digitalWrite(rojo, LOW);
 digitalWrite(verde, HIGH);
 delay(500);
 digitalWrite(verde, LOW);
 digitalWrite(azul, HIGH);
 delay(500);
 digitalWrite(azul, LOW);
 
}

Luego hablaremos del como presentas la información porque por ahora es un caos para mi gusto claro.

Veamos tu problema.
No parece estar en el código, lo que me hace pensar que tienes alguna falla en la conexion de tus sensores.
Puedes dibujarnos como estan conectados tus sensores? Tal vez en el proceso de hacerlo y al revisar, surja algo que no este bien.
Todo debe esta con GND al arduino, lo ideal es que sea siempre al mismo cable GND y no que vayas de sensor en sensor.
Verifica y muestra el esquema. No hace falta que uses un programa (si lo sabes hacer no hay problema). Con dibujarlo a mano alzada y luego le tomas una foto y la subes Segun Normas no hay problema.

Hola surbyte,

antes de escribir este hilo me aseguré de tener todos los sensores perfectamente conectados y con GND del Arduino en una misma línea de la protoboard donde conecto las correspondientes de cada sensor, pero nada. He seguido insistiendo y por hacerlo un poco más fácil la detección del problema he realizado el ejemplo que comentaba de la temperatura y luminosidad a parte, pero nuevamente me sigo encontrando con el mismo problema...

Descarto el título de este hilo como posible problema puesto que ahora no estoy haciendo uso de la LCD, únicamente lo estoy mostrando vía puerto serie.

Dejo el código:

void setup() {

  pinMode(A0, INPUT);
  pinMode(A3, INPUT);

  Serial.begin(9600);

}

void loop() {

    unsigned int lectura = analogRead(A0);   
    float voltaje = ((lectura * 5.0) / 1023) * 1000;  
    float temp = voltaje / 10; 
    
    unsigned int LDR = analogRead(A3);
    float porcentaje = (LDR * 100.0) / 1023;


    Serial.print("Temperatura: ");
    Serial.print(temp);
    Serial.println();
    Serial.print("Porcentaje: ");
    Serial.print(porcentaje);
    Serial.println("%");
   
    delay(1000);
}

No sé qué mas hacer, porque no tiene ninguna lógica lo que esta pasando...

que es esto?

  pinMode(A0, INPUT);
  pinMode(A3, INPUT);

para que defines algo como entrada digital y luego lo usas como Analógica
Elimina esas líneas

y en el código principal elimina todas estas

 pinMode(A2, INPUT);          //Leeré LDR.
 pinMode(A1, INPUT);          //Leeré el sensor de Humedad del Suelo.
 pinMode(A0, INPUT);          //Leeré el LM35  
 pinMode(sensorLl, INPUT);

Solo se definen si se usan como entradas digitales y luego un digitalRead no un analogRead

He eliminado esas líneas, pero no ha solucionado el problema comentado. En el programa no sé que más tocar.

En cuanto al conexionado, el LM35 lo conecto como dice el fabricante, y la LDR usando un divisor de tensión con resistencia pull-down (también he probado a ponerla pull-up y lo mismo), cosa que no tiene misterio... He cambiado la placa, componentes y protoboard y nada. Todo indica que debe estar en la programación, pero tampoco veo nada incoherente.

En el código general LDR esta en A2 y en este en A3, tengo cuidado!!

void setup() {

  Serial.begin(9600);

}

void loop() {

    float temp =  (500.0 * (float) analogRead(A0) / 1023.0;    // LM35 conectado a A0
    
    float porcentaje = (float) analogRead(A3) / 1023.0 * 100.0; // LDR conectado a A3

    Serial.print("Temperatura: ");
    Serial.print(temp);
    Serial.println();
    Serial.print("Porcentaje: ");
    Serial.print(porcentaje);
    Serial.println("%");
   
    delay(1000);
}

LM35 esquema

Esquema de la LDR pero la mueves al Ax que uses en este caso A3

Sí, sería por uno de los últimos cambios que hice. He probado a conectarlo a diferentes pines del convertidor AD por probar algo, vaya.

Lo que me has pasado es lo que yo tengo. Los 5 voltios del Arduino y GND del mismo para cada sensor, y su corresponiente pin de control conectado a A0 para el LM35 y a A5 para el LDR (última modificación que he hecho en el segundo programa y es como lo tengo actualmente)

El funcionamiento del código que has puesto entiendo que es exactamente igual al que yo puse.

Exactamente no pero prueba o bien prueba solo con el LM35 y olvida lo demas
Veamos de a poco que ocurre

Estando solo una variable no hay problema, bien sea la temperatura o la luminosidad. También probe eso.