can i make millis() "zero" by myself???

I am using millis() function in my program and i want to make its value equal to zero after every hour, can it be done??? And how???

Technically yes, but you really shouldn't.

Think of how you can "reset" the time in your brain ("it's been 45 minutes since I put in the laundry") without reaching up and changing the time every hour.

hint: it involves subtraction.

i didn't got you man..... :(

You look at a clock (millis())when it's 8:36 PM and write it down (storing in variable). Later, you check the time (millis() again) and see that it's 9:45. You can figure out that 1 hour and 9 minutes has passed by taking 9:45 and subtracting 8:36.

So, when you want to zero the clock, you just say

unsigned long zeroTime = millis();

and when you want to check it later, say this

unsigned long elapsedTime = millis() - zeroTime;

Yes i'm already doing this, and having problem in it, Now Let me clear my question again, i'm using millis() to "compare" it with some previous stored millis() in a variable that how much time is passed, but as time comes when millis() get reset to zero automatically (u should know this) after about 52 days, so i will not be able to compare its value with previously stored value of millis() which will be a huge value stored in a variable just before reset and current millis() will be just few milliseconds..... I'm stuck :(

how much time is passed

If you are trying to time events that occur more than 49 days apart (that's how long it takes millis() to roll over, then you are taking the wrong approach. You need a RTC for that duration.

If the events are less than 49 days apart, and you are having problems determining the interval, then you need to post your code. Subtraction is guaranteed to work, even when millis() rolls over.

event is for life time.. its a counter which is counting pulses and after 500 pulses it makes "pin 13" HIGH for 4 seconds and after 4 sec it makes it LOW again, so during that 4 seconds i want to keep counting if any pulse is available.. This program is working very nicely but that is the only problem i'm facing...

int count = 0;
int previousValue = 0;
int currentValue = 0;
long long currentTime = 0;
void setup()
{
   pinMode(13, OUTPUT);
   pinMode(4, INPUT);
}
void loop()
{
   currentValue = digitalRead(4);

   if (previousValue != currentValue)
   {if(currentValue == HIGH)
         ++count;}

   if(count == 500)
     {count = 0;
     digitalWrite(13, HIGH);
     currentTime = millis()/1000;}

   if( (millis()/1000) == currentTime+4 )
     {currentTime = 0;
     digitalWrite(13,LOW);}
previousValue = currentValue; 
}
  1. Change your declaration of currentTime to unsigned long. That is the type returned by millis().

  2. Get rid of your divisions of millis(). They are completely unnecessary. So:

currentTime = millis()/1000;

becomes

currentTime = millis();

  1. The only mathematical operation that is rollover safe is subtraction, and that is only safe with unsigned types. So if you want to have a rollover safe comparison, it can only involve subtraction on an unsigned type, which for your purposes is rather simple to accomplish (and is also why the type of currentTime needs to be unsigned long). Just change your last conditional from:

if( (millis()/1000) == currentTime+4 )

to

if(millis() - currentTime >= 4000)

long long currentTime = 0;

currentTime is 1/1000 of the output from millis(), which fits in an unsigned long. Why are you storing the smaller value in a larger variable?

This program is working very nicely but that is the only problem i'm facing.

If the only problem you are facing is that the program is working nicely, consider yourself lucky.

unsigned long lightOn;
.
.
.
if(count == 500)
{
   lightOn = millis();
   // turn the light on and reset the counter
}

if(millis() - lightOn > 4000)
{
   // turn the light off
   // Do not change lightOn
}

The LED will be turned off on every pass through loop after the LED has been on for 4 seconds, but that doesn't hurt anything.

I guess I fail to see what problem you are trying to solve.

jraskell: 1. Change your declaration of currentTime to unsigned long. That is the type returned by millis().

  1. Get rid of your divisions of millis(). They are completely unnecessary. So:

currentTime = millis()/1000;

becomes

currentTime = millis();

  1. The only mathematical operation that is rollover safe is subtraction, and that is only safe with unsigned types. So if you want to have a rollover safe comparison, it can only involve subtraction on an unsigned type, which for your purposes is rather simple to accomplish (and is also why the type of currentTime needs to be unsigned long). Just change your last conditional from:

if( (millis()/1000) == currentTime+4 )

to

if(millis() - currentTime >= 4000)

Thats fine, i have done all of the above, but i think rollover problem will be still there as in currentTime if the maximum value of millis() arrives and after that instant millis() get reset and starts from zero so in currentTime there will be maximum value of millis() and from subtraction we will get negative number... And @ PaulS.. Yes you didn't got my problem buddy... :)

Thats fine, i have done all of the above, but i think rollover problem will be still there as in currentTime if the maximum value of millis() arrives and after that instant millis() get reset and starts from zero so in currentTime there will be maximum value of millis() and from subtraction we will get negative number...

Please explain how you will store a negative number in an unsigned variable. There was a very interesting thread a while back that went into all the details about why subtraction using unsigned variables is guaranteed to produce the correct results. You could search for that thread if you want, or you can just accept the fact that it will work.

The way you are using millis, even if rollover were a problem, you would experience issues for 4 seconds every 49 days. Seems acceptable to me.

Hi Saad, Why not you are using RTC.. You can make it under 150 rupees.. oops..you dont need for one hour interval.. "I am using millis() function in my program and i want to make its value equal to zero after every hour, can it be done??? And how???"" Just see the Blink without delay in REFERENCE SECTION... You can declare two variables for storing the values for millis.. The first one will check for 1 hour and the second will be check for 4 second passing time..

@ PaulS… yeah i got it now… you are right, i can afford 4 seconds error in 49 days…
@ Khalid… Don’t know about RTC, will check it…

Check my stopwatch class - http://www.arduino.cc/playground/Code/StopWatchClass - and you can start multiple millis() based timers when you want ...

yep thanks.. :) but as in your library written..

