Pages: 1 [2]   Go Down
Author Topic: Reset millis() clock  (Read 3710 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the thorough description Bill.

If the variables in question have been confirmed to be ISR access only by the Timer0 overflow ISR and we have disabled the interrupt, is it necessary to provide explicit atomic access protection or is 'standard' access sufficient from the function in question?

Best Regards,
George
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12744
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


As written, @MGeo's code essentially accesses the variables atomically.  The timer is stopped (and the interrupt disabled) during the access so there is no possibility of a conflict with the interrupt service routine.

However, @MGeo restarts the timer without ensuring the new values have been first written to SRAM.  That's why volatile is necessary.


Quote
If the variables in question have been confirmed to be ISR access only by the Timer0 overflow ISR and we have disabled the interrupt, is it necessary to provide explicit atomic access protection


No.

Quote
or is 'standard' access sufficient from the function in question?

Yes.


Edit: spelling.
« Last Edit: April 30, 2012, 04:16:27 am by Coding Badly » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

However, @MGeo restarts the timer without ensuring the new values have been first written to SRAM.  That's why volatile is necessary.

Thank you, that adds much clarity to the subject.

About this insistence that the millisecond timer be reset: expect the Arduino to react about as violently as I would react if you grabbed my wrist and tried setting the time on my watch.

That's a bit much, particularly considering as programmer it is in the end my watch to set.

------------------------------------

In case others come across this thread with the same question:

After all the input here and my testing and studying of wiring.c, I'm realizing you can in fact reset millis, mostly.  The fractional counter variable timer0_fract within wiring.c is used for the microseconds calculation and is declared as follows (in bold italic):

volatile unsigned long timer0_overflow_count = 0;
volatile unsigned long timer0_millis = 0;
static unsigned char timer0_fract = 0;

This can not be reached from a sketch.  So you can clear most but not all of the counter state variables from a sketch.  The only way I can see around this is to modify wiring.c.  If that is the case, one would be better off placing a custom millis_reset() in the modified wiring.c.  All a bit much for the casual user.

George
« Last Edit: May 05, 2012, 09:03:28 am by MGeo » Logged

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

For my applciation I desire to reset the millis() clock.  

For my application I desire to reset the year to 1984.
Logged

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

I am using mills() command to operate a clock. I have calibrated the software timer to make the millis() function accurate on an UNO. (about 1-2 seconds a day) I initally set the clock with an NTP server on power-up and touch-up the time every 24 hours. This is going to operate a sprinkler system at my home. The documentation states the mills() will reset about every 50 days. I am assuming at or about 50 days the value will go to Zero and start over. This may have some unpredictable result on my system. To be proactive, I was thinking about a day counter that when it gets to 40 days and 40 nights  smiley-eek, to cause a pin on the arduino to toggle and fire a 555 to make a reset pulse.
All my essential data is stored in EEPROM in the 328 and the clock will resync with a NTP server on power-up / reboot. My question is, does anyone see a fault in my logic. Its kind of hard to test something if it only happens every 50 days or so.
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 63
Posts: 2641
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

albert,
I wouldn't throw hardware at a s/w issue.
I think you would be better of using the Time and TimeAlarms libraries.
They do it all for you and don't have any millis() rollover issues.
Time library tracks time and allows for a synchronization routine to set the time and keep the time in sync.
It also allows setting a sync interval for how often to re-sync the time.
The TimeAlarms library provides for setting up "alarms" that can call your functions
at predetermined date/times or periodically.

There are many examples provided including one that uses NTP to sync the time.

Although if you really want to slam the millis() clock back to zero:

Code:
/*
 * Code to Reset the millis counter back to 0
 * NOTE: this does not reset the hardware counter and
 * also does not set the software fractional value as that was declared static
 * in wiring.c
 * As a result, the first "tick" will be be shorter than it should be.
 */

void millisReset()
{
extern volatile unsigned long timer0_millis;
extern volatile unsigned long timer0_overflow_count;
noInterrupts();
timer0_millis = 0;
timer0_overflow_count = 0;
interrupts();
}

--- bill
« Last Edit: August 14, 2013, 11:49:13 pm by bperrybap » Logged

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

The documentation states the mills() will reset about every 50 days. I am assuming at or about 50 days the value will go to Zero and start over. This may have some unpredictable result on my system. To be proactive, I was thinking about a day counter that when it gets to 40 days and 40 nights  smiley-eek, to cause a pin on the arduino to toggle and fire a 555 to make a reset pulse.

40 days and 40 nights, eh? And then the sprinkler goes haywire and causes a flood?

There is no need to reset the timer, any more than you have to reset your clock at midnight. By doing subtraction on unsigned longs the rollover is handled seamlessly. Please post the code in question that you think may have problems.
Logged

Pages: 1 [2]   Go Up
Jump to: