Final Delay at Countdown using millis()

Hello :),

I'm making an countdown inside of a lot of code, and I have suspicious about the code is slowing down the millis() count because isn't processed in real-time and that's add milliseconds to the final result and that means few seconds after few minutes added to the final result.

How can its possible avoid this issue?

Thank you!

PS, code attached just in case:

// Incluir libreria
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
LiquidCrystal lcd2(8, 9, 4, 5, 6, 7);

int menuposiciones = 3;
int showed = 0;
int cancelledsauna = 0;
int timer = 2; long seconds = 0; long mlscnds = 0; int converted = 0;
int luces = 0;
int sauna = 0;

int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

int read_LCD_buttons()
{
 adc_key_in = analogRead(0);
 if (adc_key_in > 1000) return btnNONE;
 if (adc_key_in < 50)   return btnRIGHT;  
 if (adc_key_in < 250)  return btnUP; 
 if (adc_key_in < 450)  return btnDOWN; 
 if (adc_key_in < 650)  return btnLEFT; 
 if (adc_key_in < 850)  return btnSELECT;  

 return btnNONE;
 
}

unsigned long start, finished, elapsed;
unsigned long cd_time_start, cd_time_finished, cd_time_elapsed;

void setup() 
{

  pinMode(13, OUTPUT); /* Relay 4 */ // Probar 
  digitalWrite(13, HIGH); // Apagar

  pinMode(12, OUTPUT); /* Relay 3 */ // Probar 
  digitalWrite(12, HIGH); // Apagar

  lcd.begin(16, 2);
  lcd2.begin(16, 2);
  lcd.cursor();
  lcd2.cursor();
  
}