// The library is based upon millis() and therefore
// has the same restrictions as millis() has wrt overflow.

Can't you make something like relative timer which can just give me difference of 4 seconds, without using millis(), so i'll completely overcome this problem..

Can't you make something like relative timer which can just give me difference of 4 seconds

it does.

without using millis(),

you need some reference and that is what millis() provide

so i'll completely overcome this problem.

This is an restriction of the 32 bitdatatype, after 2^32 tics it will overflow. that is 49+ days in terms of milliseconds. But the math in the lib will not overflow, however it cannot measure duration longer than 49+ days.

If you don't want this ==> write a 64 bit based milliseond timer. That will overflow once every 210.400.000.000+ days roughly 500 million years. But I expect it will be relative slow and therefore unpractical but please proof me I am wrong in this.

The four seconds/49 days issue does not exist. Re-read PaulS' comment - he says that there is NO problem with millis overflow if you use subtraction, BUT that even if you don't accept that, there would only be an issue in that tiny timeframe. For more detail check johnwasser's analysis in this thread: http://arduino.cc/forum/index.php/topic,60215.0.html. It is true though that millis can't help you (directly) if you want to time events longer than the ~49 day limit - do you?

Personally, for any code I expect to run for more than 48 or 49 days, I store millis in an unsigned long long and make sure the high 32-bits are properly incremented each time millis() rolls over.

I have a piece of code that calculates rainfall by subtracting the time of the last tipping bucket rain gauge contact closure from the current time and converting that to closures per second. We had our first measurable rainfall in 6 or 8 months a few days back. That's a lot more than 49 days worth of milliseconds ;)

As for whether or not to use an RTC, sure, why not!

WOW!!! I got it now wildbill.. :) Example given by john cleared me everything.. :) Thats by sure that we will NOT face the roll over problem in millis() due to unsigned value...

Example: The start time is 0xFFFFFF00 (256 milliseconds before rollover). 512 milliseconds later millis() has overflowed by 256 and is now 0x00000100. Subtracting 0xFFFFFF00 from 0x00000100 leaves you with 0x00000200 which equals 512, the elapsed interval! MAGIC! ;)

Thanksss alot to all.. :) by the way.. I haven't used RTC yet, is it helpful and easy to use???? and how it works??? I mean, Not like millis() ..? storing value somewhere which can overflow??