Lcd arduino dejar fija una linea y cambiar otra

Hola a todos.... estimados, tengo una pantalla LCD 16x2 en la cual he logrado mostrar datos como temperatura, humedad, la hora, etc.... LO QUE ME GUSTARIA es poder hacer que en la primera linea se muestre la hora con hora, minutos, segundos (uso un delay de 1000), y en la segunda linea , me muestre la temperatura, humedad y otros datos, pero que cambie el mensaje cada (por ejemplo), cada 3 segundos... no se como hacerlo, porque si pongu un delay despues de darle el mensaje de la segunda linea, obvio el reloj de la primera linea aparecerá congelado por 3 segundos.... alguien sabe como hacer que 1 linea se cambie cada X tiempo... y la segunda cada Y tiempo???

aca el codigo completo que tengo.---

#include <Wire.h>    // incluye libreria para interfaz I2C
#include <RTClib.h>   // incluye libreria para el manejo del modulo RTC
#include <LiquidCrystal_I2C.h> // Libreria para LCD 
#include <DHT.h>    // importa la Librerias DHT
#include <DHT_U.h>

RTC_DS3231 rtc;     // crea objeto del tipo RTC_DS3231
bool evento_inicio = true;  // variable de control para inicio de evento con valor true
bool evento_fin = true;   // variable de control para finalizacion de evento con valor true

# define RELE 4     // constante RELE con valor 4 que corresponde a pin digital 3
        // donde se encuentra conectado el modulo de rele

int TRIG = 10; //DISTANCIA ULTRASONIDO
int ECHO = 9; 
int LED = 3;
int DURACION;
int DISTANCIA;


LiquidCrystal_I2C lcd(0x27, 16, 2); //PANTALLA LCD)


///DHT22

        int SENSOR = 2;     // pin DATA de DHT22 a pin digital 2
        int TEMPERATURA;
        int HUMEDAD;
        DHT dht(SENSOR, DHT22);   // creacion del objeto, cambiar segundo parametro        // por DHT11 si se utiliza en lugar del DHT22

///fin DHT22

void setup(){

// INICIAR DHT
      
      dht.begin();      // inicializacion de sensor

// inicializar LCD: 
      lcd.begin();
      lcd.backlight();
      lcd.clear();
      
     
//DISTANCIA ULTRASONIDO
      pinMode (TRIG, OUTPUT);
      pinMode (ECHO, INPUT);
      pinMode (LED, OUTPUT);
      Serial.begin(9600);

 pinMode(RELE, OUTPUT);   // pin 4 como salida RELOJ RTC

 if (! rtc.begin()) {       // si falla la inicializacion del modulo
 Serial.println("Modulo RTC no encontrado !");  // muestra mensaje de error
 while (1);         // bucle infinito que detiene ejecucion del programa
 }
//rtc.adjust(DateTime(__DATE__, __TIME__)); // funcion que permite establecer fecha y horario
            // al momento de la compilacion. Comentar esta linea
}