void loop() 
{

  //cd_time_start = millis();

  // Leer botones LCD
  lcd_key = read_LCD_buttons();

  // Si el sauna fué cancelado avisar una sola vez y luego volver al menu principal
  if( cancelledsauna == 1 )
  {
          lcd.setCursor(0,0);
          lcd.print("    CANCELLED   ");
          lcd.noCursor();

          lcd2.setCursor(0,1);
          lcd2.print("     Wait...    ");
          lcd2.noCursor();

          cancelledsauna = 0;
          menuposiciones = -1;
          
          delay(2000);
  }

  // Sauna apagado
  if( sauna == 0 )
  {
      
      if( menuposiciones == 0 ) {
  
          showed++;
          // PANTALLA: INFO
          lcd.setCursor(0,0);
          lcd.print(" PRESS -- OK -- ");
          lcd.noCursor();
          lcd2.setCursor(0,1);
          lcd2.print("    TO START    ");
          lcd2.noCursor();
      
      }else if( menuposiciones == 1 ) {
  
          showed++;
          // PANTALLA: LUCES
          lcd.setCursor(0,0);
          lcd.print("   L I G H T S  ");
          lcd.noCursor();
        
          // Flechas arriba abajo
          lcd2.setCursor(0,1);
          lcd2.print("on   v off      ");
          lcd2.setCursor(3,1);
          lcd2.write(0b01011110);
          lcd2.noCursor();
      
          if ( lcd_key == btnLEFT)
          {
            digitalWrite(13, LOW); // Encendido
          }
          if ( lcd_key == btnDOWN)
          {
            digitalWrite(13, HIGH); // Apagado
          }
      
      }else if( menuposiciones == 2 ) {
      
          showed++;
          // PANTALLA: TIMER
          lcd.setCursor(0,0);
          lcd.print("T I M E R   ");
          lcd.noCursor();
        
          // Flechas arriba abajo
          lcd2.setCursor(0,1);
          lcd2.print("Up   v Down     ");
          lcd2.setCursor(3,1);
          lcd2.write(0b01011110);
          lcd2.noCursor();
          
      }else if( menuposiciones == 3 ) {
      
          showed++;
          // PANTALLA: SAUNA
          lcd.setCursor(0,0);
          lcd.print("    S A U N A   ");
          lcd.noCursor();
        
          // Flechas arriba abajo
          lcd2.setCursor(0,1);
          lcd2.print("on   v off     '");
          lcd2.setCursor(3,1);
          lcd2.write(0b01011110);
          lcd2.noCursor();
  
          if( timer > 1 )
          {
            lcd2.setCursor(12,1);
            lcd2.print(timer);
            lcd2.noCursor();
          }else{
            lcd2.setCursor(12,1);
            lcd2.print("Inf.");
            lcd2.noCursor();          
          }
  
          if ( lcd_key == btnLEFT)
          {
            digitalWrite(12, LOW); // Encendido
            sauna = 1;
          }
          if ( lcd_key == btnDOWN)
          {
            digitalWrite(12, HIGH); // Apagado
            sauna = 0;
          }
        
      }else if( menuposiciones == 4 ) {
      
          showed++;
          // PANTALLA: INFO
          lcd.setCursor(0,0);
          lcd.print(" VERSION: 0.3.7  ");
          lcd.noCursor();
          lcd2.setCursor(0,1);
          lcd2.print("                ");
          lcd2.noCursor();
      
      }
        
      // Posición Timer ?
      if( menuposiciones == 2 ) 
      {
  
          lcd.setCursor(0,0);
          lcd.print("T I M E R      '");
  
          // Mínimo cero
          if( timer > 1 )
          {
            lcd.setCursor(12,0);
            lcd.print(timer);
          }else{
            // Marcar como infinito
            lcd.setCursor(12,0);
            lcd.print("Inf.");
          }
          
  
        // Contról timer
        if (lcd_key == btnLEFT)
        {
          // Máximo 120
          if( timer < 120 )
          {
            // Subir tiempo
            timer++;
            lcd.setCursor(0,0);
            lcd.print("T I M E R      '");
            lcd.setCursor(12,0);
            lcd.print(timer);
            delay(100);
          }
        }
        
        if (lcd_key == btnDOWN)
        {
          // Mínimo cero
          if( timer > 1 )
          {
            // Bajar tiempo
            timer--;
            lcd.setCursor(0,0);
            lcd.print("T I M E R      '");
            lcd.setCursor(12,0);
            lcd.print(timer);
            delay(100);
          }else{
            // Marcar como infinito
            lcd.setCursor(0,0);
            lcd.print("T I M E R      '");
            lcd.setCursor(12,0);
            lcd.print("Inf.");
          }
        }
        
      }
  
      
      if( showed != 0 )
      {
          if (lcd_key == btnRIGHT)
          {
            
            // Precionó Select
            delay(500);
            showed--;
            // Es pantalla de info?
            if( menuposiciones == 4 )
            {
              // Si
              menuposiciones = 1;
            }else{
              // No
              menuposiciones++;
            }
          
          }
      }
  
  }else{
      // Sauna encendido

        // Convertir minutos en segundos si es que no estaba definido
        if( converted == 0 )
        {
            // No estaba definido
            // Convertir minutos a segundos
            seconds = timer * 60;
            //seconds = 30;
            mlscnds = seconds * 1000;
            // Eviar que convierta de nuevo
            converted++;
        }

        // Cuenta
        start=millis();
        delay(1000);
        finished=millis();
        elapsed=finished-start;
        // Calcular milisegundos restantes
        //seconds = seconds - 1;
        mlscnds = mlscnds - elapsed;

        // Mostrar remaining (restante)
        lcd.setCursor(0,0);
        lcd.print("Remaining:    ' ");
        lcd.noCursor();

        // Mostrar Milisegundos Restantes
        lcd2.setCursor(11,0); // Ocultar luego (pasar a minutos)
        lcd2.print(mlscnds / 1000); // Ocultar luego (pasar a minutos)
        lcd2.noCursor(); // Ocultar luego (pasar a minutos)

        /*
        // Mostrar Milisegundos Restantes
        lcd2.setCursor(0,0); // Ocultar luego (pasar a minutos)
        lcd2.print(millis()); // Ocultar luego (pasar a minutos)
        lcd2.noCursor(); // Ocultar luego (pasar a minutos)
        */


        // Show temperature
        lcd2.setCursor(0,1);
        lcd2.print("Set v:50  Now30 ");
        lcd2.setCursor(3,1);
        lcd2.write(0b01011110);

        lcd2.setCursor(8,1);
        lcd2.write(0b011011111);

        lcd2.setCursor(15,1);
        lcd2.write(0b011011111);
        
        lcd2.noCursor();

        // Actualizar Timer Countdown
        if( mlscnds < 1  )
        {
          digitalWrite(12, HIGH); // Apagar
          converted--;
          sauna = 0;
        }

        // Cancelar programa
          if (lcd_key == btnRIGHT)
          {

            digitalWrite(12, HIGH); // Apagar
            menuposiciones = 0;
            cancelledsauna = 1;
            converted--;
            sauna = 0;
          
          }
  
  }
  
}
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
LiquidCrystal lcd2(8, 9, 4, 5, 6, 7);

Two displays on one set of pins?

It does not make sense to use millis() AND delay() in the same code. Get rid of one of them.

PaulS:

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

LiquidCrystal lcd2(8, 9, 4, 5, 6, 7);



Two displays on one set of pins?

It does not make sense to use millis() AND delay() in the same code. Get rid of one of them.

If I can't, how can I delay the loop and measure the time?

Thank you PaulS!

Why you have 2 LCD's? You have a section in Spanish if is easier to you.

The demo Several Things at a Time illustrates the use of millis() to manage timing.

...R

dezagus:
and that means few seconds after few minutes added to the final result.

The arduino resonator has an accuracy of something like ±5%. A few seconds per minute is pretty much what you'd expect.

If you need accuracy, then you need your arduino to talk to a Real Time Clock (RTC).