Pages: 1 [2]   Go Down
Author Topic: Resetting Millis() to zero, reset clock  (Read 4162 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Overflows are registered in timer0_overflow_count, making it possible to calculate further how long the arduino has really been running beyond the unsigned long limit ...

This is not correct. That variable counts the number of times Timer0 overflows (which itself happens every 1.024 mS). It is used in one place only and that is to return the correct value from micros(). It is not a "millis() overflow count" as you seem to think.

Quote
I personally prefer resetting timer0_millis back to 0 manually in a periodically fashion to prevent any weird stuff from happening every 50 days.

This is not a useful thing to do, any more than resetting your kitchen clock each evening to stop it "rolling over" at midnight. For one thing, it isn't necessary. For another, while you are resetting the clock it is no longer counting the time.

If you have any reasonably complex sketch where you need to count multiple intervals then there will be no obvious time in which to reset the timer.

Quote
It is better coding practice to read timer0_overflow_count before and after long-running operations ...

No, that achieves nothing, as I said above.

The others are quite right. Something like this always works:

Code:
if (millis () - startTime >= interval)
  {
  // do something
  }

(Given that startTime is unsigned long).

Example is given in OP. When dealing with large intervals, uncertainty of roll-over increases, making the possibility of negative return on comparisons (smaller number minus larger number) greater.

How can a negative return be possible on comparing unsigned numbers? That is the crux. It isn't possible, and thus you get the correct answer. What other answer could you get?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Whenever you want to reset millis():
Code:
timer0_millis = 0;

I just want to also point out, in case you ignore my earlier advice, that this is flawed because you haven't "protected" that line from interrupts.

http://www.gammon.com.au/interrupts

Scroll down to "critical sections". If you must do the above, you have to turn interrupts off:

Code:
noInterrupts ()
timer0_millis = 0;
interrupts ();

Without doing that, at the moment you attempt to set the timer to zero, an interrupt may occur which means it is possibly only half set to zero.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 597
Posts: 33296
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.
Yes you are right, that is what I was taught and what I did teach.
Logged

Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3941
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.

None needed. Probably just another of those differences between English and Usanian smiley-wink
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://gammon.com.au/millis
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 287
Posts: 25681
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Nick!

Karma++
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1893
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Nick!

Karma++
Same for me :-)
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The others are quite right. Something like this always works:

Code:
if (millis () - startTime >= interval)
  {
  // do something
  }

(Given that startTime is unsigned long).

Example is given in OP. When dealing with large intervals, uncertainty of roll-over increases, making the possibility of negative return on comparisons (smaller number minus larger number) greater.

How can a negative return be possible on comparing unsigned numbers? That is the crux. It isn't possible, and thus you get the correct answer. What other answer could you get?

Aw sweet, it all makes sense now. I executed the following code

Code:
unsigned long var;
unsigned long varminus;

void setup(void)
{
  // initialize serial:
  Serial.begin(9600);
  var = 100;
  varminus = var-200;
  
  Serial.println("The answer to 100 minus 200 on unsigned-long vars is: ");
  Serial.println(varminus);
}

void loop(void)
{
}

And the output is:

Code:
The answer to 100 minus 200 on unsigned-long vars is:
4294967196

The odometer analogy is the perfect one for a commoner to get around obscure binary/hex-thinking.

In any case, many thanks for forum members that stuck around, I've edited OP to accommodate future reference
« Last Edit: August 28, 2013, 07:07:01 am by redtails » Logged

NSW Australia
Offline Offline
Faraday Member
**
Karma: 78
Posts: 3173
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.

None needed. Probably just another of those differences between English and Usanian smiley-wink

While a staunch defender of the "pure" English tongue, on cogitation, I do believe the term "modular arithmetic" is in fact quite correct and indeed, more accurately descriptive than "modulo arithmetic".

The modulus is a parameter of a numeric value determined by a specific operation and the act of performing that operation is described as "modulo" or a modulo function.  So the arithmetic of performing further operations - notably comparisons - on such results, the moduli as a plural, can appropriately be described as "modular" arithmetic where "modular" derives from the "moduli" in the same way we refer to "alveolar" where the (lung) alveoli are concerned, and a few other Latin terms - though I cannot quote the original Latin rules behind that (I never formally studied Latin).

There could be claimed to be the occasional word ending in o - such as "medico" whose apparent derived adjective ("medical") ends in "al" but I suspect this is spurious and results from the colloquial addition of "o" to a word (such as "nymph") whose derived adjective did end in "al".

My point - for what it is worth smiley-sleep - is that "modulo" is the name of a process the result of which is the modulus and the arithmetic relating to these is concerned more with what you can do with the moduli, than how you obtain them.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In any case, many thanks for forum members that stuck around, I've edited OP to accommodate future reference

Thank you.

Quote
Take a look at Gamon's explanation of the millis() issue, and what is often done wrong that causes errors.

It's "Gammon" (with two "m"s.).

Gamon was a guy in Orgrimmar in World of Warcraft, who was constantly being killed.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I have solved this problem in this way:
Code:
unsigned long check_millis = 0;
long interval = 1000;
unsigned long previousMillis = 0;

void setup(){
}
void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis >= check_millis) check_millis = currentMillis;
  else {
    check_millis = 0;
    previousMillis = 0;
  }

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    //do somethings
  }
}
Logged

Pages: 1 [2]   Go Up
Jump to: