Date & time goes off

Hi,
I've uploaded a sketch containing most of the example date & time sketch and synced it up via processing. The Duemilanove 328 is connected to a wall plug and has not been unplugged. The date & time was fine for a little while - maybe 20 minutes or less. But now it suddenly shows a different month & time on the LCD and changes every few minutes.
What would cause the date to suddenly change?
Could this be power related issue? (I don't think so, but do have 2 temp sensors hooked up as well)
This is my first time using date & time.
Thanks :slight_smile:

Perhaps the serial port is getting bad data that its trying to sync to.

Can you post your sketch.

Here is my sketch.
When the date/time go bad it is no longer connected to my computer, but is already running and working fine.

/*
 * A simple sketch that uses WiServer to send a tweet with the current system time every 5 minutes
 */

#include <DateTime.h>
#include <DateTimeStrings.h>
#include <LiquidCrystal.h>

//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(4, 3, 8, 7, 6, 5);
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  255   // Header tag for serial time sync message
char temp_val[3];
char temps[3] ="";
char* weather = " ";
int inPin = 5;   // select the input pin for analog temp value 5= out, 4 = in.
int inVal;  
int i;
int samples[8];
int t=0;
int ti=0;
char n[6] = " ";
int x=0;
char* place=" ";
int r;
int inVal3=0;
int samples2[8];
int counter=0;
int custom_0[] = {0x0e, 0x0e, 0x04, 0x0e, 0x1b, 0x0a, 0x0e, 0x11};



// Define a custom char in lcd
int defineCharacter(int ascii, int *data) {
    int baseAddress = (ascii * 8) + 64;  
    // baseAddress = 64 | (ascii << 3);
    lcd.command(baseAddress);
    for (int i = 0; i < 8; i++)
        lcd.write(data[i]);
    lcd.command(128);
    return ascii;
} 

void setup() {
Serial.begin(57600);
defineCharacter(0, custom_0);
lcd.begin(16,2);
lcd.print("Robo Temp 3000");
lcd.setCursor(0,1);
lcd.print((char)229);
lcd.print(" ");
lcd.print((char)224);
lcd.print(" ");
lcd.print((char)225);
lcd.print(" ");
lcd.print((char)226);
lcd.print(" ");
lcd.print((char)227);
lcd.print(" ");
lcd.print((char)218);
lcd.print(" ");
lcd.write(0);
delay(2000);
}

void TempWrit()
{
  lcd.setCursor(0, 0);
  lcd.clear();
  lcd.print(place);
  lcd.print(" temp ");
  lcd.print(x);
  lcd.print((char)223);
  lcd.print(" F.");
  lcd.setCursor(0,1);
  lcd.print(weather);
  delay(2500);
// lcd.setCursor(16,1);
//lcd.autoscroll();
//  for (int thisChar = 0; thisChar < 16; thisChar++) {
//    lcd.print(" ");
 //   delay(400);
  //   }
 lcd.clear();
 // lcd.noAutoscroll();
}

void WeatherOut()
{
  inPin = 5;
for(i = 0;i<=7;i++) // gets 8 samples of temperature
 { 
 samples[i]= ( 5.0 * analogRead(inPin) * 100.0) / 1024.0;
 inVal = inVal + samples[i];
 }
  inVal = inVal/8.0; // better precision
  t = ((inVal * 9)/ 5 + 32);    
Serial.print("Weather out ");  
Serial.println(t); 
  inVal = 0;        //reset variable
  x=t;
  itoa(t,temp_val,10);
  place="Out";
}

void WeatherIn()
{
  inPin = 4;
for(i = 0;i<=7;i++) // gets 8 samples of temperature
 { 
 samples[i]= ( 5.0 * analogRead(inPin) * 100.0) / 1024.0;
 inVal = inVal + samples[i];
 }
  inVal = inVal/8.0; // better precision
  ti = ((inVal * 9)/ 5 + 32);                       
  inVal = 0;                                //reset variable
  x=ti;
  itoa(ti,temp_val,10);
  place="In";
  }
  
 void GetSun() {
 // photocellReading = analogRead(3);  
  for(i = 0;i<=7;i++) // gets 8 samples of temperature
 { 
 samples2[i]= (analogRead(3));
 inVal3 = inVal3 + samples2[i];
 }
 inVal3 = inVal3/8.0; // better precision with 8 samples

 if (inVal3 < 8) {
    weather = "Night Time";
  } else if (inVal3 < 110) {
   weather = "Cloudy";
  } else if (inVal3 < 200) {
    weather = "Partly Cloudy";
  } else if (inVal3 < 280) {
weather="Partly Sunny";
  } else {
   weather = "Sunny";
  }
  Serial.print("Sun level ");
 Serial.print(inVal3);
 Serial.print(" ");
 Serial.println(weather);
}

void loop()
{
  //update time
  unsigned long  prevtime;
  if( getPCtime()) {  // try to get time sync from pc
    Serial.print("Clock synced at: ");
    Serial.println(DateTime.now(),DEC);
  }
  if(DateTime.available()) { // update clocks if time has been synced
    digitalWrite(13,LOW);  // first flash the LED
    prevtime = DateTime.now();
    while( prevtime == DateTime.now() )  // wait for the second to rollover
        ;
    DateTime.available(); //refresh the Date and time properties

    // send our time to any app at the other end of the serial port
    Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
    Serial.println(DateTime.now());counter++;
  }
    
  if (counter>=4)
  {
    lcd.clear();
    lcd.print ("Robo Temp 3000");
    lcd.setCursor(0,1);
    lcd.print((char)229);
lcd.print(" ");
lcd.print((char)224);
lcd.print(" ");
lcd.print((char)225);
lcd.print(" ");
lcd.print((char)226);
lcd.print(" ");
lcd.print((char)227);
lcd.print(" ");
lcd.print((char)218);
lcd.print(" ");
lcd.write(0);  
 counter=0;
    delay(2000);
    lcd.clear();
     }
      WeatherOut();
      GetSun();
      TempWrit();
      WeatherIn();
      weather=" ";
      TempWrit();
digitalClockDisplay( );   // update digital clock
}
boolean getPCtime() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    if( Serial.read() == TIME_HEADER ) {        
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        char c= Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      DateTime.sync(pctime);   // Sync Arduino clock to the time received on the serial port
      return true;   // return true if time message received on the serial port
    }  
  }
  return false;  //if no message return false
}
void digitalClockDisplay(){
  lcd.clear();// digital clock display of current date and time
  Serial.print(DateTime.Hour,DEC);
  lcd.print(DateTime.Hour,DEC);
  printDigits(DateTime.Minute);
  Serial.print(" ");
  lcd.print(" ");
  Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
  lcd.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
   Serial.print(" ");
   lcd.print(" ");
  Serial.print(DateTimeStrings.monthStr(DateTime.Month));
  lcd.setCursor(0,1);
  lcd.print(DateTimeStrings.monthStr(DateTime.Month));
   Serial.print(" ");
  lcd.print(" ");
    Serial.println(DateTime.Day,DEC); 
   lcd.print(DateTime.Day,DEC); 
   
    delay(2500);
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  lcd.print(":");
  if(digits < 10)
  {
    Serial.print('0');
    lcd.print('0');
  }
  Serial.print(digits,DEC);
   lcd.print(digits,DEC);
 
}

Pauly, you will have a problem if the temperature goes above 99 degrees (your buffer only holds two digits plus the terminating null) but I guess that may not be the issue here.

Can you check the wall wart and see how much voltage it is feeding to Arduino. The LCD backlight draws a lot power and the onboard regulator may be overheating.

If thats not it, try commenting out the following lines in loop:

/* temporarily comment out these lines:
WeatherOut();
GetSun();
TempWrit();
WeatherIn();
weather=" ";
TempWrit();
*/

This will tell us if we need to look at those functions or somewhere else

Ok, I commented out the lines you suggested and still received the same results, so it is not that part of the code.
My wall wart is giving me 9 volts.
I have the lcd (usually the backlight is on), 2 temp sensors, 1 light resist sensor and 1 led hooked up. Do you think it is a power issue?

When running from the wall wart does the voltage regulator (a chip near the power socket) get hot?

does the problem occur when powered from usb?

The same problem occurs when powered via USB without any sensors or leds added, so I'm guessing it is not power related, but code related.

a good test would be to run the DateTime example code to see if that has a similar problem.

My thoughts exactly. I ran the example code and it has the same problem. After about 10-15 minutes it changes the date and time to something incorrect. I tested it on a Diecimilia 328.
Not sure what to do now if the example doesn't work. :-?

// DateTime.pde
// example sketch for the DateTime library

#include <DateTime.h>
#include <DateTimeStrings.h>

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  255   // Header tag for serial time sync message

void setup(){
  Serial.begin(19200);
  pinMode(13,OUTPUT); // we flash the LED each second
}

void  loop(){
  unsigned long  prevtime;
  if( getPCtime()) {  // try to get time sync from pc
    Serial.print("Clock synced at: ");
    Serial.println(DateTime.now(),DEC);
  }
  if(DateTime.available()) { // update clocks if time has been synced
    digitalWrite(13,LOW);  // first flash the LED
    prevtime = DateTime.now();
    while( prevtime == DateTime.now() )  // wait for the second to rollover
        ;
    DateTime.available(); //refresh the Date and time properties
    digitalClockDisplay( );   // update digital clock

    // send our time to any app at the other end of the serial port
    Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
    Serial.println(DateTime.now());
    digitalWrite(13,HIGH);
  }
  delay(100); 
}

