Time library

Can anyone get my in touch with the person/people who wrote the Time Library?
I may, or may not, have found a bug or at least have a reproducible error in a specific situation.

Why not post the issue/code here, and let others help evaluate the potential problem?

Hi rdrink, I am the author of the time library. You can post a description of the issue along with the code that reproduces the problem here and I will try to help

**** UPDATE ****
I commented out the following code from the setup loop and the spaces went away. Is this something I can do without? :slight_smile:

setSyncProvider(requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");

mem,

Per my previous email here is a snippet of code that I'm having a problem with. I've delete most everything in the main loop and I'm still getting three "space character" printed in the serial monitor where the "now()" functions are called. Actually in pasting the output from the serial monitor below I see that, at least when the lines are pasted, they are some funky character. Needless to say these "spaces" being printed on the serial monitor as the program loops seriously messes up my display.

Question on the download libraries, do the go in the libraries folder under "My Documents" or the libraries folder with the Arduino software?
.
xaaa2827x
xaaa2827x
xaaa2827x
.

#include <Time.h>
#include <Wire.h> 
#include <DS1307RTC.h> 

// include the X10 library files:
#include <x10.h> 
#include <x10constants.h>

// define the Timer library variables
#define TIME_MSG_LEN 11    // Time synce to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER 'T'    // Head tag for serial time sync message
#define TIME_REQUEST 7     // ASCII bell character requests a time synce message




#define zcPin 6         // the zero crossing detect pin (black wire)
#define dataPin 7       // the X10 data out pin (Yellow wire)
#define repeatTimes 2   // how many times each X10 message should repeat
                        // in an electrically noisy environment, you  
                        // can set this higher.
#define BuzzerPin 31                        
#define On true
#define Off false



boolean FirstTimeThrough = true;  // Allow X10 commands to be sent on first pass through 
                                  // the code to itialize all values and states. Set to
                                  // false at end of file.

int Light            = 1;         
int Dark             = 0;  
int LightDarkMode    = 1;
                
const int OutsideLightLevelPin = A2;                        
int OutsideLightLevel = 0;

const int OutsideTempPin = A3;
int OutsideTemp = 0;
int OutsideTempRaw = 0;
int BackBasementMotion = 0;
int GarageMotionState = 0;
int LastGarageMotionState = 0;
int GarageMotionCounter = 0;

long previousMillis = 0;     // Will store last time loop was updated
long interval = 1000;        // Time of 1 second loop in milliseconds
long X10RefreshInterval = 5000 ; // X10 refresh intrval time

long TimerFrontYard = 0;     // One second counter
long TimerBackBasement = 0;  // One second counter
long CurrentTime = 0;        // Number of seconds from 01/01/1970
long PreviousTime = 0;       // 

boolean SwitchState = 0;
boolean NewSwitchState = 0;
int EntrywayMotion = 0;

x10 myHouse =  x10(zcPin, dataPin); // set up a new x10 library instance:

boolean X10_C1 = Off;              // Applilance module - ceramic heater in bathroom
boolean X10_L4 = Off;              // X10 Lamp switch module - Front porch light
boolean X10_L5 = Off;              // X10 Lamp switch module - Front yard light
boolean X10_L14 = Off;             // X10 Lamp module (screw in) - Back basement

// Arduino Setup Function
void setup() {
   
  Serial.begin(9600);
 
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet) { 
//     Serial.println("Unable to sync with the RTC");
    }  
  else {
//     Serial.println("RTC has set the system time");
    }
  setSyncProvider(requestSync);  //set function to call when sync required
 // Serial.println("Waiting for sync message");
    
} // End of Arduio Setup Function

// *************************************
// Main Program Loop
// *************************************
void loop() {

  // Refresh_X10();  
   PreviousTime = CurrentTime;
   Serial.print("x");
   CurrentTime = now();
   time_t t = now();
   Serial.print(minute());
  Serial.print(second(t));
   Serial.print("x");
   Serial.println("");
   
   FirstTimeThrough = false;
   
} // End of Main Program Loop

// ************************************************************


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

