Progress Bar on 16x2 LCD -Arduino Uno

Hi

I am trying to implement a progress/status bar on the 16x2 LCD for a defined period of time. Previously I did it with delay() function, which worked beautifully in displaying but due to its blocking nature, I cannot run any other code during that time.

Now, using the millis() function, I am trying to implement the same. The logic here that I am using is to break the time period in 16 equal segments and after a check at each segment the code displays the byte in the next display slot. but the display is not running for the same time.
I would be utterly grateful for any help that can make it work.

#include <LiquidCrystal.h>
const unsigned long period=5000;
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
byte smiley[8] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};
void setup()
{
  lcd.begin(16,2);
  Serial.begin(9600);
  int i=0;
    unsigned long start = millis();
    unsigned long track = millis();
    int segment=period/16;
    lcd.createChar(0, smiley);
    while((track-start)<= period)
    {  
         lcd.setCursor(0,0);
         track= millis();
         if((track-start)%segment==0)
         { 
           lcd.setCursor(i,1);
           lcd.write(byte(0));
           i++;
         }
   }
}

void loop()
{
}

When debugging conditional statements such as while and if it is useful to print the values being tested before testing them. Have you tried that and if so, are the values printed what you expect and are they printed when you expect to see them ?

Thanks for your prompt reply.

I introduced a Serial.print() command inside the 'if' loop to see the values. Every output is coming two times and hence the progress status bar is completing early than the time period(4 seconds in this case). However, I dont know why it is coming two times and how should i circumvent it?

 if((track-start)%segment==0)
         { 
           temp= track-start;
           Serial.println(temp);
           lcd.setCursor(i,1);
           lcd.write(byte(0));
           i++;
         }

Output:
0
0
250
250
500
500
750
750
1000
1000
1250
1250
1500
1500
1750
1750
2000
2000
2250
2250
2500
2500
2750
2750
3000
3000
3250
3250
3500
3500
3750
3750
4000
4000

int i = 0;
int steps = 16;
unsigned long total_time = 5000;
unsigned long step_time = total_time / steps;
unsigned long now = millis();
unsigned long start_time = now;
while (now - start_time < total_time)
{
   now = millis();
   if (now - start_time > step_time)
   {
      lcd.setCursor(i,1);
      lcd.write(byte(0));
      i++;
      step_time = total_time *  (i + 1) / steps;
   }
}

Hey pcbbc, that is a wonderul algorithm! Implemented it and worked.

Thanks everyone for their input on this

This thread ends here