boolean getPCtime() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    if( Serial.read() == TIME_HEADER ) {        
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        char c= Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      DateTime.sync(pctime);   // Sync Arduino clock to the time received on the serial port
      return true;   // return true if time message received on the serial port
    }  
  }
  return false;  //if no message return false
}

void digitalClockDisplay(){
  // digital clock display of current date and time
  Serial.print(DateTime.Hour,DEC);
  printDigits(DateTime.Minute);
  printDigits(DateTime.Second);
  Serial.print(" ");
  Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
  Serial.print(" ");
  Serial.print(DateTimeStrings.monthStr(DateTime.Month));
  Serial.print(" ");
  Serial.println(DateTime.Day,DEC); 
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits,DEC);
}

Perhaps we can tell something from the data. Can you paste a fragment of the output showing the last few correct times and then a bunch of incorrect times.

Hi,
I've posted data received from the Serial Monitor
and from Processing as they are slightly different.

Arduino Serial Monitor

Clock synced at: 1254422090

18:34:ber 1

ÿ1254422091

18:34:52 Thursday Oc18:34:ursday October 1

ÿ1254422093

18:34:54 Thursday Oc18:34:2095

18:35:41 Thursday October 1
18:35:42 Thu18:35:43 Thursday October 1
18:35:44 Thu11:38:50 Fri11:38:5232

11:38:53 Friday November 20

ÿ1258717133

11:38:5ovember 20

ÿ1258717134

11:38:55 Friday Novemberÿ1258717135

Processing

Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
[0] "/dev/tty.modem"
[1] "/dev/cu.modem"
[2] "/dev/tty.usbserial-A40014V7"
[3] "/dev/cu.usbserial-A40014V7"
 Connecting to -> /dev/tty.usbserial-A40014V7
51 Thursday Octotober 1


[ch711]1254422092


53 Thtober 1


[ch711]1254422094


55 Thursday October 1


[ch711]125442tober 1


[ch711]1254422096
rsday October 1


[ch711]1254422144


day November 20


[ch711]1258717131


 Friday November 20


[ch711]125871714 Friday N 20


er 20

You seem to be losing characters from the serial messages. Here is a test sketch that increments and prints a count every second. The header is sent so you can use the Processing sketch to view the output there to check it's the same as on the Arduino Serial monitor. If you don't see the numbers increase in sequence every second then perhaps there is some problem with your board or the serial connection.

#define TIME_HEADER  255 
unsigned long count = 1254422090;  // a starting count 

void setup(){
  Serial.begin(19200);
  pinMode(13,OUTPUT); // we flash the LED each second
}

void  loop(){  
   digitalWrite(13,LOW);  // first flash the LED
   delay(500);
   digitalWrite(13,HIGH);  
   delay(500);
   Serial.print( TIME_HEADER,BYTE);
   Serial.println(count);
   count = count + 1;
}

I get a perfect sequence of numbers in Arduino Serial monitor when running your sketch. Haven't tried Processing yet.

Try this, it's similar to the code from the playground example but it does not use any data from the serial port to set the time. If this sequences ok then you need to look at what is coming down the serial port.

#include <DateTime.h>
#include <DateTimeStrings.h>

#define TIME_HEADER  255 
unsigned long count = 1254422090;  // a starting count 

void setup(){
  Serial.begin(19200);
  pinMode(13,OUTPUT); // we flash the LED each second
  DateTime.sync(count);
}

void  loop(){  
  unsigned long  prevtime;  
  
  prevtime = DateTime.now();
  while( prevtime == DateTime.now() )  // wait for the second to rollover
  {
     digitalWrite(13,!digitalRead(13));  //  toggle the LED
     delay(250);
  }      
  DateTime.available(); //refresh the Date and time properties
  digitalClockDisplay( );   // update digital clock
  Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
  Serial.println(DateTime.now());
 
  while(Serial.available() ) 
    Serial.print((char)Serial.read()) ;
  Serial.println();  
}

void digitalClockDisplay(){
  // digital clock display of current date and time
  Serial.print(DateTime.Hour,DEC);
  printDigits(DateTime.Minute);
  printDigits(DateTime.Second);
  Serial.print(" ");
  Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
  Serial.print(" ");
  Serial.print(DateTimeStrings.monthStr(DateTime.Month));
  Serial.print(" ");
  Serial.println(DateTime.Day,DEC); 
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits,DEC);
}

The code will print incoming serial data in this format:

18:35:28 Thursday October 2
ÿ1254422128

18:35:29 Thursday October 2
ÿ1254422129

18:35:30 Thursday October 2
ÿ1254422130
asdfasdf << this is data received on the serial port
18:35:31 Thursday October 2
ÿ1254422131

Your latest code is sequencing correctly.
How do I look at what is coming down the serial port?

The code I posted echoes characters to the serial monitor, see my previous post. You can enhance the Serial.print statement that handles the echoed characters if you want to make this output easier to see.