How to set RTC ds1307 time date accurately [SOLVED]

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

How to set RTC ds1307 time date accurately [SOLVED]

Post by DanPolka »

(AFTERWORD: the original subject intended to be, "How to set RTC ds1307 time date from computer upon press button", but I guess there's a character limit, so I shortened it to allow to indicate [SOLVED] in the subject.)

I see that when using RTClib to set the time in a ds1307, the time that's used to set it is the time retrieved on compile, which causes the rtc to lag real time by about 30 seconds.

So, in order to set the RTC more accurately, I thought to put the time adjust statement,
"rtc.adjust(DateTime(__DATE__, __TIME__));"
into a one-shot button press within the main loop.

But it appears that the time/date even there is always the time and date retrieved at compile, rather than the time/date at button press, that is, it just loads the time/date that was retrieved on compile every time the button is pressed instead of getting the current time and loading that time into the RTC.

How can I get the current time from the computer on button press to set that time into the 1307 ???

code is:
// Reads Date and time from a DS1307 RTC connected via I2C and Wire lib
// RTC plugged directly onto Uno, with A2 (D17) set as gnd, A3 (D16) set as +5 (high)

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

const int PwrToRTC = 17; // set this as OUTPUT, and HIGH to power RTC directly from plugged into Uno board
const int GndToRTC = 16; // set this as OUTPUT, and LOW for GROUND for RTC from plugged into Uno board
const int buttonPin = 6; // pin number of a normally CLOSED pushbutton pin

// switch debounce vars:
int val; // variable for reading the switch pin status
int val2; // variable for reading the switch pin status after a delay
int buttonState; // the current reading from the input pin

// one-shot var: allow to do action only ONCE when button pressed, don't do again until switch released and
// then pressed again
int oneShotHasFired; // one shot has fired, don't fire again until cleared



void setup () {
  Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif

  pinMode(PwrToRTC, OUTPUT); // set analog pin A3 (digital 17 on Uno) as OUTPUT and HIGH for POWER rtc
  digitalWrite(PwrToRTC, HIGH);
  
  pinMode(GndToRTC, OUTPUT); // set analog pin A2 (digital 16 on Uno) as OUTPUT and LOW for GROUND rtc
  digitalWrite(GndToRTC, LOW);
  
  pinMode(buttonPin, INPUT); // set pin 6 as input for pushbutton switch
  digitalWrite(buttonPin, HIGH); // turn on pullup resistors for pin 4 in order to use NC switch to ground

  buttonState = digitalRead(buttonPin); // read the initial state
  oneShotHasFired = 0; // hasn't fired yet
  
  rtc.begin();
//  Serial.println("setting the time/date");
  // following line sets the RTC to the date & time this sketch was compiled
//  rtc.adjust(DateTime(__DATE__, __TIME__));
  //Serial.println("finished setting the time/date?");
 }

void loop () {
  val = digitalRead(buttonPin); // read input value and store it in val
  delay(10); // time delay for debounce switch
  val2 = digitalRead(buttonPin); // read it again after delay, store in val2
  
  if (val == val2) { // ok, the two readings are the same
    if (val != buttonState) { // the button state has changed!
      if (val == HIGH && oneShotHasFired == 0) { // check if the button is pressed
       Serial.println("Button just pressed");
       oneShotHasFired = 1;
       
        rtc.adjust(DateTime(__DATE__, __TIME__));
       
        DateTime now = rtc.now();
        Serial.println();
        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();
  
  
      }  
    }  else { // the button is RELEASED // -not- pressed...
              // Serial.println(" Button just released");
               oneShotHasFired = 0;
    }  
  } 
}
Last edited by DanPolka on Fri Feb 21, 2014 11:03 am, edited 1 time in total.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: How to set RTC ds1307 time date from computer upon press

Post by adafruit_support_rick »

The short answer is that it would be difficult. You would need to implement a communications protocol to retrieve the time from the computer and set it on the arduino. There is a standard protocol for this, called NTP. It's how your computer gets the current time.
DanPolka wrote:which causes the rtc to lag real time by about 30 seconds.
30 seconds? That's just not right. I'd expect it to be closer to 5 seconds, especially with a small sketch which will download quickly.

1chicagodave
 
Posts: 564
Joined: Wed Jun 19, 2013 3:35 am

Re: How to set RTC ds1307 time date from computer upon press

Post by 1chicagodave »

Just a thought...

You could just replace this -

Code: Select all

"rtc.adjust(DateTime(__DATE__, __TIME__));"
with the time a minute or two in the future. Then, when your computer clock shows that same time....press the button. It won't be exact, but could be within a second or so.

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date from computer upon press

Post by DanPolka »

Rick, isn't there something in an RTClib that would retrieve & set the time date on command, other than at compile time??

And while searching around for others wanting to set the time more accurately I did see mention of a similar 30-40 second lag, and now that I think of it, my computer does take quite a while to accomplish both the compile and the upload, not sure why.

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date from computer upon press

Post by DanPolka »

Dave, thanks, I suppose I could repeated tweak different time offsets until I get as close as I can; do you know what the format of the time date required by the rtc.adjust command is?

But since my search reveals that some others have also wanted to get the RTC set more accurately, I'm surprised that there isn't a RTClib (or other library) statement that allows for real time setting of the real time clock. :?

User avatar
Franklin97355
 
Posts: 23910
Joined: Mon Apr 21, 2008 2:33 pm

Re: How to set RTC ds1307 time date from computer upon press

Post by Franklin97355 »

But since my search reveals that some others have also wanted to get the RTC set more accurately, I'm surprised that there isn't a RTClib (or other library) statement that allows for real time setting of the real time clock. :?
The main problem with this is where you will get the real time setting. You could write code that would send a serial request to a computer running a program (python?) and the program would send back the computer time which the Arduino would then write to the RTC but that's not something that should be in the library of the Arduino (in my opinion).

1chicagodave
 
Posts: 564
Joined: Wed Jun 19, 2013 3:35 am

Re: How to set RTC ds1307 time date from computer upon press

Post by 1chicagodave »

DanPolka wrote:Dave, thanks, I suppose I could repeated tweak different time offsets until I get as close as I can; do you know what the format of the time date required by the rtc.adjust command is?
Have you opened up the RTClib.cpp file to look at the comments?
// A convenient constructor for using "the compiler's time":
// DateTime now (__DATE__, __TIME__);
// NOTE: using PSTR would further reduce the RAM footprint
DateTime::DateTime (const char* date, const char* time) {
// sample input: date = "Dec 26 2009", time = "12:34:56"

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date from computer upon press

Post by DanPolka »

No, I didn't, but thanks for showing me what the format is; I'll try tweaking it this way, as nothing else I have found actually resets the RTC at any time other than compile.

And how would I look into the .ccp file?

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date from computer upon press

Post by DanPolka »

You can now see how little I understand about programming with this question:

I put the following into a program to try to use a specified datetime in
rtc.adjust(DateTime(__DATE__, __TIME__));
and got a compile error

Code: Select all

const char* date;
const char* time;

date = "Dec 26 2009";
time = "12:34:56";
With compile error,
"ds1307_SetAndReadTimeOnPressButtonTest:29: error: expected constructor, destructor, or type conversion before '=' token"
beginning at

Code: Select all

date = "Dec 26 2009";
I presume it's obvious what I'm doing wrong and not understanding, but I don't know what it is.

So, given that you've told me what the format for datetime is,
how exactly do I use it in code, please. :(

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date from computer upon press

Post by DanPolka »

Ok, never mind, I think, for now, messing semi-blindly with the code, I did the following, and it seems to have worked:

Code: Select all

char* date = "Dec 26 2009";
char* time = "12:34:56";
So now, having a time date that I know wasn't done on compile, I can try to actually implement your suggestion. Thanks!!! :)

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date from computer upon press

Post by DanPolka »

Well I'll be! It works!!
Somewhat cumbersome, wish I could get the date_time more easily just from programmatically interrogating the computer system clock, but this will work!

THANK YOU DAVE! :D

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: How to set RTC ds1307 time date from computer upon press

Post by adafruit_support_rick »

DanPolka wrote:Well I'll be! It works!!
Somewhat cumbersome, wish I could get the date_time more easily just from programmatically interrogating the computer system clock, but this will work!
You realize that you only have to do this once, right? That's what the rtc.isRunning test in the original code is all about. If you have the backup battery installed, the RTC will continue to run, even if you remove power from the system.

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date accurately [SOLVED]

Post by DanPolka »

For me, reminders like that are in no way unnecessary! But since ds1307 drifts with passage of time, I'll have to recurrently readjust it, which is why I'd prefer an easier way to do that.

Of course, the better solution all around would be to get a better RTC, like the ChronoDot, which I will eventually, hoping that what is working to set & read ds1307 might work for it too??

Which reminds me, it's convenient to stick the ds1307 directly onto the Uno, is there any plan to make the ChronoDot have a similar breakout board pinout arrangement to allow for that?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: How to set RTC ds1307 time date accurately [SOLVED]

Post by adafruit_support_rick »

My experience with the chronodot is that it really just doesn't drift much at all.
We don't make the chronodot, so I don't know anything about their product plans.

If you really want to set the time automatically, have a look at the CC3000 WiFi shield or breakout. We have NTP support in the library for that, and an NTP example sketch.
http://www.adafruit.com/index.php?main_ ... h&q=cc3000

DanPolka
 
Posts: 108
Joined: Tue Feb 18, 2014 5:31 am

Re: How to set RTC ds1307 time date accurately [SOLVED]

Post by DanPolka »

I'll bear WiFi & NTP in mind for after main part of project is finished, that sounds interesting.

And of course, even if Adafruit doesn't make ChronoDot, doesn't mean breakout for 3231 or 3232 chips couldn't be offered. :)

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”