Millis timing issue drawing bar graph

Hello. I have a tft.display and am trying to make a download progress bar using seven rectangles. Each rectangle lights up in sequence being a White colour for 500 millis then changing colour to green. Each rectangle when green will stay Green untill ALL seven rectangles are green.
Now using a delay this task is a rather simple affair but millis is proving a tough nut.

The 1st rectangle turns White and the timer is set to eventInterval = 1500;

Then the 1st rectangle turns Green and the timer is set to eventInterval = 2000;
And so forth all the other Rectangles

currentTime_1 = millis();
  /* This is the event */
  if (currentTime_1 - previousTime_1 >= eventInterval_1) {        
   /* Update the timing for the next time around */
       
//delay(500);
tft.fillRect(10, 165, 10, 30, TFT_WHITE); //Bars #1
  previousTime_1 = currentTime_1;
  }  
currentTime_2 = millis();
  /* This is the event */
  if (currentTime_2 - previousTime_2 >= eventInterval_2) {        
   /* Update the timing for the next time around */
   
//delay(500);
tft.fillRect(10, 165, 10, 30, TFT_GREEN); //Bars #1
  previousTime_2 = currentTime_2;
  }

Things start getting wonky when Rectangle Four gets drawn because Rectangle One and then number Two start turning White then Green again.
I've tried many ways to come up with a solution but to no avail.

Any tips appreciated.

If you show complete code, we could probably identify which variable has been misdeclared, probably as an int rather than a long int of some form.

The code is huge. That snippit is for One Rectangle and there are Seven.
The 1st Rectangle turns White after 1500 millis then turns Green 500 millis later.
Problem is it turns back to White 1500 millis later.
Do I need to try a hack like setting

previousTime_1 = currentTime_1;

every 1000 millis through my code or is there an easier work around for having a seperate on/off time for something like this?

Thanks

What is the final goal?

Smelling x-y.

2 Likes

I truly hope you're joking. You want us to debug problems with your code, given a tiny slice of it, that may not even contain an error?
I'm out. Have fun!

2 Likes

Hello mungusfungus

I assume that you have written the programme by yourself, then it is quite easy to find the error.

There's a trick to figuring out why something isn't working:

Use a logic analyzer to see what happens.
Put Serial.print statements at various places in the code as diagnostic prints to see the values of variables, especially ones that control the motors, and determine whether they meet your expectations.

Have a nice day and enjoy coding in C++.

1 Like

after some time expired he will write "i found answer" and mark own post as solution

1 Like

Hello. Many of the Blink without delay examples I've read seem to have a separate currentTime/previousTime and eventInterval for each event and I've taken that on as my go to way of using millis.
A guy has got to start somewhere :slight_smile:

Here is the code with just 5 Bars animated. It's very amateur as I'm a hobbyist who just loves making graphics on cheap tft displays using esp32's :blush:


#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

const unsigned long eventInterval = 0;
const unsigned long eventInterval_1 = 1500;  //Used for Bar #1 White
const unsigned long eventInterval_2 = 2000;  //Used for Bar #1 Green
const unsigned long eventInterval_3 = 2500;  //Used for Bar #2 White
const unsigned long eventInterval_4 = 3000;  //Used for Bar #2 Green
const unsigned long eventInterval_5 = 3500;  //Used for Bar #3 White
const unsigned long eventInterval_6 = 4000;  //Used for Bar #3 Green
const unsigned long eventInterval_7 = 4500;  //Used for Bars
const unsigned long eventInterval_8 = 5000;  //Used for Bars
const unsigned long eventInterval_9 = 5500;  //Used for Bars
const unsigned long eventInterval_10 = 6000;  //Used for Bars

unsigned long previousTime = 0;
unsigned long previousTime_1 = 0;
unsigned long previousTime_2 = 0;
unsigned long previousTime_3 = 0;
unsigned long previousTime_4 = 0;
unsigned long previousTime_5 = 0;
unsigned long previousTime_6 = 0;
unsigned long previousTime_7 = 0;
unsigned long previousTime_8 = 0;
unsigned long previousTime_9 = 0;
unsigned long previousTime_10 = 0;

unsigned long currentTime = millis();
unsigned long currentTime_1 = millis();
unsigned long currentTime_2 = millis();
unsigned long currentTime_3 = millis();
unsigned long currentTime_4 = millis();
unsigned long currentTime_5 = millis();
unsigned long currentTime_6 = millis();
unsigned long currentTime_7 = millis();
unsigned long currentTime_8 = millis();
unsigned long currentTime_9 = millis();
unsigned long currentTime_10 = millis();


void setup() {
tft.init();
tft.setRotation(1);
Serial.begin(115200);
tft.fillScreen(TFT_BLACK);

}


