Go Down

Topic: reseting millis() (Read 2 times) previous topic - next topic

Dodsond

I am working on a timing function for a light switch and am testing some code to make sure I know how it works. I want to reset the time after a given number of seconds which I thought would be easy but I am still having trouble figuring out how to get it done.
Here is what I have so far.
Code: [Select]
unsigned long time;
unsigned long last_time;
unsigned long duration;
int reset;

void setup(){
  Serial.begin(9600);
last_time = 0;
reset = 0;
}
void loop(){
 
  time = millis();
 
delay(1000);
duration = time - last_time;
last_time = time;
Serial.print("time ");
Serial.println(time);
Serial.print("time between prints ");
Serial.println(duration);
if (time > 10000)
{
time = reset;
}
}




As you can see I am trying to reset time to 0 but when I run it the time just keeps going up.
What am I missing?
Dan

Arrch

#1
Jul 29, 2012, 05:14 am Last Edit: Jul 29, 2012, 11:34 pm by Arrch Reason: 1
If you're going to cook something on the stove for an hour, you don't set your your time to midnight and wait until 1AM before you take it off the stove, you record the time you started cooking and every so often, subtract it from the current time to determine how long it's been on the stove.

It might be more beneficial to describe, more abstractly, what you are trying to do.

marco_c

Millis can't be reset. What you need to do is remember when your time period started by storing the value of millis at the time and then working out time elapsed by subtracting current value from the stored value.  This is a pretty common technique with timing stuff on computers.
Arduino libraries http://arduinocode.codeplex.com<br />Parola for Arduino http://parola.codeplex.com

Dodsond

but millis() eventually rolls over to zero again. How do you account for that?

Nick Gammon

Your clock rolls around to 12 twice a day. How do you compensate for that?
http://www.gammon.com.au/electronics

James C4S


but millis() eventually rolls over to zero again. How do you account for that?

Very simple, with subtraction:
http://www.cmiyc.com/blog/2012/07/16/arduino-how-do-you-reset-millis/
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

retrolefty

#6
Jul 29, 2012, 06:11 am Last Edit: Jul 29, 2012, 07:25 am by retrolefty Reason: 1
Unless your desired event timing periods are in excess of 50+ days there is no problem nor concern about the roll-over event. As long as you always subtract (present time - old saved time stamp)then the roll-over will have on effect on your calculation. The subtraction in effects utilizes a 33rd borrow bit to deal with a possible roll-over.

Lefty


Dodsond

I just was not liking the millis() way of turning on my light switch so I went back to my time library. The code seems to be running all right though I havent tested it with the equipment other than the sensors yet (no outputs). My only thing I would like to add is the correct time or at least the correct time of day to the code.
Can't quite figure it out. If there is even a way to manually enter the hour and minute this code would be done.
I would apreciate you glancing at it.
Code: [Select]
//include the time library, so our garduino can keep track of how long the lights are on
#include <Time.h>

//define analog inputs to which we have connected our sensors
int moistureSensor = 0;
int lightSensor = 1;
int tempSensor = 2;

//define digital outputs to which we have connecte our relays (water and light) and LED (temperature)
int waterPump = 7;
int lightSwitch = 8;
int tempLed = 2;

//define variables to store moisture, light, and temperature values
int moisture_val;
int light_val;
int temp_val;

void setup() {
//open serial port
Serial.begin(9600);
//set the water, light, and temperature pins as outputs that are turned off
pinMode (waterPump, OUTPUT);
pinMode (lightSwitch, OUTPUT);
pinMode (tempLed, OUTPUT);
digitalWrite (waterPump, LOW);
digitalWrite (lightSwitch, LOW);
digitalWrite (tempLed, LOW);


}
void loop() {
// read the value from the moisture-sensing probes, print it to screen, and wait a second
moisture_val = analogRead(moistureSensor);
Serial.print("moisture sensor reads ");
Serial.println( moisture_val );
delay(1000);
// read the value from the photosensor, print it to screen, and wait a second
light_val = analogRead(lightSensor);
Serial.print("light sensor reads ");
Serial.println( light_val );
delay(1000);
// read the value from the temperature sensor, print it to screen, and wait a second
temp_val = analogRead(tempSensor);
Serial.print("temp sensor reads ");
Serial.println( temp_val );
delay(1000);
Serial.print("hour ");
Serial.println(hour());

//turn water on when soil is dry, and delay until soil is wet
if (moisture_val < 850)
{
digitalWrite(waterPump, HIGH);
}

//while (moisture_val < 850)
//{
//delay(10000);
//}

digitalWrite(waterPump, LOW);

//turn on light after 6:00am if room lights are not on
if ((light_val > 400) && (hour() >= 6))
{
digitalWrite(lightSwitch, LOW);
Serial.println("light off after 6 because other lights are on ");
}
else{
  if (hour() >= 6){
  digitalWrite(lightSwitch, HIGH);
  Serial.println("light on after 6a.m.");
  }
  else{
    digitalWrite(lightSwitch, LOW);
    Serial.println("light off not6 yet");
  }

}
//turns off light after 8:00 p.m.
if (hour() >= 20)
{
  digitalWrite(lightSwitch, LOW);
  Serial.println("light off after 8 ");
}

//turn on temp alarm light if temp_val is less than 850 (approximately 50 degrees Fahrenheit)
if (temp_val < 850)
{
digitalWrite(tempLed, HIGH);
}

}

Thanks
Dan

Dodsond

My timing would be better if my lights came on at a certain time of day and this program will be running continuously well past 50 days so I'm going to try and go back to the time library again.
Wish me luck and thanks
Dan

Nick Gammon

Just so reply #7 makes sense I've merged the threads.
http://www.gammon.com.au/electronics

cjdelphi

Dodsond - is this of any use to you?...

Code: [Select]

long days=0;
long hours=0;
long mins=0;
long secs=0;
long currentmillis=0;
unsigned long time;
unsigned long last_time;
unsigned long duration;
int reset;

void setup(){
  Serial.begin(9600);
last_time = 0;
reset = 0;
}


void loop(){
time = millis();

GetTimeRunning(); 
delay(1000);
if (days>0) // days will displayed only if value is greater than zero
   {
    Serial.print(days);
    Serial.print(" days and: ");
    }
   Serial.print(hours);
   Serial.print(" hours: ");
   Serial.print(mins);
   Serial.print(" minutes: ");
   Serial.print(secs);   
   Serial.println(" Seconds.");
   
}   

void GetTimeRunning()
{
  currentmillis= millis(); 
  secs = currentmillis/1000; //convect milliseconds to seconds
  mins=secs/60; //convert seconds to minutes
  hours=mins/60; //convert minutes to hours
  days=hours/24; //convert hours to days
  secs=secs-(mins*60); //subtract the coverted seconds to minutes in order to display 59 secs max
  mins=mins-(hours*60); //subtract the coverted minutes to hours in order to display 59 minutes max
  hours=hours-(days*24); //subtract the coverted hours to days in order to display 23 hours max
  //Display results
}



Results

Quote

0 hours: 0 minutes: 0 Seconds.
0 hours: 0 minutes: 1 Seconds.
0 hours: 0 minutes: 2 Seconds.
0 hours: 0 minutes: 3 Seconds.
0 hours: 0 minutes: 4 Seconds.
0 hours: 0 minutes: 5 Seconds.
0 hours: 0 minutes: 6 Seconds.
0 hours: 0 minutes: 7 Seconds.
0 hours: 0 minutes: 8 Seconds.
0 hours: 0 minutes: 9 Seconds.
0 hours: 0 minutes: 10 Seconds.
0 hours: 0 minutes: 11 Seconds.
0 hours: 0 minutes: 12 Seconds.
0 hours: 0 minutes: 13 Seconds.
0 hours: 0 minutes: 14 Seconds.
0 hours: 0 minutes: 15 Seconds.
0 hours: 0 minutes: 16 Seconds.
0 hours: 0 minutes: 17 Seconds.
0 hours: 0 minutes: 18 Seconds.
0 hours: 0 minutes: 19 Seconds.
0 hours: 0 minutes: 20 Seconds.
0 hours: 0 minutes: 21 Seconds.
0 hours: 0 minutes: 22 Seconds.
0 hours: 0 minutes: 23 Seconds.
0 hours: 0 minutes: 24 Seconds.
0 hours: 0 minutes: 25 Seconds.
0 hours: 0 minutes: 26 Seconds.
..... so on

Tom Carpenter

#11
Jul 29, 2012, 02:04 pm Last Edit: Jul 29, 2012, 02:06 pm by Tom Carpenter Reason: 1

Code: [Select]

void GetTimeRunning()
{
  currentmillis= millis(); 
  secs = currentmillis/1000; //convect milliseconds to seconds
  mins=secs/60; //convert seconds to minutes
  hours=mins/60; //convert minutes to hours
  days=hours/24; //convert hours to days
 secs=secs-(mins*60); //subtract the coverted seconds to minutes in order to display 59 secs max
 mins=mins-(hours*60); //subtract the coverted minutes to hours in order to display 59 minutes max
 hours=hours-(days*24); //subtract the coverted hours to days in order to display 23 hours max
}



Would this not be simpler:
Code: [Select]

void GetTimeRunning()
{
  currentmillis= millis(); 
  secs = currentmillis/1000; //convect milliseconds to seconds
  mins=secs/60; //convert seconds to minutes
  hours=mins/60; //convert minutes to hours
  days=hours/24; //convert hours to days
 secs %= 60; //remainder when divided by 60
 mins %= 60; //remainder when divided by 60
 hours %= 24; //remainder when divided by 24
}

~Tom~

PaulS

Quote
If you're going to cook something on the stove for an hour, you don't set your your time to midnight and wait until 1PM before you take it off the stove

I should hope not. It would be burnt to a crisp 13 hours later... 8)

Nick Gammon

... because the clock wrapped around.

You should have reset it to 12 when you started. Oh wait, it *was* at 12. <grin>
http://www.gammon.com.au/electronics

Arrch


Quote
If you're going to cook something on the stove for an hour, you don't set your your time to midnight and wait until 1PM before you take it off the stove

I should hope not. It would be burnt to a crisp 13 hours later... 8)


Wait, there is another way to cook food? Wish my wife knew that...  ]:)

Go Up