Resetting millis()

Probably a short question.

I'm trying to reset millis() in Arduino (0017).
I looked at the following topic:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167861718

This explains me that with the help of

extern volatile unsigned long timer0_overflow_count;
timer0_overflow_count = 0;

I can reset millis().

However, when I try

extern volatile unsigned long timer0_overflow_count;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.println(millis());
  if(millis() > 1000)
  {
    timer0_overflow_count = 0;
  }
  delay(100);
}

It does not work. millis() keeps incrementing.
If I directly read timer0_overflow_count it reports the following in a serial monitor:

0
99
99
98
99
98
99
99
98
etc...

What am I missing?

I am using an Atmega168.

Thanks in advance!

Probaby a simple question - why?

I have this program that runs on 4 different 'agents'.
Together, these 4 agents form a game that lasts for about 60 seconds.

  1. They have to send each other whether they are powered and then all must sync their timers. If I could reset millis() on command, this would solve the problem.

  2. Also, I use an operation of
    millis() % gameDuration
    to cause millis to be constrained to 0 to 60 seconds. I could also simply reset millis() after 60 seconds if possible.

  3. I also use a sleep state that kicks in after 60 seconds. During this sleep state, millis does not increment, resulting in other difficulties.

All of these could have been overcome if I could just reset the millis() timer. I could also try and do without, but this would result in a formula that has to take 8 variables into account.

Nevermind guys,

I have solved it by making a custom function of millis() that can be reset.

Zwaf, can you give me your function. I need to reset Millis too for the long life PID usage. Thanks.

It does not work. millis() keeps incrementing.

The way I see it is that it works just fine.

You have a 100ms delay after resetting the value and so should expect to print a millis() value around 100 each time through the loop.

You should disable interrupts while resetting the overlfow counter however to make it reliable.

Probaby a simple question - why?

I second that!

You second my typo? ;D

I third your typo!

Hello I want to know to how you guys were able to resolve this. In my case I had to do a custom form of delaying since the maximum delay that the Delay() function can handle is just 30seconds. I'm doing a logging systems that logs hourly. Another odd this is that My Arduino is getting crippled by the 9 hour rollover issue when it fact the millis() function has already been updated to last for 55 days... what am I missing here?

Hello I want to know to how you guys were able to resolve this. In my case I had to do a custom form of delaying since the maximum delay that the Delay() function can handle is just 30seconds. I'm doing a logging systems that logs hourly. Another odd this is that My Arduino is getting crippled by the 9 hour rollover issue when it fact the millis() function has already been updated to last for 55 days... what am I missing here?

If you look at the blink without delay sketch in the Arduino IDE digital examples you will see that there is no reason to use delay(), it's a rather primitive and blocking function that is best not used these days.

As far as your 9 hour rollover, are you aware that millis() returns a long value, sounds like you may be assigning it to a int variable rather then a long variable?

Lefty

the maximum delay that the Delay() function can handle is just 30seconds

Really? You sure?

Oh sorry about the delay yeah it was more than 30s but my concern is that I want to be able to override that delay in case I want to do something else.

Here's my code

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Wire.h>
#include <math.h>
#include <WProgram.h>
#include <DS1307.h>
#include <ctype.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

int r0 = 0; //value select pin at the 4051 (s0)
int r1 = 0; //value select pin at the 4051 (s1)
int r2 = 0; //value select pin at the 4051 (s2)
int row = 0; // storeing the bin code
int count = 0; // just a count
int bin [] = {000, 1, 10, 11, 100, 101, 110, 111};

int state;
char name [32];
char sb;
unsigned long time;
int buttonState = 0;
extern volatile unsigned long timer0_overflow_count;

void setup(void)
{
Serial.begin(9600);
analogWrite(5,255);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(10, OUTPUT);
card.init();
volume.init(card);
root.openRoot(volume);
sprintf(name,"%d%d%d.CSV",RTC.get(DS1307_DATE,true),RTC.get(DS1307_MTH,true),RTC.get(DS1307_YR,true));
}
void loop(void){

timer0_overflow_count=0;
unsigned long loopStart=millis();
unsigned long waitTime = loopStart + 30000; //30mins

buttonState = digitalRead(6);

if (buttonState == HIGH) state=1;
else if(buttonState == LOW) state=0;
else state = 0;

if(Serial.available())
{
sb = Serial.read();
if(sb=='v')
{
//some code here
}
}
if(state==1);
{
//some code here
}
//if(!Serial.available()&&!buttonState==LOW) delay(30000);

do
{
//subroutine
}
while(millis()<waitTime&&!Serial.available()&&!buttonState==LOW);

}

unsigned long waitTime = loopStart + 30000;  //30mins

30000 milliseconds is not 30 minutes.

I'm sorry about that that was modded but it used to be 180000... This code get affected by the 9 hour rollover... Why is that...

There is no 9 hour rollover - what version of the IDE are you using?

I'm using 0018... and here is the whole code

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Wire.h>
#include <math.h>
#include <WProgram.h>
#include <DS1307.h>
#include <ctype.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

int r0 = 0; //value select pin at the 4051 (s0)
int r1 = 0; //value select pin at the 4051 (s1)
int r2 = 0; //value select pin at the 4051 (s2)
int row = 0; // storeing the bin code
int count = 0; // just a count
int bin [] = {000, 1, 10, 11, 100, 101, 110, 111};

int state;
char name [32];
char sb;
unsigned long time;
int buttonState = 0;
extern volatile unsigned long timer0_overflow_count;

double getVoltage(int pin)
{
double vin;
int value =analogRead(pin);
vin = ((value * 5.0) / 1024.0)*((110.0 + 230.0)/110.0);
return vin;
}
double Thermister(int pin)
{
float Temp;
int RawADC = analogRead(pin);
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15; // Convert Kelvin to Celcius
return Temp;
}

void setup(void)
{

Serial.begin(9600);
analogWrite(5,255);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(10, OUTPUT);
card.init();
volume.init(card);
root.openRoot(volume);
sprintf(name,"%d%d%d.CSV",RTC.get(DS1307_DATE,true),RTC.get(DS1307_MTH,true),RTC.get(DS1307_YR,true));
}
void loop(void){

timer0_overflow_count=0;
unsigned long loopStart=millis();
unsigned long waitTime = loopStart + 30000;

buttonState = digitalRead(6);

if (buttonState == HIGH) state=1;
else if(buttonState == LOW) state=0;
else state = 0;

if(Serial.available())
{
sb = Serial.read();
if(sb=='v')
{
Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
Serial.print(":");
Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
Serial.print(":");
Serial.print(RTC.get(DS1307_SEC,false));//read seconds
Serial.print("\t"); // some space for a more happy life
Serial.print(RTC.get(DS1307_DATE,false));//read date
Serial.print("/");
Serial.print(RTC.get(DS1307_MTH,false));//read month
Serial.print("/");
Serial.print(RTC.get(DS1307_YR,false)); //read year
Serial.println();
Serial.print("verify state: ");
Serial.println(state);
Serial.print("verify time: ");
Serial.print(RTC.get(DS1307_HR,true));
Serial.print(":");
Serial.print(RTC.get(DS1307_MIN,false));
Serial.print(":");
Serial.println(RTC.get(DS1307_SEC,false));
Serial.print("temperature: ");
Serial.println(Thermister(1));
for (count=0; count<1; count++) {
row = bin[count];
r0 = row & 0x01;
r1 = (row>>1) & 0x01;
r2 = (row>>2) & 0x01;
digitalWrite(2, r0);
digitalWrite(3, r1);
digitalWrite(4, r2);
Serial.print("v");
Serial.print(count);
Serial.print(": ");
Serial.println(getVoltage(0));
}
}
}
if(state==1);
{
file.open(root, name, O_CREAT | O_APPEND | O_WRITE);
file.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
file.print(":");
file.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
file.print(":");
file.print(RTC.get(DS1307_SEC,false));//read seconds
file.print(" "); // some space for a more happy life
file.print(RTC.get(DS1307_DATE,false));//read date
file.print("/");
file.print(RTC.get(DS1307_MTH,false));//read month
file.print("/");
file.print(RTC.get(DS1307_YR,false)); //read year
file.print(",");
for (count=0; count<1; count++) {
row = bin[count];
r0 = row & 0x01;
r1 = (row>>1) & 0x01;
r2 = (row>>2) & 0x01;
digitalWrite(2, r0);
digitalWrite(3, r1);
digitalWrite(4, r2);
file.print(getVoltage(0));
file.print(",");
}
//file.println();
file.print(Thermister(1));
file.print(",");
file.println(millis());
file.close();
}
//if(!Serial.available()&&!buttonState==LOW) delay(30000);

do
{
//subroutine
}
while(millis()<waitTime&&!Serial.available()&&!buttonState==LOW);

}

And we experienced it twice that if we leave the Arduino running for more than 8 hours the SD card losses all information and becomes blank. I'm using a 2GB sd card

if (buttonState == HIGH) state=1;  
 else if(buttonState == LOW) state=0;
 else state = 0;

There is no else. buttonState is either HIGH (1) or LOW (0). So, state == buttonState, retardless of what buttonState is.

10240000

With no qualifier on the end, like UL (unsigned long), constants are considered to be integers. The value far exceeds what can be stored in an integer.

0.0000000876741

The value is far too small to be represented as a discrete float value. It will be treated as 0.

It would appear that you are expecting more of the poor little Arduino than it is capable of.

Hmm so will changing 30000 to 30000UL instead fix the problem?

How come it becomes 1024000? I didn't quite understand sir... I'm just doing a digitalRead cause I made a switch to start and stop logging

millis() returns an unsigned long. The return value needs to be stored in a variable of the correct type. Otherwise, truncation or overflow can occur, as you have experienced.

I'm just doing a digitalRead cause I made a switch to start and stop logging

What values can digitalRead return? HIGH or LOW. There are no other choices. The pin is either HIGH or it is LOW. If it isn't HIGH, it MUST be low. There is no other choice.