void loop(){

//DISTANCIA ULTRASONIDO
  digitalWrite(TRIG, HIGH);
  //delay(1);
  digitalWrite(TRIG, LOW);
  DURACION = pulseIn(ECHO, HIGH);
  DISTANCIA = DURACION / 5.82;
  Serial.println(DISTANCIA);


  if(DISTANCIA >= 40 ||  DISTANCIA < 0){
    digitalWrite(LED, HIGH);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("LVL:");         // caracter barra como separador
      lcd.print(DISTANCIA);       // funcion que obtiene el dia de la fecha completa
      lcd.print(" - FALTA");
  }
  else {
    digitalWrite(LED, LOW);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("LVL:");         // caracter barra como separador
      lcd.print(DISTANCIA);       // funcion que obtiene el dia de la fecha completa
      lcd.print(" - LLENO");
  }

 DateTime fecha = rtc.now();        // funcion que devuelve fecha y horario en formato
              // DateTime y asigna a variable fecha
 if ( fecha.hour() == 19 && fecha.minute() == 00 ){ // si hora = 14 y minutos = 30
    if ( evento_inicio == true ){     // si evento_inicio es verdadero
      digitalWrite(RELE, HIGH);       // activa modulo de rele con nivel alto
      Serial.println( "Rele encendido" );   // muestra texto en monitor serie
      evento_inicio = false;        // carga valor falso en variable de control
    }             // para evitar ingresar mas de una vez
  }

 if ( fecha.hour() == 19 && fecha.minute() == 01 ){ // si hora = 15 y minutos = 30
    if ( evento_fin == true ){        // si evento_fin es verdadero
      digitalWrite(RELE, LOW);        // desactiva modulo de rele con nivel bajo
      Serial.println( "Rele apagado" );     // muestra texto en monitor serie
      evento_fin = false;       // carga valor falso en variable de control
    }             // para evitar ingresar mas de una vez
  }

 Serial.print(fecha.day());       // funcion que obtiene el dia de la fecha completa
 Serial.print("/");         // caracter barra como separador
 Serial.print(fecha.month());       // funcion que obtiene el mes de la fecha completa
 Serial.print("/");         // caracter barra como separador
 Serial.print(fecha.year());        // funcion que obtiene el año de la fecha completa
 Serial.print(" ");         // caracter espacio en blanco como separador
 Serial.print(fecha.hour());        // funcion que obtiene la hora de la fecha completa
 Serial.print(":");         // caracter dos puntos como separador
 Serial.print(fecha.minute());        // funcion que obtiene los minutos de la fecha completa
 Serial.print(":");         // caracter dos puntos como separador
 Serial.println(fecha.second());      // funcion que obtiene los segundos de la fecha completa
 

  if ( fecha.hour() == 2 && fecha.minute() == 0 ){  // si hora = 2 y minutos = 0 restablece valores de
    evento_inicio = true;       // variables de control en verdadero
    evento_fin = true;
  }


// Imprimir en la primera línea del LCD 

      lcd.setCursor(0,0);    
      lcd.print(fecha.day());       // funcion que obtiene el dia de la fecha completa
      lcd.print("/");         // caracter barra como separador
      lcd.print(fecha.month());       // funcion que obtiene el mes de la fecha completa
      lcd.print("/");         // caracter barra como separador
      lcd.print(fecha.year());        // funcion que obtiene el año de la fecha completa
      lcd.print(" ");         // caracter espacio en blanco como separador
      lcd.print(fecha.hour());        // funcion que obtiene la hora de la fecha completa
      lcd.print(":");         // caracter dos puntos como separador
      lcd.print(fecha.minute());        // funcion que obtiene los minutos de la fecha completa
      //lcd.print(":");         // caracter dos puntos como separador
      //lcd.print(fecha.second());      // funcion que obtiene los segundos de la fecha completa
    
      delay(1000);           // demora de 1 segundo

//loop DHT 
  TEMPERATURA = dht.readTemperature();  // obtencion de valor de temperatura
  HUMEDAD = dht.readHumidity();   // obtencion de valor de humedad
  Serial.print("Temperatura: ");  // escritura en monitor serial de los valores
  Serial.print(TEMPERATURA);
  Serial.print(" Humedad: ");
  Serial.println(HUMEDAD);

      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Temperatura: ");
      lcd.print(TEMPERATURA);
      lcd.print((char)223);
      lcd.print("C");
      
      lcd.setCursor(0,1);
      lcd.print("Humedad: ");
      lcd.print(HUMEDAD);
      lcd.print(" %");
      
      delay(2500); 
  
//FIN loop DHT




}

Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

puedes usar algo como esto:

unsigned long ultimaVezHora;
unsigned long ultimaVezTemp;

const unsigned long intervaloHora = 1000;
const unsigned long intervaloTemp = 2500;

…