void downloading(){
  currentTime_1 = millis();
  /* This is the event */
  if (currentTime_1 - previousTime_1 >= eventInterval_1) {        
tft.fillRect(10, 165, 10, 30, TFT_WHITE); //Bars #1
  /* Update the timing for the next time around */
  previousTime_1 = currentTime_1;
  }
  currentTime_2 = millis();
  /* This is the event */
  if (currentTime_2 - previousTime_2 >= eventInterval_2) {        
tft.fillRect(10, 165, 10, 30, TFT_GREEN); //Bars #1
  /* Update the timing for the next time around */
  previousTime_2 = currentTime_2;
  }
currentTime_3 = millis();
  /* This is the event */
  if (currentTime_3 - previousTime_3 >= eventInterval_3) {        
tft.fillRect(25, 165, 15, 30, TFT_WHITE); //Bars #2
  /* Update the timing for the next time around */
  previousTime_3 = currentTime_3;
  }
currentTime_4 = millis();
  /* This is the event */
  if (currentTime_4 - previousTime_4 >= eventInterval_4) {        
tft.fillRect(25, 165, 15, 30, TFT_GREEN); //Bars #2
  /* Update the timing for the next time around */
  previousTime_4 = currentTime_4;
  }
currentTime_5 = millis();  
  /* This is the event */
  if (currentTime_5 - previousTime_5 >= eventInterval_5) {        
tft.fillRect(45, 165, 20, 30, TFT_WHITE); //Bars #3
  /* Update the timing for the next time around */
  previousTime_5 = currentTime_5;
  }
currentTime_6 = millis();
  /* This is the event */
  if (currentTime_6 - previousTime_6 >= eventInterval_6) {        
tft.fillRect(45, 165, 20, 30, TFT_GREEN); //Bars #3
  /* Update the timing for the next time around */
  previousTime_6 = currentTime_6;
  }
currentTime_7 = millis();
  /* This is the event */
  if (currentTime_7 - previousTime_7 >= eventInterval_7) {        
tft.fillRect(70, 165, 40, 30, TFT_WHITE); //Bars #4
  /* Update the timing for the next time around */
  previousTime_7 = currentTime_7;
  }
currentTime_8 = millis();  
  /* This is the event */
  if (currentTime_8 - previousTime_8 >= eventInterval_8) {       
tft.fillRect(70, 165, 40, 30, TFT_GREEN); //Bars #4
  /* Update the timing for the next time around */
  previousTime_8 = currentTime_8;
  }
currentTime_9 = millis();
  /* This is the event */
  if (currentTime_9 - previousTime_9 >= eventInterval_9) {        
tft.fillRect(115, 165, 60, 30, TFT_WHITE);  //Bars #5
  /* Update the timing for the next time around */
  previousTime_9 = currentTime_9;
  }
currentTime_10 = millis();  
  /* This is the event */
  if (currentTime_10 - previousTime_10 >= eventInterval_10) {       
tft.fillRect(115, 165, 60, 30, TFT_GREEN); //Bars #5
  /* Update the timing for the next time around */
  previousTime_10 = currentTime_10;
  }    
}

void loop() {
/* Updates frequently */
  currentTime = millis();
  /* This is the event */
  if (currentTime - previousTime >= eventInterval) {
  downloading();
  /* Update the timing for the next time around */
  previousTime = currentTime;
  }
}

Thanks for taking the time to reply

Thank you for your input. For me to Grok something my initial step is to read examples and as a learner being careful of who to follow is very hard when Google's top search results give examples such as what I have in my code.
My 2nd step is to try and internalize how the code works and for me that comes from copy/pasta segments of code to see what they do with regards to what I'm trying to achieve.
I won't post what I've come up with as a hack for getting this code to work because you'll probably fall off your chair :rofl:

But I do intend to 'refine' the code and your suggestion of using an array has given me some very good food for thought.

Thank you again.

Sorry 'Grok' is to understand something

The book is quite an entertaining read on one level, but as usual, every time I read an old Heinlein favorite, I come away with a different understanding. One of the pillars of classic SF, he was, along with Bradbury, Asimov, E.E. 'Doc' Smith, Arthur. C. Clarke. and (latterly), Herbert.

1 Like

Yes I read Stranger in a Strange Land when I was a teenager in the 80's and the word Grok has stayed with me ever since.

By the time I hit high school in the 70's it had fallen out of favor, because it was overused by the hippies who came before us. It was only used by teens my age who had much older siblings as influencers, particularly if they were providing their younger siblings with recreational 'consumables'. An "all in the family" thing.
But we're a long ways from your original topic. Did you gain any answers, or shall we refocus our lasers?

I have a deeper knowledge of millis now compared to when I first posted and I think this topic will disappear into the Arduino Forum abyss along with countless other Blink without Delay posts so Lasers it is.
I've been meaning to read Stranger in a Strange Land again but I may have to try an audio book version this time. Thine eyes are not what they once were.

Our local library has Large Print versions of many of those classics, as the requesters are generally 'of that age group'.
Refocussing....

Yeah, wow. Looking at the code posted in #10, I see room for changes.
Why don't you take a stab at doing this using an array, and see what you come up with? It's pretty simple, once you get the hang of it.
One approach might be:
write a function that simply calls the display routine chosen using an index value,
and call that routine from loop(), passing the index value to the function
The array would be 2-D, holding the event duration plus all the TFT parameters in each row.

After that, explore structs, and create a 1D array of structs, each element of the struct holding all the information formerly held in one row of the 2D array.

That's an approach, anyway. I'm sure others will have insightful commentary on this.

1 Like

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