void processSyncMessage() {
  // 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
    char c = Serial.read() ; 
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

time_t requestSync()
{
  Serial.print(TIME_REQUEST,BYTE);  
  return 0; // the time will be sent later in response to serial mesg
}

Sorry for not posting my code in a window. I'll have to figure out how to do that.

Sorry for not posting my code in a window. I'll have to figure out how to do that.

You can modify your post to fix it. Select all your code, then press the button with the # symbol on it (4th from the right on the second row of buttons above the text box.

What do you have supplying time to the Arduino via the serial port?

I have a DS1370 Real Time Clock Module from Sparkfun Electronics.

I have a DS1370 Real Time Clock Module from Sparkfun Electronics.

Does this send data to the serial port? Most do not. Most are I2C devices.

It's a I^2C device.

But your time sync function is reading serial data. Why?

Because I don't know what I am doing? :slight_smile: So I take it the function I commented out tries to read the time from the serial port (serial console)? The only one I really need is the RTC function that read the time data from the I^2C buss?

Hi crites, the arduino clock is synchronized by the RTC with this call:
setSyncProvider(RTC.get); // the function to get the time from the RTC

so the requestSync function is not needed, you can remove the following line:
setSyncProvider(requestSync); //set function to call when sync required

You can also remove the processSyncMessage() function, its purpose is to set the Arduino time from serial messages but you are using the RTC to do that so its not needed.

Thanks mem, I think I have it under control. I am trainable. :slight_smile:

rdrink, sorry for hi jacking your thread.

@crites yes you kind of did (but I'm glad you got your question answered)
@PaulS, @mem I didn't post code because it's not exactly a code based problem. Hopefully a description will suffice:
For a current project I am using the time library to send sensor data at the top of the minute, complete with a timestamp from the values from Time.h
So far this has been working fine and I have been able to run it for a long time (days) with no problems. I then decided that I wanted to start storing the sensor values in case I needed to resend them and so I set up an array for storage. This is where the problem begins: leaving the code to run for a while, as the array begins to fill the date values start changing, eventually resetting to 1/1/70.
At first I thought the problem was my own but when I couldn't fix it I simply removed the function that wrote to the array, and the date was once again fine.
So it seems, although I have no idea how one would prove this, that writing to an array is clobbering the variables (memory space?) of the Time library. I've looked at the C code for something obvious (like duplicate variable names) but can't see a reason. So @mem I thought I'd contact you and see if you might have some insight.
I'm not sure I kept any of the broken code, but because it was fairly reproducible I'll see if I can break it again.

@rdrink, from your description it does sound like a problem with something overwriting memory.

There is no reason why time values cannot be reliably stored in an array, that’s how the companion time alarms library works.

If you can post a sketch that duplicates the problem then perhaps we can help get it working.

@mem
In classic fashion as soon as I tried to reproduce the problem I found the error in my code! But subtle enough to make it worth posting for others

#include <Time.h>  
int curr_min, prev_min;

int store[15]; // array for storing elements
int store_count = 0; // keep track of storage
boolean ack = false;

// store values in array 
void saveVal(int val){
  store[store_count] = val; 
  //store[store_count%15] = val;
  store_count = store_count+1; // increment index
}


// make rand value
int rand(){
  return int(random(500,12345));
}


// Format time 
String getTime() {
  int h = hour();
  int m = minute();
  int s = second();
  String h_string = (String)h;
  String m_string;
  String s_string;
  if(m <= 9) { 
    m_string = "0" + (String)m; 
  } 
  else { 
    m_string = (String)m; 
  }
  if(s <= 9) { 
    s_string = "0" + (String)s; 
  } 
  else { 
    s_string = (String)s; 
  }
  String time_string = h_string+":"+m_string+":"+s_string;
  return time_string;
}


////
void setup(){
  Serial.begin(9600);
  setTime(1296915473); // the time I wrote this
}

void loop(){
  // write time value to array
  if(second()%10 == 0){
    curr_min = minute();
    //if(curr_min != prev_min){
      prev_min = minute(); 
      int new_val = rand();
      saveVal(new_val); 
      String date_time = (String)month() + "/" + (String)day() + "/" + (String)year() + " " + getTime();
      Serial.println(date_time);
    //}
    delay(9000);
  }
}

Run this code and after a few minutes you'll see the date values go wonky.
If you look at the storeVal function you'll see that I am incrementing the array. However note that the array is a static 15 elements, yet I forgot to reset my incrementer, so after 15 ticks or so these stored values go wandering off into the memory space used by the Time library thus corrupting the data!
The fix is in the second line of the storeVal function (commented out) where store_count%15 prevents walking off the end of the array. Swap it for the one above and everything is fine.

mem I'm posting this just in case you ever get reports of corrupt time data you'll know something to look for.

-rd

@rdrink, good to hear you found the problem.

One tip that makes it easier to ensure that all references to an array will respect the number of elements is to use a constant.
For example:

const int nbrElements = 15;
int store[nbrElements]; // array for storing elements


  store[store_count % nbrElements] = val;

hi there

i am trying to re-write the code for that

with time library

in the old schect i was calculating time like that

for ( months = Start_month ; months <= 12 ; months++ ){
for (days = Start_day ; days <= 31 ; days++ ){
for( hours = Start_hour ; hours < 24 ; hours++){
for ( minutes = Start_minute ; minutes < 60 ; minutes++){
for( seconds = Start_second; seconds < 60; seconds++){

Second_calc = millis();

Check_Bell();

if ( ( seconds < 10 ) || ( ( seconds >= 30 ) && ( seconds < 40 ) ) ) Print_Time();
if ( ( ( seconds >= 10 ) && ( seconds < 20 ) ) || ( ( seconds >= 40 ) && ( seconds < 50 ) ) ) Print_Temp();
if ( ( ( seconds >= 20 ) && ( seconds < 30 ) ) ) Print_Date();
if ( ( ( seconds >= 50 ) && ( seconds < 60 ) ) ) Print_Year();

if ( ( ( seconds < 10) || ( ( seconds >= 30 ) && ( seconds < 40 ) ) ) && ( seconds % 2 == 0 ) ) digitalWrite(dot,HIGH);
if ( ( ( seconds < 10) || ( ( seconds >= 30 ) && ( seconds < 40 ) ) ) && ( seconds % 2 == 1 ) ) digitalWrite(dot,LOW);

W_eeprom();

while( ( Second_calc + 1000 ) > millis() ){
if ( millis() < Second_calc ) break;
}
}
Start_second = 0;
}
Start_minute = 0;
}
Start_hour = 0;
delay(2995);
if ( ( months == 4 || months == 6 || months == 9 || months == 11 ) && ( days == 30 ) ) days++;
if ( ( months == 2 ) && ( days == 28 ) && ( ( year % 4 ) != 0 ) ) days = days + 10;
if ( ( months == 2 ) && ( days == 29 ) && ( ( year % 4 ) == 0 ) ) days = days + 10;
}
Start_day = 1;
}
Start_month = 1;
year++;
}

but now i am using time library

i set the time in the setup

setTime(CurrentHour,CurrentMinute,CurrentSecond,CurrentDay,CurrentMonth,CurrentYear);

and in setup also

setSyncInterval(63072000);// almost two years

but after 5 minutes the clock returns to CurrentHour,CurrentMinute,CurrentSecond,CurrentDay,CurrentMonth,CurrentYear

why?

any ideas?