DS1307 RTC with Time and TimeAlarms library
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
Try calling RTC.now after you call setSyncProvider
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
I'm happy with the ~5 min sync from startup. I'm looking at the Time.h library commands and the only sync variable is setSyncInterval(interval); // number of seconds between re-sync.
If I could force sync on startup, I could set the interval to = 24 hrs. I'm not sure how many of these timing features will slow down my running project. I may take a peek inside the library.
If I could force sync on startup, I could set the interval to = 24 hrs. I'm not sure how many of these timing features will slow down my running project. I may take a peek inside the library.
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
Stange, the alarm is not triggering. I have the alarm time set after the sync takes place. I have watched the times
Can't be much wrong.
See latest code:
Can't be much wrong.
See latest code:
Code: Select all
// Daily alarm test using a DS1307 RTC
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Time.h>
#include <TimeAlarms.h>
LiquidCrystal_I2C lcd(0x27,20,4);
RTC_DS1307 RTC;
time_t syncProvider() //this does the same thing as RTC_DS1307::get()
{
return RTC.now().unixtime();
}
void setup () {
//setTime(17,26,0,7,4,2013);
RTC.begin();
setSyncProvider(syncProvider);
// RTC.now; // Test to force initial sync, no.
Alarm.alarmRepeat(18,31,0, Alarm1); // every day
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
pinMode(13, OUTPUT);
}
void loop () {
clockDisplay();
Alarm.delay(1000);
}
void clockDisplay(){
DateTime now = RTC.now();
char buf[20]; // -------------------- RTC Time --------------------
sprintf(buf, "%02d:%02d %02d/%02d/%4d", now.hour(), now.minute(), now.month(), now.day(), now.year());
lcd.print(buf);
lcd.setCursor(0,1);
char buf1[20]; // ------------------ Arduino Time -----------------
sprintf(buf1, "%02d:%02d:%02d %02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
lcd.print(buf1);
lcd.setCursor(0,0);
}
void Alarm1(){
digitalWrite(13, HIGH); //alarm test output - On
delay(4000);
digitalWrite(13, LOW); } // Off
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
I'm not sure why you're having this 5-minute sync issue. Here's my sketch - I commented out all references to RTC.now(), and I'm just printing out the time as returned by the Time library.
It just comes right up and starts spitting out the current time.
It just comes right up and starts spitting out the current time.
Code: Select all
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
#include <Time.h>
#include <TimeAlarms.h>
RTC_DS1307 RTC;
time_t syncProvider() //this does the same thing as RTC_DS1307::get()
{
return RTC.now().unixtime();
}
void setup () {
Serial.begin(57600);
Wire.begin();
RTC.begin();
setSyncProvider(syncProvider); //reference our syncProvider function instead of RTC_DS1307::get()
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
}
void loop () {
Serial.print(year(), DEC);
Serial.print('/');
Serial.print(month(), DEC);
Serial.print('/');
Serial.print(day(), DEC);
Serial.print(' ');
Serial.print(hour(), DEC);
Serial.print(':');
Serial.print(minute(), DEC);
Serial.print(':');
Serial.print(second(), DEC);
Serial.println();
/* DateTime now = RTC.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print(" since midnight 1/1/1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.println("d");
// calculate a date which is 7 days and 30 seconds into the future
DateTime future (now.unixtime() + 7 * 86400L + 30);
Serial.print(" now + 7d + 30s: ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();
Serial.println();*/
delay(3000);
}
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
Where did you get this LiquidCrystal_I2C library?
Maybe try taking that out and see if your problems go away?
Maybe try taking that out and see if your problems go away?
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
The 5 Minutes time is hard coded in the Time.h library, Time.cpp file, with this code:
I don't believe the I2C LCD library has anything to do with this, I have been using it for everything imaginable for a year with no probs. The I2C communications with the RTC & LCD are fine otherwise I'd have errors or comm fail.
The below code is a simple TimeAlarms.h daily alarm demonstration, it always works. I'll try converting my test to Serial and test it.
Code: Select all
static tmElements_t tm; // a cache of time elements
static time_t cacheTime; // the time the cache was updated
static time_t syncInterval = 300; // time sync will be attempted after this many seconds
The below code is a simple TimeAlarms.h daily alarm demonstration, it always works. I'll try converting my test to Serial and test it.
Code: Select all
//This sketch triggers a daily alarm output
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Time.h>
#include <TimeAlarms.h>
LiquidCrystal_I2C lcd(0x27,20,4);
void setup()
{
setTime(19,05,0,7,04,13); // set time (h,m,s,d,m,yy)
// create the alarms
Alarm.alarmRepeat(19,7,0, Event1); // (h,m,s, Event1)
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
pinMode(13, OUTPUT); }
void loop(){
digitalClockDisplay();
Alarm.delay(1000); // wait one second between clock display
}
void Event1(){
digitalWrite(13, HIGH); //alarm output on
delay(5000);
digitalWrite(13, LOW); } // Off
void digitalClockDisplay()
{
char buf[20];
sprintf(buf, "%02d:%02d:%02d %02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
lcd.print(buf);
lcd.setCursor(0,0);
}
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
Aha! Figured it out. Your sketch wasn't initializing the I2C library:
Add a call to Wire.begin() right before the RTC.begin() :
Add a call to Wire.begin() right before the RTC.begin() :
Code: Select all
void setup () {
Serial.begin(57600);
setTime(17,26,0,7,4,2013);
Wire.begin(); //initialize the I2C driver
RTC.begin();
setSyncProvider(syncProvider);
RTC.now; // Test to force initial sync, no.
Alarm.alarmRepeat(18,31,0, Alarm1); // every day
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
pinMode(13, OUTPUT);
}
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
db
I tested your code - great, then added my LCD display to it and retested -- great. The time syncs instantly!
So after reading your last reply, I added your initial time set code and added the Wire.Begin():
My code now works perfect as planned. Latest version below. Now I can sleep. Your the Best!
I tested your code - great, then added my LCD display to it and retested -- great. The time syncs instantly!
So after reading your last reply, I added your initial time set code and added the Wire.Begin():
Code: Select all
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
Code: Select all
// Daily alarm test using a DS1307 RTC
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Time.h>
#include <TimeAlarms.h>
LiquidCrystal_I2C lcd(0x27,20,4);
RTC_DS1307 RTC;
time_t syncProvider() //this does the same thing as RTC_DS1307::get()
{
return RTC.now().unixtime();
}
void setup () {
Wire.begin();
RTC.begin();
setSyncProvider(syncProvider);
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
Alarm.alarmRepeat(22,34,0, Event1); // every day
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
pinMode(13, OUTPUT);
}
void loop () {
clockDisplay();
Alarm.delay(1000);
}
void clockDisplay()
{
DateTime now = RTC.now();
char buf[20]; // -------------------- RTC Time --------------------
sprintf(buf, "%02d:%02d %02d/%02d/%4d", now.hour(), now.minute(), now.month(), now.day(), now.year());
lcd.print(buf);
lcd.setCursor(0,1);
char buf1[20]; // ------------------ Arduino Time -----------------
sprintf(buf1, "%02d:%02d:%02d %02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
lcd.print(buf1);
lcd.setCursor(0,0);
}
void Event1(){
digitalWrite(13, HIGH); //alarm test output
delay(4000);
digitalWrite(13, LOW); }
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
Nifty! Glad to help
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
I have something strange going on.
I was testing a couple other sketches relating to RTC, then came back to the above and uploaded my above reliable code.
Now the Arduino time and RTC time are not synchronized with my PC on compile/load. I have had the battery out of the RTC also, but its time now ~ 16 minutes slow, seems to be stored at point of each power loss (batt out).
This worked perfectly since 8-Apr. Could the code I tested have caused this? It had memory address references, see below.
Any suggestions?
I was testing a couple other sketches relating to RTC, then came back to the above and uploaded my above reliable code.
Now the Arduino time and RTC time are not synchronized with my PC on compile/load. I have had the battery out of the RTC also, but its time now ~ 16 minutes slow, seems to be stored at point of each power loss (batt out).
This worked perfectly since 8-Apr. Could the code I tested have caused this? It had memory address references, see below.
Any suggestions?
Code: Select all
// #############################################################################
// #
// # Scriptname : DS1307_Test.pde
// # Author : Peter Schmelzer, Oliver Kraus
// # Date : 2011-04-08
// # Version : 1.21
// # License : cc-by-sa-3.0
// #
// # Description:
// # Test file for the DS1307new library. Assumes that you have a DS1307
// # connected to the I2C-Bus of your Arduino and that it has a battery backup.
// #
// #############################################################################
// *********************************************
// INCLUDE
// *********************************************
#include <Wire.h> // For some strange reasons, Wire.h must be included here
#include <DS1307new.h>
// *********************************************
// DEFINE
// *********************************************
// *********************************************
// VARIABLES
// *********************************************
uint16_t startAddr = 0x0000; // Start address to store in the NV-RAM
uint16_t lastAddr; // new address for storing in NV-RAM
uint16_t TimeIsSet = 0xaa55; // Helper that time must not set again
// *********************************************
// SETUP
// *********************************************
void setup()
{
pinMode(2, INPUT); // Test of the SQW pin, D2 = INPUT
digitalWrite(2, HIGH); // Test of the SQW pin, D2 = Pullup on
Serial.begin(9600);
/*
PLEASE NOTICE: WE HAVE MADE AN ADDRESS SHIFT FOR THE NV-RAM!!!
NV-RAM ADDRESS 0x08 HAS TO ADDRESSED WITH ADDRESS 0x00=0
TO AVOID OVERWRITING THE CLOCK REGISTERS IN CASE OF
ERRORS IN YOUR CODE. SO THE LAST ADDRESS IS 0x38=56!
*/
RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Store startAddr in NV-RAM address 0x08
/*
Uncomment the next 2 lines if you want to SET the clock
Comment them out if the clock is set.
DON'T ASK ME WHY: YOU MUST UPLOAD THE CODE TWICE TO LET HIM WORK
AFTER SETTING THE CLOCK ONCE.
*/
// TimeIsSet = 0xffff;
// RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
/*
Control the clock.
Clock will only be set if NV-RAM Address does not contain 0xaa.
DS1307 should have a battery backup.
*/
RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
if (TimeIsSet != 0xaa55)
{
RTC.stopClock();
RTC.fillByYMD(2011,4,8);
RTC.fillByHMS(22,7,0);
RTC.setTime();
TimeIsSet = 0xaa55;
RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
RTC.startClock();
}
else
{
RTC.getTime();
}
/*
Control Register for SQW pin which can be used as an interrupt.
*/
RTC.ctrl = 0x00; // 0x00=disable SQW pin, 0x10=1Hz,
// 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
RTC.setCTRL();
Serial.println("DS1307 Testsketch");
Serial.println("Format is \"hh:mm:ss dd-mm-yyyy DDD\"");
uint8_t MESZ;
MESZ = RTC.isMEZSummerTime();
Serial.print("MEZ=0, MESZ=1 : ");
Serial.println(MESZ, DEC);
Serial.println();
}
// *********************************************
// MAIN (LOOP)
// *********************************************
void loop()
{
RTC.getTime();
if (RTC.hour < 10) // correct hour if necessary
{
Serial.print("0");
Serial.print(RTC.hour, DEC);
}
else
{
Serial.print(RTC.hour, DEC);
}
Serial.print(":");
if (RTC.minute < 10) // correct minute if necessary
{
Serial.print("0");
Serial.print(RTC.minute, DEC);
}
else
{
Serial.print(RTC.minute, DEC);
}
Serial.print(":");
if (RTC.second < 10) // correct second if necessary
{
Serial.print("0");
Serial.print(RTC.second, DEC);
}
else
{
Serial.print(RTC.second, DEC);
}
Serial.print(" ");
if (RTC.day < 10) // correct date if necessary
{
Serial.print("0");
Serial.print(RTC.day, DEC);
}
else
{
Serial.print(RTC.day, DEC);
}
Serial.print("-");
if (RTC.month < 10) // correct month if necessary
{
Serial.print("0");
Serial.print(RTC.month, DEC);
}
else
{
Serial.print(RTC.month, DEC);
}
Serial.print("-");
Serial.print(RTC.year, DEC); // Year need not to be changed
Serial.print(" ");
switch (RTC.dow) // Friendly printout the weekday
{
case 1:
Serial.print("MON");
break;
case 2:
Serial.print("TUE");
break;
case 3:
Serial.print("WED");
break;
case 4:
Serial.print("THU");
break;
case 5:
Serial.print("FRI");
break;
case 6:
Serial.print("SAT");
break;
case 7:
Serial.print("SUN");
break;
}
Serial.print(" seconds since 1.1.2000:");
Serial.print(RTC.time2000, DEC);
uint8_t MESZ = RTC.isMEZSummerTime();
Serial.print(" MEZ=0, MESZ=1 : ");
Serial.print(MESZ, DEC);
Serial.print(" - Address in NV-RAM is: ");
RTC.getRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
Serial.print(lastAddr, HEX);
lastAddr = lastAddr + 1; // we want to use it as addresscounter for example
RTC.setRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
if (TimeIsSet == 0xaa55) // check if the clock was set or not
{
Serial.println(" - Clock was set!");
}
else
{
Serial.println(" - Clock was NOT set!");
}
delay(1000); // wait a second
}
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
You want to handle setting the time the way it's done in the example sketches:
When you first apply power to the RTC, the clock oscillator is disabled. RTC.isrunning() checks a status bit on the DS1307, and reports whether or not the oscillator is running. This code assumes it will automatically download and run immediately after compilation. If the RTC has been reset, it will set the compilation time as the current time.
Code: Select all
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
I solved part of this problem. I found that when the RTC is running, there is no date/time update via serial from the compiler Pc.
In the below code
The below line, actually sets the RTC. It is not executed, unless (! RTC.isrunning()), meaning unless(Not RTC.isrunning()). The ! is a Logical negation operator in C/C++.
So If the RTC Is running, regardless of time, the above line is never run, it is not set or synchronized with the compiler PC time.
To force the compiler PC time update of the RTC with each compile, the RTC.adjust line could be used alone. After making this change however, the Arduino clock is not synchronized for 5 Min/300 seconds, as is hard coded into the Time.h library.
I'm working on an instant sync of the Arduino time.
In the below code
Code: Select all
if (! RTC.isrunning()) { // Is RTS running or not
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
Code: Select all
RTC.adjust(DateTime(__DATE__, __TIME__));
To force the compiler PC time update of the RTC with each compile, the RTC.adjust line could be used alone. After making this change however, the Arduino clock is not synchronized for 5 Min/300 seconds, as is hard coded into the Time.h library.
I'm working on an instant sync of the Arduino time.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
Out of curiosity, why are you trying to adjust the time on the RTC every time you compile?
If you remove the power from the RTC prior to compiling and downloading, my suggested code will reset the time.
Calling setSerialProvider will immediately synchronize the time on the arduino with the RTC, regardless of the 5-minute timeout hardcoded into the Time library.
If you remove the power from the RTC prior to compiling and downloading, my suggested code will reset the time.
Calling setSerialProvider will immediately synchronize the time on the arduino with the RTC, regardless of the 5-minute timeout hardcoded into the Time library.
- ashton1
- Posts: 13
- Joined: Sat Mar 23, 2013 9:59 am
Re: DS1307 RTC with Time and TimeAlarms library
I know some of my minute issues are nearly a waste of forum space, but this issue is annoying on my end when testing many different sketches/codes from 2009 newer, some having hard time set values. I kept going back to my own project and the time was years, hours, minutes off. When I'd load/compile my own project, it wasn't updating to the correct current time/date, because my borrowed code thought since the RTC was 'running' it was accurate. I'm sure I am not the only person dealing with this issue.
So really in my real world, if I have multiple Arduinos with RTCs running things, and I plug into any/all of them to update the sketch, I Do want the RTC to be updated also to the correct time, not to walk away after an update with the RTC at a random time.
I'm going to be testing the DS1307new library https://code.google.com/p/ds1307new/downloads/list that includes a Summertime Calculation (DST). It may be worth while to US developers with time-sensitive, clock, or data logging projects.
So really in my real world, if I have multiple Arduinos with RTCs running things, and I plug into any/all of them to update the sketch, I Do want the RTC to be updated also to the correct time, not to walk away after an update with the RTC at a random time.
I'm going to be testing the DS1307new library https://code.google.com/p/ds1307new/downloads/list that includes a Summertime Calculation (DST). It may be worth while to US developers with time-sensitive, clock, or data logging projects.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: DS1307 RTC with Time and TimeAlarms library
For what it's worth, the Chronodot uses the DS3231, a much more accurate RTC than the D1307. It is also 100% code-compatible with the DS3107.
But, if you want to reset a clock that's been running for a while, the simple thing to do is to pull the battery out just before you recompile and reload the code.
Alternately, you could add code to allow you to reset the time over serial - just type it in...
But, if you want to reset a clock that's been running for a while, the simple thing to do is to pull the battery out just before you recompile and reload the code.
Alternately, you could add code to allow you to reset the time over serial - just type it in...
Please be positive and constructive with your questions and comments.