Pages: [1] 2   Go Down
Author Topic: How to set a value for millis()?  (Read 4778 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 1
Posts: 111
... only learning ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

millis() returns the "time passed" since the last boot/upload/restart.
I would like to change its value in runtime.

I cannot use a variable to solve this because it would cause the breaking/modification of existing code.

Is it possible to set the current value of millis()?

Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Since that isn't the intended use for millis(), I guess a question would be why do you need to change it?
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Create a MyMillis() function like this, may be wrapped in a class

Code:
unsigned long MMdelta = 0L;

unsigned long MyMillis()
{
  return millis()- MMdelta;
}

void MMReset(unsigned long val = 0L)
{
  MMdelta = millis() - val;  
}
////////////////////////////////////////////
void setup()
{
  Serial.begin(115200);
  Serial.println("MyMillis demo");
  
  for(int i=0; i< 10; i++)
  {
    delay(10);
    Serial.println(MyMillis());
  }
  delay(1000);
  MMReset();
  for(int i=0; i< 10; i++)
  {
    delay(10);
    Serial.println(MyMillis());
  }
  MMReset(1000);
  for(int i=0; i< 10; i++)
  {
    delay(10);
    Serial.println(MyMillis());
  }
}

void loop()
{
}
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Full Member
***
Karma: 1
Posts: 111
... only learning ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the replies.

I intend to use power-down sleep mode. When sleeping, the current value of millis is frozen. Therefore, if we know exactly how much time passed during sleep mode, we can adjust millis() as desired.

The proposed function is a good approach but I still need to change many existing programs that are migrating from non-sleep to sleep mode. Probably, I will go in this way if there is no way to direct change the variable used by millis().

Thanks
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Ionito,

Inspired by your question I wrote a simple StopWatch Class based upon millis(), See - http://www.arduino.cc/playground/Code/StopWatchClass . It will not work for your question but nevertheless I thought you might be interested.

Thanks again for the inspiration smiley-wink

Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Full Member
***
Karma: 1
Posts: 111
... only learning ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rob,

Nice code!! Thanks!!
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 21
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you have a look at wiring.c, you'll see that millis() reads variable timer0_millis.  If you take the right precautions you can update this variable.  I've amended my SleepDelay library to do this and I'm currently testing it out.  So far, it seems ok but I'm going to test it for a few days first.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Cloudy,

Will you be able to write a playground article about it?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

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

Quote
If you have a look at wiring.c, you'll see that millis() reads variable timer0_millis
timer0_millis is only part of the value.  The other part is the timer itself.  It is extremely difficult to change the millis value without introducing an offset.
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 21
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@robtillaart  Yes I will once I'm happy with it.

@Coding Badly   Not sure what you mean by introducing an offset.  The timer doesn't work in power down sleep mode.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Kind of off thread, but it's funny how frequently people ask or want to be able to preset a value for millis(), seems to be a very popular request. And while I'm certainly not a guru software type, none of the reasons given for needing this seem to not be better handled in a different and better matter?


Lefty

Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Lefty
One of my CS teachers told me that software is made from the same the stuff dreams are made of, if you can dream it you can make it smiley

The "problem" is often that people don't have a formal training in algorithmic - OO or realtime design which often leads to "if the only tool is a hammer, every problem is a nail" thinking. A very common pattern. People have a timing problem, they know millis() is about time,  so millis() can/should solve it, and often it just can solve it, but sometimes not. Even knowing this pattern I find myself doing it too smiley

Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

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

Quote
Not sure what you mean by introducing an offset.
If you change timer0_millis without also considering TCNT0 and the hidden / unreachable value within the timer, your change introduces an error into the millis value (an offset from the correct value).
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 111
... only learning ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It worked!!!

This is the code:

Code:
 
...
#include <Wire.h>
...

 
    // timer0_millis can change inside the ISR process for timer0
    // 2 options: disable interrupts OR make 2 consecutive readings and
    //                compare. I am using the second option here:

    unsigned long reading1;
    unsigned long reading2;
    boolean readingOK = false;
    int k=0;
    while (k<1000 && !readingOK) {
      reading1 = timer0_millis;
      reading2 = timer0_millis;
      if (reading1 == reading2) { readingOK = true; }
      k++;
    }
    
    timer0_millis = 2000 + reading1; // e.g. 2000: time elapsed while sleep
    nint++;
    Serial.print("Going to sleep. Count # " );
    Serial.println(nint );
    Serial.print("Time: millis() " );
    Serial.println(millis() );
    delay(2);               // wait until the last serial character is send

It completely solved my problem. There is a small error in the process. However, if the process is always the same after returning from sleeping, we can determine its value with great accuracy and adjust.

Thanks
Logged

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

Quote
It worked!!!
Only because you're lucky.  Let the code run long enough and it will fail.
Logged

Pages: [1] 2   Go Up
Jump to: