awesome EEPROM - Reset - overflow - Clock related question

Hello there. I have built a LCD clock using a free atmga8 chip from a nice seller; everything works well, but I do think after about 50 days, my arduino atmga8 's millis() will go back to zero. It is a problem for my clock, because I am planning to have my clock running all year long on an AC adapter; so I saw EEPROM, and I got an idea about reseting my arduino before 50 days, and use the EEPROM to update my clock automatically. Also, I have optiboot on my atmga8, so reset time is about 2 sec. Will this work?

int resetPin=10; //pin 10 is connected to a 1K resistor, and then to the resetPin; <pin 10----1k Ohm -----reset Pin>; already have a 10k pull up resistor connect to reset;

void setup (){
pinMode(resetPin, OUTPUT);
digitalWrite(resetPin, HIGH);

// startup, read the value from eeprom, and set my time
day=EEPROM.read (1); //day
hr=EEPROM.read (2); //hr
min=EEPROM.read (3); //min
halfday=EEPROM.read (4); //halfday

}

if(day==45){ // when it's 45 days, record the timer data, and then reset pin go low to reset my arduino;

EEPROM.write(1, day);
EEPROM.write(2, hr);
EEPROM.write(3, minn);
EEPROM.write(4, halfDay);
digitalWrite(resetPin, LOW);
}

No need to reset your arduino. If you write the code correctly then the roll over will not be an issue.

but I do think after about 50 days, my arduino atmga8 's millis() will go back to zero.

So what?
My wall-clock goes through zero (midnight) once a day, and it has yet to cause me to reset at 23:59 or whatever.

Please use code tags when posting code.

Grumpy_Mike:
No need to reset your arduino. If you write the code correctly then the roll over will not be an issue.

Here is my clock code. is it correct or work??

byte CK[8] = {
  0b00000,
  0b01110,
  0b10101,
  0b10101,
  0b10111,
  0b10001,
  0b01110,
  0b00000
};  

byte AU[8] = {
  0b00100,
  0b00100,
  0b01110,
  0b11111,
  0b00100,
  0b01110,
  0b01110,
  0b01010};

byte AR[8] = {
  0b01000,
  0b00100,
  0b00110,
  0b11111,
  0b11111,
  0b00110,
  0b00100,
  0b01000};
  
byte AL[8] = {
  0b00000,
  0b00100,
  0b01110,
  0b01110,
  0b01110,
  0b11111,
  0b00100,
  0b00000
};  

byte TI[8] = {
  0b00000,
  0b01110,
  0b00100,
  0b11111,
  0b00100,
  0b01010,
  0b10001,
  0b00000
};

  
#define au 0x01
#define ar 0x02
#define ck 0x03
#define al 0x04
#define ti 0x05

#define beep A5
#define led 7
#include "ClickButton.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(13,12,11,10,9,8);

//------------------------------------------------------------------------------------------------------

ClickButton ba(2, LOW, CLICKBTN_PULLUP); // cursor change -
ClickButton bb(3, LOW, CLICKBTN_PULLUP); // cursor change +
ClickButton bc(4, LOW, CLICKBTN_PULLUP); // okay button

int sec=0;
int minn=0;
int hr=0;
int day=0;

int asec=0;
int aminn=0;
int ahr=0;
int aday=0;

int timer=0;
int alarm=0;
char* sp="Start";

int state=0;

int menu=1;
int psmenu=1;

int post=1;
int pspost=1;

int arpost=0;
int xint=1000;
unsigned long nowtimer=0;
unsigned long pretimer=0;

unsigned long xnowtimer=0;
unsigned long xpretimer=0;

//------------------------------------------------------------------------------------------------------
void setup()
{

  lcd.begin(16,2); 
  lcd.createChar(1, AU);
  lcd.createChar(2, AR);  
  lcd.createChar(3, CK);
  lcd.createChar(4, AL);  
  lcd.createChar(5, TI);  
  pinMode(led, OUTPUT);
  pinMode(beep, OUTPUT);
  
  ba.multiclickTime = 50;
  bb.multiclickTime = 50;    
  bc.multiclickTime = 50; 
}


//------------------------------------------------------------------------------------------------------
void loop()
{
  ba.Update();
  bb.Update();  
  bc.Update(); 
 
  
  if(alarm==1){
  digitalWrite(beep, state);
  }
  else
  digitalWrite(beep, LOW);
  
  
  nowtimer=millis();
  if(nowtimer-pretimer>=1000) {
    sec++;    
    
    if(timer==1){
    asec--;
    }   

    pretimer=nowtimer;     
  }  
  
 
  xnowtimer=millis();
  if(xnowtimer-xpretimer>=xint) { 
   state=!state;   
   arpost++;    
   
   lcd.clear();
   xpretimer=xnowtimer;    
  }
  
  

  if(sec==60){  minn++;  sec=0; }
  if(minn==60){ hr++;  minn=0; }
  if(hr==24){ day++;  hr=0; }

  if(asec==-1){  aminn--;  asec=59; }
  if(aminn==-1){ ahr--;  aminn=59; }
  if(ahr==-1){ aday--;  ahr=23; }  
  if(aday==0 && ahr==0 && aminn==0 && asec==0 && timer==1) {timer=0; alarm=1;}
  
  if(arpost==16)arpost=0;
  
  
  if(timer==0){ 
    sp="Start";
    digitalWrite(led, LOW);
  }
  else {
    sp="Pause";
    digitalWrite(led, state);
  }
 

    if(menu!= psmenu){   //whenever menu changes, clear the lcd, set position back to 1;
    lcd.clear();  
    post=1;
    psmenu=menu;
    }
    
    if(post!=pspost){  //whenever position changes, clear the lcd;
    lcd.clear();
    pspost=post;
    }

  //========== menu 1 ====================== K 00  00:00:00 K
  if(menu==1){
    
    char buffer[17];
    sprintf (buffer, "%c %02d%c %02d:%02d:%02d %c", ck, day, ti, hr, minn, sec, ck);
    lcd.setCursor(0,0);
    lcd.print (buffer);
    
    switch( post ){
  
    case 1:
    lcd.setCursor (arpost,1); //right arrow location 0-15;
    lcd.write(ar);
    if(bb.clicks==1) xint-=200; 
    if(xint==200) xint=1000;
    break;
    
    case 2:
    lcd.setCursor (3,1);
    lcd.write(au);
    if(bb.clicks==1) day++;     
    break;    
    
    case 3:
    lcd.setCursor (7,1);
    lcd.write(au);
    if(bb.clicks==1) hr++;    
    break;

    case 4:
    lcd.setCursor (10,1);
    lcd.write(au);
    if(bb.clicks==1) minn++;  
    break;

    case 5:
    lcd.setCursor (13,1);
    lcd.write(au);
    if(bb.clicks==1)sec=0;  
    break;

    }
    
    if(post==6)post=1;
    
    if(bc.clicks==1) post++;
    if(bb.clicks==-1){ day=0; hr=0; minn=0; sec=0; }//long press reset   
  }
  

  //========== menu 2 ====================== 
  if(menu==2){
    
    char buffer[17];
    sprintf (buffer, "%c %02d%c %02d:%02d:%02d %c", al, aday, ti, ahr, aminn, asec, al);
    lcd.setCursor(0,0);
    lcd.print (buffer);
    
    switch( post ){
  
    case 1:
    if(alarm==0){
    char x[17];
    sprintf (x, "         [%s]", sp);
    lcd.setCursor (0,1);
    lcd.print(x);
    if(bb.clicks==1) timer=!timer; 
    }
    
    if(alarm==1){
    lcd.setCursor (0,1);
    lcd.print("(: Time is Up :)");  
    if(bb.clicks==1) {timer=0; alarm=0;} 
    }
    
    break;
    
    case 2:
    lcd.setCursor (3,1);
    lcd.write(au);
    if(bb.clicks==1) aday++;     
    break;    
    
    case 3:
    lcd.setCursor (7,1);
    lcd.write(au);
    if(bb.clicks==1) ahr++;    
    break;

    case 4:
    lcd.setCursor (10,1);
    lcd.write(au);
    if(bb.clicks==1) aminn++;  
    break;

    case 5:
    lcd.setCursor (13,1);
    lcd.write(au);
    if(bb.clicks==1)asec++;  
    break;

    }
    
    if(post==6)post=1;
    
    if(bc.clicks==1) post++;    
    if(bb.clicks==-1) {  aday=0; ahr=0; aminn=0; asec=0; alarm=0; timer=0; }//long press reset 
    
  }
  
  //================================  
  /*if(post>2) {if(ba.clicks==1) post=1;}
  if(post==1) {if(ba.clicks==1) menu++;}
  */
  
  if(ba.clicks==1) menu++;
  if(menu==3) menu=1;
  

  if(bb.clicks==-1);
  if(bc.clicks==-1);
}

//------------------------------------------------------------------------------------------------------

AWOL:

but I do think after about 50 days, my arduino atmga8 's millis() will go back to zero.

So what?
My wall-clock goes through zero (midnight) once a day, and it has yet to cause me to reset at 23:59 or whatever.

Please use code tags when posting code.

alright, you are right, but will this idea of resetting my arduino actually or by any chance works?

is it correct or work?

You're the one with it sitting in front of you - you tell us!

Yes, your 49day problem is no problem.

You may however experience an issue with using the arduino as a clock, as you will find out that it won't be accurate and you will be resetting the time very frequently (which could be weekly or monthly depending on the degree of which you may suffer from obsessive compulsive disorder).

Adding a nice Real Time Clock (RTC) is a very inexpensive way to add more fun and learning to your project. A decent one can be accurate to seconds in a year. Particularly so if you are proud of your new LCD clock. :blush:

AWOL:

is it correct or work?

You're the one with it sitting in front of you - you tell us!

but to test it, I have to wait 45 days sitting in front of it.

arduinomagbit:
but to test it, I have to wait 45 days sitting in front of it.

easy solution:

pay a friend to sit there for 45 days.

do something else for 45 days and look at it in the 46th day.

XD

but to test it, I have to wait 45 days sitting in front of it

No, you really don't - just offset the time to near the roll-over.

BulldogLowell:
Yes, your 49day problem is no problem.

You may however experience an issue with using the arduino as a clock, as you will find out that it won't be accurate and you will be resetting the time very frequently (which could be weekly or monthly depending on the degree of which you may suffer from obsessive compulsive disorder).

Adding a nice Real Time Clock (RTC) is a very inexpensive way to add more fun and learning to your project. A decent one can be accurate to seconds in a year. Particularly so if you are proud of your new LCD clock. :blush:

this is my timing code; when millis() reset back to 0; 0 - (a large number) will never >= 1000; RTC is too expensive for me, considering my atmga8 is free and I build this clock from old components, but I will try that out later.

  nowtimer=millis();
  if(nowtimer-pretimer>=1000) {
    sec++;    
    
    if(timer==1){
    asec--;
    }   

    pretimer=nowtimer;     
  }

You are fine with Unsigned integer subtraction as you have done. i'd look to exclude any drift in the millis() timer do to a small amount of blocking that may happen within the (updating your LCD for example, in this form:

nowtimer = millis();
  if(now timer - pre timer >= 1000) {
    sec++;    
    
    if(timer == 1){
    asec--;
    }   

    pretimer += 1000UL;     
  }

now when the timer resets, it adds exactly 1000 milliseconds, even if more than 1000 ms have elapsed (e.g. 1002milliseconds)

AWOL:

but to test it, I have to wait 45 days sitting in front of it

No, you really don't - just offset the time to near the roll-over.

Example...
http://forum.arduino.cc/index.php?topic=258158.msg1856807#msg1856807

AWOL:

but to test it, I have to wait 45 days sitting in front of it

No, you really don't - just offset the time to near the roll-over.

??

wouldn't that be then another 49 days from when you reset the time....

Offsetting millis moves the first rollover closer to now. The next rollover will be 49+ days from the first rollover. In other words, offsetting millis makes it much easier to test a single / the first rollover.

If you follow the link I posted there is another testing method that causes a rollover every 65536 milliseconds.

alright, you are right, but will this idea of resetting my arduino actually or by any chance works?

No it will not work.

This is because as soon as the reset happens the pin gets turned into an input and therefore stops providing a low to the reset pin. The reset pin will not have been low long enough to complete a reset and so the processor will hang.

There are ways round that using external components like a monostable or some capacitors, but as you don't even want to go there then their is little point saying how it is done.