My Millis is not equal to 1 second (UNO)

HI,

While making test with my Arduino project, I found that my "millis" is not equal to 1 second.

My counter using millis is counting to 10 but if I compare, I get 9.25 seconds to my stopwatch.

To debug that, I add 2 lines to my code with "serial.print" so I can see my variable "Countermillis and CounterMillis1"

I start the counter and found that the difference between both was not 1000.

I tried to change the value of my interval but it's not working.

It look like my full code takes more that a second to fully run on my UNO (I think)

I set my variable at the beginning of my code

  unsigned long CounterMillis = 0;
  unsigned long CounterMillis1 = 0;
  const long interval2 = 900;

And this is the part of my code for the counter

void LcdCounter(){


    CounterMillis = millis();
    if (CounterMillis - CounterMillis1 >= interval2) {

    if (a < 40 && purge == 0 && stateRELAY1 == HIGH) // value of 40 for testing purpose.              
    {                                                 // The final goal will be 360 seconds
    a ++;
    lcd_2.setCursor(11, 1);
    lcd_2.print(a);
    Serial.println(CounterMillis); // for debug millis
    Serial.println(CounterMillis1); // for debug millis
    }
    
    else
    {
    if (purge == 1){
    a = 0;
    purge = 0;
    lcd_2.setCursor(11, 1);
    lcd_2.print(F("     "));
    }

    if (a >= 40) // value of 40 for testing purpose. 
                 // The final goal will be 360 seconds
    {
    stateRELAY1 = LOW;
    stateRELAY2 = LOW;
    stateRELAY3 = LOW;
    lcd_2.setCursor(11, 1);
    lcd_2.print(F("Purge"));
    }
    }
    CounterMillis1 = CounterMillis;
    }
}

When I check on serial print the value of CounterMillis and CounterMIllis1 I get this

2059008
2058103

Off course the values changed at each print but every time I check, the difference between them is around the same value and it's not 1000.

Question

How can I get 1 second for my counter?

Hi Delta_

If I put the interval to 1000, the counter become slower and when it reach 10,
my stopwatch show me 14 seconds. I tried a few value and 900 was the closest
to 1 second.

Hi Delta_G

I didn't think the full code could be useful for that question but since
I'm looking for help, I'm certainly not going to argue with you so see
my code attached.

Thanks,

Control_Compressor_VR_Oct_1_FlowsensorV7.ino (12.5 KB)

Write a bare minimum sketch to check out millis().
What are the results?

.

Nick's reply on "Re: How accurate is millis()?" #8,

fyi, there is a lot of blocking code in your project... for example...

void DallasTemperature::requestTemperatures()
{
  _wire->reset();
  _wire->skip();
  _wire->write(STARTCONVO, parasite);

  // ASYNC mode?
  if (!waitForConversion) return; 
  blockTillConversionComplete(&bitResolution, 0);

  return;
}

(it even admits to it)

all kidding aside, if you look at the Dallas spec sheets, you will see just how long it takes to get a temperature, depending on the resolution you asked for. I cannot tell if any of that is affecting your millis() timer but you have to know all of the potential parts of the sketch that can potentially block.

because of your structure, you can easily just omit functions in loop() to see what may be the culprit.

Two possible issues.

1 - the resonator is inaccurate. This can't be fixed - you need to purchase a proper Real Time Clock module. They are ten bucks.

2 - the sketch marks a period by setting the new start of the timed interval to millis() after something that takes time has occured.

dont do this:

if(millis() - startMs >= 1000) {
  do_something_that_takes_200ms();
  startMs = millis();
}

do this

if(millis() - startMs >= 1000) {
  startMs = millis();
  do_something_that_takes_200ms();
}

or better still, do this

if(millis() - startMs >= 1000) {
  startMs += 1000;
  do_something_that_takes_200ms();
}

Just be sure, if you use that third one, to initialise startMs in your setup().

Hi BulldogLoell,

I deactivated all sections in my loops except the counter and then millis = 1000
the temperature section only add .005. The pressure and the O2 analysing
section are the ones who takes more but anyway I won't change that.
Correcting millis or using a RTC may do it but I don't know yet.
still reading and asking questions.

Hi PaulMurrayCbr,

I would like to try your example but i'm not sure where to put in in my code
and do I replace lines with yours or add them ? Do I initialize (int statMs;) or need to be set to 0 ?

My code again.

void LcdCounter(){


    CounterMillis = millis();
    if (CounterMillis - CounterMillis1 >= interval2) {

    if (a < 40 && purge == 0 && stateRELAY1 == HIGH) // value of 40 for testing purpose.              
    {                                                 // The final goal will be 400 counts
    a ++;
    lcd_2.setCursor(11, 1);
    lcd_2.print(a);
    Serial.println(CounterMillis); // for debug millis
    Serial.println(CounterMillis1); // for debug millis
    }
    
    else
    {
    if (purge == 1){
    a = 0;
    purge = 0;
    lcd_2.setCursor(11, 1);
    lcd_2.print(F("     "));
    }

    if (a >= 40) // value of 40 for testing purpose. 
                 // The final goal will be 400 counts
    {
    stateRELAY1 = LOW;
    stateRELAY2 = LOW;
    stateRELAY3 = LOW;
    lcd_2.setCursor(11, 1);
    lcd_2.print(F("Purge"));
    }
    }
    CounterMillis1 = CounterMillis;
    }
}

you see I'm just a beginner and still need to be taken by the hand for now.

many thanks