void loop() {

…

if (millis() - ultimaVezHora >= intervaloHora){
  ultimaVezHora = millis();
  actualizar display hora
}

if (millis() - ultimaVezTemp >= intervaloTemp){
  ultimaVezTemp = millis();
  actualizar display temp
  

Esta forma de hacerlo va a hacer que el loop se ejecute muy rápidamente, varios cientos de veces por segundo dependiendo de la distancia de tu objeto. Probablemente más de lo que necesitas o de lo que soporte el DHT.

Tu variable DISTANCIA nunca va a ser negativa ya que pulseIn no te regresará valores negativos y no es necesaria la comparación DISTANCIA<0

Verifica tu cálculo de la distancia con el sensor ultrasónico. Es posible que se requiera que el pulso de disparo en TRIG dure 10 microsegundos.

Vuelve a verificar si tu relevador se activa con HIGH o con LOW

1 Like

Gracias... lo probe pero no funciona.. como dices hace que se ejecute muy rapidamente .. tanto que algunas letras de la pantallas de ven borrosas y otras ni se leen...

Puedes postear el código modificado?

1 Like

asi.... `

#include <Wire.h>    // incluye libreria para interfaz I2C
#include <RTClib.h>   // incluye libreria para el manejo del modulo RTC
#include <LiquidCrystal_I2C.h> // Libreria para LCD 
#include <DHT.h>    // importa la Librerias DHT
#include <DHT_U.h>

RTC_DS3231 rtc;     // crea objeto del tipo RTC_DS3231
bool evento_inicio = true;  // variable de control para inicio de evento con valor true
bool evento_fin = true;   // variable de control para finalizacion de evento con valor true

# define RELE 4     // constante RELE con valor 4 que corresponde a pin digital 4
        // donde se encuentra conectado el modulo de rele

int TRIG = 10; //DISTANCIA ULTRASONIDO
int ECHO = 9; 
int LED = 3;
int DURACION;
int DISTANCIA;


LiquidCrystal_I2C lcd(0x27, 16, 2); //PANTALLA LCD)

unsigned long ultimaVezHora;
unsigned long ultimaVezTemp;

const unsigned long intervaloHora = 1000;
const unsigned long intervaloTemp = 2500;


///DHT22

        int SENSOR = 2;     // pin DATA de DHT22 a pin digital 2
        int TEMPERATURA;
        int HUMEDAD;
        DHT dht(SENSOR, DHT22);   // creacion del objeto, cambiar segundo parametro        // por DHT11 si se utiliza en lugar del DHT22

///fin DHT22

void setup(){

// INICIAR DHT
      
      dht.begin();      // inicializacion de sensor

// inicializar LCD: 
      lcd.begin();
      lcd.backlight();
      lcd.clear();
      
     
//DISTANCIA ULTRASONIDO
      pinMode (TRIG, OUTPUT);
      pinMode (ECHO, INPUT);
      pinMode (LED, OUTPUT);
      Serial.begin(9600);

 pinMode(RELE, OUTPUT);   // pin 4 como salida RELOJ RTC

 if (! rtc.begin()) {       // si falla la inicializacion del modulo
 Serial.println("Modulo RTC no encontrado !");  // muestra mensaje de error
 while (1);         // bucle infinito que detiene ejecucion del programa
 }
//rtc.adjust(DateTime(__DATE__, __TIME__)); // funcion que permite establecer fecha y horario
            // al momento de la compilacion. Comentar esta linea
}

void loop(){

//DISTANCIA ULTRASONIDO
  digitalWrite(TRIG, HIGH);
  delay(1);
  digitalWrite(TRIG, LOW);
  DURACION = pulseIn(ECHO, HIGH);
  DISTANCIA = DURACION / 5.82;
  Serial.println(DISTANCIA);


  if(DISTANCIA >= 40){
    digitalWrite(LED, HIGH);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("LVL:");         // caracter barra como separador
      lcd.print(DISTANCIA);       // funcion que obtiene el dia de la fecha completa
      lcd.print(" - FALTA");
  }
  else {
    digitalWrite(LED, LOW);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("LVL:");         // caracter barra como separador
      lcd.print(DISTANCIA);       // funcion que obtiene el dia de la fecha completa
      lcd.print(" - LLENO");
  }

 DateTime fecha = rtc.now();        // funcion que devuelve fecha y horario en formato
              // DateTime y asigna a variable fecha
 if ( fecha.hour() == 19 && fecha.minute() == 55 ){ // si hora = 14 y minutos = 30
    if ( evento_inicio == true ){     // si evento_inicio es verdadero
      digitalWrite(RELE, HIGH);       // activa modulo de rele con nivel alto
      Serial.println( "Rele encendido" );   // muestra texto en monitor serie
      evento_inicio = false;        // carga valor falso en variable de control
    }             // para evitar ingresar mas de una vez
  }

 if ( fecha.hour() == 19 && fecha.minute() == 56 ){ // si hora = 15 y minutos = 30
    if ( evento_fin == true ){        // si evento_fin es verdadero
      digitalWrite(RELE, LOW);        // desactiva modulo de rele con nivel bajo
      Serial.println( "Rele apagado" );     // muestra texto en monitor serie
      evento_fin = false;       // carga valor falso en variable de control
    }             // para evitar ingresar mas de una vez
  }

 Serial.print(fecha.day());       // funcion que obtiene el dia de la fecha completa
 Serial.print("/");         // caracter barra como separador
 Serial.print(fecha.month());       // funcion que obtiene el mes de la fecha completa
 Serial.print("/");         // caracter barra como separador
 Serial.print(fecha.year());        // funcion que obtiene el año de la fecha completa
 Serial.print(" ");         // caracter espacio en blanco como separador
 Serial.print(fecha.hour());        // funcion que obtiene la hora de la fecha completa
 Serial.print(":");         // caracter dos puntos como separador
 Serial.print(fecha.minute());        // funcion que obtiene los minutos de la fecha completa
 Serial.print(":");         // caracter dos puntos como separador
 Serial.println(fecha.second());      // funcion que obtiene los segundos de la fecha completa
 

  if ( fecha.hour() == 2 && fecha.minute() == 0 ){  // si hora = 2 y minutos = 0 restablece valores de
    evento_inicio = true;       // variables de control en verdadero
    evento_fin = true;
  }


// Imprimir en la primera línea del LCD 
if (millis() - ultimaVezHora >= intervaloHora){
  ultimaVezHora = millis();

      lcd.setCursor(0,0);    
      lcd.print(fecha.day());       // funcion que obtiene el dia de la fecha completa
      lcd.print("/");         // caracter barra como separador
      lcd.print(fecha.month());       // funcion que obtiene el mes de la fecha completa
      lcd.print("/");         // caracter barra como separador
      lcd.print(fecha.year());        // funcion que obtiene el año de la fecha completa
      lcd.print(" ");         // caracter espacio en blanco como separador
      lcd.print(fecha.hour());        // funcion que obtiene la hora de la fecha completa
      lcd.print(":");         // caracter dos puntos como separador
      lcd.print(fecha.minute());        // funcion que obtiene los minutos de la fecha completa
      lcd.print(":");         // caracter dos puntos como separador
      lcd.print(fecha.second());      // funcion que obtiene los segundos de la fecha completa
    
}

//loop DHT 
  TEMPERATURA = dht.readTemperature();  // obtencion de valor de temperatura
  HUMEDAD = dht.readHumidity();   // obtencion de valor de humedad
  Serial.print("Temperatura: ");  // escritura en monitor serial de los valores
  Serial.print(TEMPERATURA);
  Serial.print(" Humedad: ");
  Serial.println(HUMEDAD);

if (millis() - ultimaVezTemp >= intervaloTemp){
  ultimaVezTemp = millis();
  
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("T: ");
      lcd.print(TEMPERATURA);
      lcd.print((char)223);
      lcd.print("C");
      
      lcd.print(" H: ");
      lcd.print(HUMEDAD);
      lcd.print(" %");
      
}

//FIN loop DHT




}`

El programa actualiza correctamente la hora en los intervalos previstos.

El problema seguramente es que la distancia se actualiza con demasiada frecuencia. Eso hace que el display no se lea correctamente. El sketch está sobreponiendo la distancia con la temperatura, ya que pones ambos en el mismo renglón. Prueba a poner la temperatura en el mismo renglón que la hora.

Hay que considerar que el retardo que pulseIn causa es proporcional a la distancia del objeto. SI la distancia es corta, este tiempo también será corto. Estamos hablando de que el pulso ultrasónico se toma unos 58 microsegundos/cm en ser detectado. De modo que el tiempo de ejecución del loop() varía, pero es muy corto (salvo cuando no se detecta ningún objeto).

¿Cada cuándo tienes que actualizar el LCD? Puedes usar la misma técnica de control de tiempo para que la distancia se actualice a intervalos de unos 100ms y ajustar este tiempo para encontrar el punto justo.

¿Estás midiendo distancias del orden de 40 milímetros?

1 Like

gracias estimado.... por ahi va funcionando bastante bien.... el LCD se deberia actuallizar cada 5 segundos.... lo de la primera linea cada segundo es para que el reloj se muestre sin problemas ...aca dejo el codigo como quedo... SOLO UNA CONSULTA MAS.... COMO se puede hacer para modificar el formato del año en la fecha?... quiero que en vez de que aparezca el año completo (ej: 2022), aparezcan solo los ultimos 2 digitos (ej: 22)....
gracias profe...

#include <Wire.h>    // incluye libreria para interfaz I2C
#include <RTClib.h>   // incluye libreria para el manejo del modulo RTC
#include <LiquidCrystal_I2C.h> // Libreria para LCD 
#include <DHT.h>    // importa la Librerias DHT
#include <DHT_U.h>

RTC_DS3231 rtc;     // crea objeto del tipo RTC_DS3231
bool evento_inicio = true;  // variable de control para inicio de evento con valor true
bool evento_fin = true;   // variable de control para finalizacion de evento con valor true

# define RELE 4     // constante RELE con valor 4 que corresponde a pin digital 3
        // donde se encuentra conectado el modulo de rele

int TRIG = 10; //DISTANCIA ULTRASONIDO
int ECHO = 9; 
int LED = 3;
int DURACION;
int DISTANCIA;


LiquidCrystal_I2C lcd(0x27, 16, 2); //PANTALLA LCD)

unsigned long ultimaVezHora;
unsigned long ultimaVezTemp;

const unsigned long intervaloHora = 1000;
const unsigned long intervaloTemp = 5000;


///DHT22

        int SENSOR = 2;     // pin DATA de DHT22 a pin digital 2
        int TEMPERATURA;
        int HUMEDAD;
        DHT dht(SENSOR, DHT22);   // creacion del objeto, cambiar segundo parametro        // por DHT11 si se utiliza en lugar del DHT22

///fin DHT22

void setup(){

// INICIAR DHT
      
      dht.begin();      // inicializacion de sensor

// inicializar LCD: 
      lcd.begin();
      lcd.backlight();
      lcd.clear();
      
     
//DISTANCIA ULTRASONIDO
      pinMode (TRIG, OUTPUT);
      pinMode (ECHO, INPUT);
      pinMode (LED, OUTPUT);
      Serial.begin(9600);

 pinMode(RELE, OUTPUT);   // pin 4 como salida RELOJ RTC

 if (! rtc.begin()) {       // si falla la inicializacion del modulo
 Serial.println("Modulo RTC no encontrado !");  // muestra mensaje de error
 while (1);         // bucle infinito que detiene ejecucion del programa
 }
//rtc.adjust(DateTime(__DATE__, __TIME__)); // funcion que permite establecer fecha y horario
            // al momento de la compilacion. Comentar esta linea
}

void loop(){

//DISTANCIA ULTRASONIDO
  digitalWrite(TRIG, HIGH);
  delay(1000);
  digitalWrite(TRIG, LOW);
  DURACION = pulseIn(ECHO, HIGH);
  DISTANCIA = DURACION / 5.82;
  Serial.println(DISTANCIA);


  if(DISTANCIA >= 40 ||  DISTANCIA < 0){
    digitalWrite(LED, HIGH);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("LVL:");         // caracter barra como separador
      lcd.print(DISTANCIA);       // funcion que obtiene el dia de la fecha completa
      lcd.print(" - FALTA");
  }
  else {
    digitalWrite(LED, LOW);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("LVL:");         // caracter barra como separador
      lcd.print(DISTANCIA);       // funcion que obtiene el dia de la fecha completa
      lcd.print(" - LLENO");
  }

 DateTime fecha = rtc.now();        // funcion que devuelve fecha y horario en formato
              // DateTime y asigna a variable fecha
 if ( fecha.hour() == 19 && fecha.minute() == 00 ){ // si hora = 14 y minutos = 30
    if ( evento_inicio == true ){     // si evento_inicio es verdadero
      digitalWrite(RELE, HIGH);       // activa modulo de rele con nivel alto
      Serial.println( "Rele encendido" );   // muestra texto en monitor serie
      evento_inicio = false;        // carga valor falso en variable de control
    }             // para evitar ingresar mas de una vez
  }

 if ( fecha.hour() == 19 && fecha.minute() == 01 ){ // si hora = 15 y minutos = 30
    if ( evento_fin == true ){        // si evento_fin es verdadero
      digitalWrite(RELE, LOW);        // desactiva modulo de rele con nivel bajo
      Serial.println( "Rele apagado" );     // muestra texto en monitor serie
      evento_fin = false;       // carga valor falso en variable de control
    }             // para evitar ingresar mas de una vez
  }

 Serial.print(fecha.day());       // funcion que obtiene el dia de la fecha completa
 Serial.print("/");         // caracter barra como separador
 Serial.print(fecha.month());       // funcion que obtiene el mes de la fecha completa
 Serial.print("/");         // caracter barra como separador
 Serial.print(fecha.year());        // funcion que obtiene el año de la fecha completa
 Serial.print(" ");         // caracter espacio en blanco como separador
 Serial.print(fecha.hour());        // funcion que obtiene la hora de la fecha completa
 Serial.print(":");         // caracter dos puntos como separador
 Serial.print(fecha.minute());        // funcion que obtiene los minutos de la fecha completa
 Serial.print(":");         // caracter dos puntos como separador
 Serial.println(fecha.second());      // funcion que obtiene los segundos de la fecha completa
 

  if ( fecha.hour() == 2 && fecha.minute() == 0 ){  // si hora = 2 y minutos = 0 restablece valores de
    evento_inicio = true;       // variables de control en verdadero
    evento_fin = true;
  }


// Imprimir en la primera línea del LCD 
if (millis() - ultimaVezHora >= intervaloHora){
  ultimaVezHora = millis();

      lcd.setCursor(0,0);    
      lcd.print(fecha.day());       // funcion que obtiene el dia de la fecha completa
      lcd.print("/");         // caracter barra como separador
      lcd.print(fecha.month());       // funcion que obtiene el mes de la fecha completa
      lcd.print("/");         // caracter barra como separador
      lcd.print(fecha.year());        // funcion que obtiene el año de la fecha completa
      lcd.print(" ");         // caracter espacio en blanco como separador
      lcd.print(fecha.hour());        // funcion que obtiene la hora de la fecha completa
      lcd.print(":");         // caracter dos puntos como separador
      lcd.print(fecha.minute());        // funcion que obtiene los minutos de la fecha completa
      lcd.print(":");         // caracter dos puntos como separador
      lcd.print(fecha.second());      // funcion que obtiene los segundos de la fecha completa

}

//loop DHT 
  TEMPERATURA = dht.readTemperature();  // obtencion de valor de temperatura
  HUMEDAD = dht.readHumidity();   // obtencion de valor de humedad
  Serial.print("Temperatura: ");  // escritura en monitor serial de los valores
  Serial.print(TEMPERATURA);
  Serial.print(" Humedad: ");
  Serial.println(HUMEDAD);

if (millis() - ultimaVezTemp >= intervaloTemp){
  ultimaVezTemp = millis();
  

      lcd.setCursor(0,1);
      lcd.print("T:");
      lcd.print(TEMPERATURA);
      lcd.print((char)223);
      lcd.print("C");
     
      lcd.print(" H:");
      lcd.print(HUMEDAD);
      lcd.print("%   ");
    
}
  
//FIN loop DHT




}

Utiliza

https://www.arduino.cc/reference/en/language/structure/arithmetic-operators/remainder/

1 Like

Gracias profe!! :pray: todo perfecto

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