Pages: 1 [2]   Go Down
Author Topic: safe way to prevent millis() wrap?  (Read 3008 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 163
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think you'll agree the code I just posted above is about the easiest thing that can be done here with a one-shot use of a time, that happens to hinge on using millis(), a timer is already built in arduino base.

Except for the fact that the code you posted won't compile because timer0_millis isn't in scope where you're trying to zero it out. And the fact that mucking about with the the state variables used by millis() is a bad idea because it is very likely to break any other library functions which rely on millis() working correctly... And the fact that zeroing a long isn't atomic so even if the code you posted DID compile the results you'd see would be very inconsistent with what you'd expect...

...oh yeah, and just coping with overflow is easy anyways.

Good luck!
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No access, scope!  Agh.  Extern solves that.


But

cli();
timer0_millis = 0;
sei();

makes it a little more atomic, don't you think?
« Last Edit: November 04, 2009, 11:08:46 am by scottmcphee » Logged

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

Quote
makes it a little more atomic

It does.  For what you're trying to do, the code will work.  

There's also a flaw that prevents your code from being generally usable.  For anyone reading this thread, please take BenF's, Fjornir's, and my advice: don't reset millis.  It isn't worth the risks.  There's an abundance of ready-to-use one-shot code available in this thread and in the this forum and in the Playground and in the examples and on the internet at-large.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This compiles:


// whack-a-millis

void setup(){
}

void loop() {

  extern volatile unsigned long timer0_millis ;
  cli();
  timer0_millis = 0 ;
  sei();

  // Groundhog Day

}


If arduino provided a general timer library, I'd use that instead.    I'd prefer to have a countdown timer and set its value in milliseconds, and then check it for zero.

C.Badly, "There's an abundance of ready-to-use one-shot code available in this thread and in the this forum and in the Playground and in the examples and on the internet at-large."   You're a very elusive poster... holding secrets back... if you know stuff, post stuff / links.   Save me from shooting my foot off!  Thanks.
« Last Edit: November 04, 2009, 11:17:57 am by scottmcphee » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just found MsTimer2 in the playground, this should also work for my case.

#include <MsTimer2.h>

//declare a software reset function, begins execution at address 0
void(* resetFunc) (void) = 0;

setup()
{
 // quiesce chip features, change I/O pins, and enable power saves
 // setup external interrupt buttons (low level interrupt)
 // sleep (power down mode)
 // wakes up here
 ...
 // setup the way I need things
 // do my job (transmit information - one shot)

  MsTimer2::set(1000, resetFunc);  // set fuse length 1s on "reset bomb"
  MsTimer2::start(); // light the fuse

}

loop()
{
 // listen for echo (if serial.Available() > 0) and act on it

 // ..when the time is right (as a background process) MsTimer2 calls reset
}


Much cleaner.  Pretty much exactly what I want but better! I don't even have to check for zero, that runs as a background task.  

using millis method for my program makes it:
Binary sketch size: 3860 bytes (of a 30720 byte maximum)

using MsTimer2 instead makes it:
Binary sketch size: 4214 bytes (of a 30720 byte maximum)

10% bigger!  Sure this uses much more code space that twisting millis, but I'm only using around 14% of my 328P, so I'm not needing optimization at this juncture.

It turns out the safest way to prevent millis() from wrapping is not to play that game at all.  


« Last Edit: November 05, 2009, 11:01:33 am by scottmcphee » Logged

Pages: 1 [2]   Go Up
Jump to: