Teemporizacion en medida con ultrasonidos

Hola, lo que pretendo en esta ocasion es medir una distancia con un sensor ultrasonidos y presentarla en un lcd 16x2 i2c. Pues bien, tengo k pulsar un boton y que empiece a medir, pero que solo mida una vez y a los 5 segundos se apague la pantalla y posteriormente regrese al estado inicial para volver a medir si se desea

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Ultrasonic.h>

Ultrasonic ultrasonic(9,8);
LiquidCrystal_I2C lcd(0x27,16,2);

int tN = 0, tV = 0;
volatile int estado = 0;
int Boton = 2;

void setup() 
{
  Serial.begin(9600);
  pinMode(Boton, INPUT_PULLUP);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("Medidor");
  attachInterrupt(0,cambio,FALLING);
}

void loop() 
{
  if(estado == 1)
  {
    tN = millis();
      
    if(tN > tV + 5000)
    {
      lcd.backlight();
      lcd.clear();
      lcd.print(ultrasonic.Ranging(CM));
      tV = tN;      
    }
    Serial.println(ultrasonic.Ranging(CM));
  }
}

void cambio()
{
  estado = 1;
}

he consegido por el momento que cada medida se realice durante los 5 seg(evito delay por si se tuviesen que realizar mas funciones). Pero a los 5 segundos no se me ocurre manera alguna de hacer para que se apague la pantalla o no muestre nada
Haber si me podeis hechar un cable, ultimamente con lo que pregunto y me contestais y busco, he aprendido bastante. Gracias a todos

Esta sin probar y seguro que hay formas mas elegantes ,pero es una idea..

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Ultrasonic.h>

Ultrasonic ultrasonic(9,8);
LiquidCrystal_I2C lcd(0x27,16,2);

unsigned long apagar = 0;
volatile bool medir = false;
bool encendida = false;
#define BOTON 2
#define INTERVALO 5000

void setup(){
  Serial.begin(9600);
  pinMode( BOTON , INPUT_PULLUP);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("Medidor");
  attachInterrupt(0,cambio,FALLING);
}

void loop(){
  if(medir){
      lcd.backlight();
      lcd.clear();
      lcd.print(ultrasonic.Ranging(CM));
      Serial.println(ultrasonic.Ranging(CM));
      medir = false;
      encendida = true;
      apagar = millis();     
  }
  if(encendida){
    if(millis() - apagar > INTERVALO){
      lcd.clear();
      // apagas retroiluminacion lcd.noBacklight() ?? no se si es asi
      encendida = false;
    }
  }
}
void cambio(){
  medir = true;
}

Que hace la función cambio?

Una variable global es volatile. Hay alguna ISR?

Variables que almacenan tiempo deben ser unsigned long. Si son de tipo int (sin el unsigned), puede haber problemas después de 32 segundos de ejecución.

No hay ISR (interrupcion). Lo que pasa que estos códigos son copiados y vienen de otras situaciones y arrastran defectos como este volatile.
consultando la web de fmalpartida ya que creo es la librería lcd que se esta usando, los códigos siempre aluden a un pin destinado al control del backlight

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

LiquidCrystal_I2C lcd(0x38);  // Set the LCD I2C address

#define BACKLIGHT_PIN     13

void setup()
{
  // Switch on the backlight
  pinMode ( BACKLIGHT_PIN, OUTPUT );
  digitalWrite ( BACKLIGHT_PIN, HIGH );
  
  lcd.begin(16,2);               // initialize the lcd 

  lcd.home ();                   // go home
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" WORLD!  ");      
}

void loop()
{

}

En este caso el pin 13 pero hay que revisar tu hardware.

Por cierto si no tienes control de backlight no puedes apagar el display. Solo hacer un lcd.clear() y te quedará iluminado y sin datos.

Lo de volatile int es para que deje modificar la interrupcion el valor de estado. La libreria que utilizo permite lcd.noBacklight() aparte de como bien decis el lcd.clear(). El caso es que este 5segundos mostrando una medida y se apague al pasar esos 5 segundos. Tendria sentido hacerlo con un bucle do while??

do
{
    tN = millis();
      
    if(tN > tV + 5000)
    {
      lcd.backlight();
      lcd.clear();
      lcd.print(ultrasonic.Ranging(CM));  
      tV = tN
}

while (tV == tN) //--> de esta forma solo se realizaria la accion una vez no??

// y ya despues apagar el display

Es lo que se me ocurre, no se si tiene logica

Lo de volatile int es para que deje modificar la interrupcion el valor de estado.

Que interrupción?
Tu código no tiene interrupción.

surbyte:
Que interrupción?
Tu código no tiene interrupción.

attachInterrupt no??

Carlitos1991:
Lo de volatile int es para que deje modificar la interrupcion el valor de estado. La libreria que utilizo permite lcd.noBacklight() aparte de como bien decis el lcd.clear(). El caso es que este 5segundos mostrando una medida y se apague al pasar esos 5 segundos. Tendria sentido hacerlo con un bucle do while??

do

{
    tN = millis();
     
    if(tN > tV + 5000)
    {
      lcd.backlight();
      lcd.clear();
      lcd.print(ultrasonic.Ranging(CM)); 
      tV = tN
}

while (tV == tN) //--> de esta forma solo se realizaria la accion una vez no??

// y ya despues apagar el display




Es lo que se me ocurre, no se si tiene logica

pero has probado lo que te he puesto arriba?

jose:
pero has probado lo que te he puesto arriba?

Esque eso

jose:
pero has probado lo que te he puesto arriba?

Si, va perfectamente, el problema es que eso de bool y true/false no lo manejo especialmente bien, y por eso busco esta forma de hacerlo. Guardare los 2, el que me has hecho tu, y haber si el que yo estoy intentando hacer sale tambien, me gustaria poder sacarlo ya que he empezado.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Ultrasonic.h>

Ultrasonic ultrasonic(9,8);
LiquidCrystal_I2C lcd(0x27,16,2);

int tN = 0, tV = 0;
volatile int estado = 0;
int Boton = 2;

void setup() 
{
  Serial.begin(9600);
  pinMode(Boton, INPUT_PULLUP);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("Medidor");
  attachInterrupt(0,cambio,FALLING);
}

void loop() 
{
  
  if(estado == 1)
{
    do
    {
      tN = millis();
        
      if(tN > tV + 5000)
      {
        lcd.backlight();
        lcd.clear();
        lcd.print(ultrasonic.Ranging(CM));
        tV = tN;      
        lcd.clear();
      }
      
      Serial.println(ultrasonic.Ranging(CM));
    }  
  while (tV == tN);
  lcd.noBacklight();
}

}

void cambio()
{
  estado = 1;
}

Gracias a todos

Si no necesitas que el programa haga algo más mientras muestra los resultados, entonces ahí sí tranquilamente se puede usar un delay.

No vi la interrupción me debo haber confundido con el código que yo mismo puse. Sorry.