RTC + Arduino clock + scheduler

Hello All,

Seems i suck at searching the forums for info i need so apologies if this info is somewhere else.

Basically i am wanting to make a scheduled relay activator. I have looked around for schedulers but supprisingly have not found much. Anyway my few questions are below.

I have added some code to sync my arduino time with the connected RTC module. I obviously need to do this to restore the arduino time if power is cut. My first question is how often should i sync the RTC time to the Arduino board when running continuasly? Further to that later i am going to have to make something to sync the RTC time from my PC how often should i be doing this? - This part is running off a DS1307 and the TimeAlarms.h library alternative suggestions are welcome.

Below is what i have put together so far. Not really required to answer my question. Basically it is a mix of hte TimeAlarmExample and some Ds1307 code to sync the onboard arduino clock with the RTC and fire some preset/hardcoded example alarms. UNTESTED at this time.

/*
 * TimeAlarmExample.pde
 *
 * This example calls alarm functions at 8:30 am and at 5:45 pm (17:45)
 * and simulates turning lights on at night and off in the morning
 * A weekly timer is set for Saturdays at 8:30:30
 *
 * A timer is called every 15 seconds
 * Another timer is called once only after 10 seconds
 *
 * At startup the time is set to Jan 1 2011  8:29 am
 */
 
#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68

int ledPin =  13;

// for RTC work
byte RTCsecond, RTCminute, RTChour, RTCdayOfWeek, RTCdayOfMonth, RTCmonth, RTCyear;



void setup()
{
  pinMode(ledPin, OUTPUT); // show the status
  Serial.begin(9600); // for debugging
  Serial.flush(); // need to flush serial buffer, otherwise first read from reset/power on may not be correct
  Wire.begin(); // initialise i2c bus for DS1307 
  
  clkSync();
  
 // create the alarms 
  Alarm.alarmRepeat(8,30,0, MorningAlarm);  // 8:30am every day
  Alarm.alarmRepeat(17,45,0,EveningAlarm);  // 5:45pm every day 
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);  // 8:30:30 every Saturday 

 
  Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){  
  digitalClockDisplay();
  Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");           
}

void WeeklyAlarm(){
  Serial.println("Alarm: - its Monday Morning");      
}

void ExplicitAlarm(){
  Serial.println("Alarm: - this triggers only at the given date and time");       
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}




void setDateDs1307(byte RTCsecond,        // 0-59
byte RTCminute,        // 0-59
byte RTChour,          // 1-23
byte RTCdayOfWeek,     // 1-7
byte RTCdayOfMonth,    // 1-28/29/30/31
byte RTCmonth,         // 1-12
byte RTCyear)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(decToBcd(RTCsecond));    // 0 to bit 7 starts the clock
  Wire.send(decToBcd(RTCminute));
  Wire.send(decToBcd(RTChour));      // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  Wire.send(decToBcd(RTCdayOfWeek));
  Wire.send(decToBcd(RTCdayOfMonth));
  Wire.send(decToBcd(RTCmonth));
  Wire.send(decToBcd(RTCyear));
  Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *RTCsecond,
byte *RTCminute,
byte *RTChour,
byte *RTCdayOfWeek,
byte *RTCdayOfMonth,
byte *RTCmonth,
byte *RTCyear)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *RTCsecond     = bcdToDec(Wire.receive() & 0x7f);
  *RTCminute     = bcdToDec(Wire.receive());
  *RTChour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *RTCdayOfWeek  = bcdToDec(Wire.receive());
  *RTCdayOfMonth = bcdToDec(Wire.receive());
  *RTCmonth      = bcdToDec(Wire.receive());
  *RTCyear       = bcdToDec(Wire.receive());
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void clkSync()
{
  
    getDateDs1307(&RTCsecond, &RTCminute, &RTChour, &RTCdayOfWeek, &RTCdayOfMonth, &RTCmonth, &RTCyear);
    setTime(RTChour,RTCminute,RTCsecond,RTCmonth,RTCdayOfMonth,RTCyear); // set time to Saturday 8:29:00am Jan 1 2011
 

}

My first question is how often should i sync the RTC time to the Arduino board when running continuasly?

Depends on the accuracy needed for your timed events, and how much the Arduino time drifts. If you sync every 5 minutes, and find that the new time is only a second off the old time, you are probably syncing more often than needed. Though the RTC doesn't care how often you sync.

Further to that later i am going to have to make something to sync the RTC time from my PC how often should i be doing this?

Somewhere between once a second and never. Why do you think you need to do this at all?

UNTESTED at this time.

Why?

My DS1307 drifts a few seconds per day. So if you require 1 second accuracy, sync with PC every hour. Do the math.
How do you correct your PC clock? By default mine seems to sync with time.windows.com once a week. I have Windows Vista.
I don't see how to change this period. It is off by more than 1 second.

Thank you for the replies

I would allow at the most 30 seconds to be thrown out in a day. Based on this and your replies i am thinking one PC sync every 24 hours would be sufficent but it sounds as tho i simply need to test it myself and i may be able to reduce or even have to increase this.

was untested due to me being in bed while posting my original message. I have since tested the code and it all is working fine for me.

Next steps....
Sync time from PC
Store alarm times on SD card
implement Web or telnet interface
Party like its 2012

the schetch read the clock DS3231 only is necessary and no every second. For the Output "S", check the days of the week and start time and end time. If between out "S" is HIGH or make some task. If not between out "S" is LOW or make other task.

Control how many outputs you like and tasks you need!!!

Schedule_tasks_ed.ino (4.18 KB)