0
Offline
Full Member
Karma: 1
Posts: 107
... only learning ...
|
 |
« on: January 04, 2011, 12:06:24 am » |
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
Faraday Member
Karma: 41
Posts: 5176
CMiYC
|
 |
« Reply #1 on: January 04, 2011, 12:51:12 am » |
Since that isn't the intended use for millis(), I guess a question would be why do you need to change it?
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 91
Posts: 9454
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #2 on: January 04, 2011, 06:31:45 am » |
Create a MyMillis() function like this, may be wrapped in a class 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
|
|
|
|
|
0
Offline
Full Member
Karma: 1
Posts: 107
... only learning ...
|
 |
« Reply #3 on: January 04, 2011, 10:29:17 am » |
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
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 91
Posts: 9454
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #4 on: January 04, 2011, 02:37:06 pm » |
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  Rob
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Full Member
Karma: 1
Posts: 107
... only learning ...
|
 |
« Reply #5 on: January 04, 2011, 02:53:34 pm » |
Rob,
Nice code!! Thanks!!
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 1
Posts: 21
Arduino rocks
|
 |
« Reply #6 on: January 07, 2011, 04:29:53 am » |
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
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 91
Posts: 9454
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #7 on: January 07, 2011, 09:05:41 am » |
@Cloudy,
Will you be able to write a playground article about it?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Dallas
Offline
Shannon Member
Karma: 120
Posts: 10201
|
 |
« Reply #8 on: January 07, 2011, 01:42:40 pm » |
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
Newbie
Karma: 1
Posts: 21
Arduino rocks
|
 |
« Reply #9 on: January 07, 2011, 02:44:26 pm » |
@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
Brattain Member
Karma: 279
Posts: 15340
Measurement changes behavior
|
 |
« Reply #10 on: January 07, 2011, 04:35:28 pm » |
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
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 91
Posts: 9454
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #11 on: January 07, 2011, 06:34:56 pm » |
@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 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  Rob
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Dallas
Offline
Shannon Member
Karma: 120
Posts: 10201
|
 |
« Reply #12 on: January 07, 2011, 11:33:04 pm » |
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
Full Member
Karma: 1
Posts: 107
... only learning ...
|
 |
« Reply #13 on: January 16, 2011, 01:08:48 am » |
It worked!!! This is the 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
Shannon Member
Karma: 120
Posts: 10201
|
 |
« Reply #14 on: January 16, 2011, 01:17:50 am » |
It worked!!! Only because you're lucky. Let the code run long enough and it will fail.
|
|
|
|
|
Logged
|
|
|
|
|
|