I have an RTC on the way, and I was wondering about setting the time. Do I need to manually set the time, or is their some way I can get the current date and time from my computer's clock? I thought I've seen something like DATE and TIME...
If you look at the library for the DS1307, there is an example Arduino sketch and a Processing sketch that will sync the RTC to your computer's clock. (You need to run both of them obviously.)
I would say it depends on which RTC you are using and how much accuracy you want. For example, the DS1307 loses 1-2 second a day, assuming you have a well designed oscillator.
Do the seconds even matter? If you are time stamping something, knowing what the current actual time allows you to determine the stamped time.
You might consider creating a serial command that resets the seconds to zero. (Or serial interface to set the clock.)
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
void setup () {
Serial.begin(57600);
Wire.begin();
RTC.begin();
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 () {
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 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);
}
I'll only set the time upon upload. After upload I'll set a flag in the EEPROM saying that time has been set, upon next reset, don't change time. Then, to change time, I clear flag.
I'll only set the time upon upload. After upload I'll set a flag in the EEPROM saying that time has been set, upon next reset, don't change time. Then, to change time, I clear flag.
The included eeprom_clear example. This will allow the RTC to have its time set. Setting the time will set the flag, "locking" the time until the flag is cleared.
Please note that both DATE and TIME are environment variables and just are accessed by the compiler when compiling the program. Represent the build date of the program. Put this little code in a program
and then try to open and closer several times the serial monitor while executed. You will see that always returns the same value. No use whatsoever unless runtime display the date that the program was compiled. Something like version control ..
I find it much, much easier just to put in the time manually.
Here is the program I use:
#include "Wire.h"
void setup() {
Wire.begin();
Serial.begin(9600);
// program to precisely set Chronodot
Wire.beginTransmission(0x68); // address DS3231
Wire.write(0x00); // select register
Wire.write(0x30); // seconds (BCD)
Wire.write(0x43); // minutes (BCD)
Wire.write(0x17); // hours (BCD)
Wire.write(0x07); // day of week (I use Mon=1 .. Sun=7)
Wire.write(0x15); // day of month (BCD)
Wire.write(0x09); // month (BCD)
Wire.write(0x13); // year (BCD, two digits)
Wire.endTransmission();
}
void loop() {
delay(500);
}
What you do is you change the numbers to show today's date, and a time maybe 1 or 2 minutes in the future. Then you compile and upload the program. When the numbers of the real time get close to (maybe 5 seconds before) the numbers you put in the program, then press the "reset" button on the Arduino, and wait a few seconds for the program to run. Then, to avoid setting the time more than once, upload a different program, such as this one:
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
// clear /EOSC bit
// Sometimes necessary to ensure that the clock
// keeps running on just battery power. Once set,
// it shouldn't need to be reset but it's a good
// idea to make sure.
// Wire.beginTransmission(0x68); // address DS3231
// Wire.write(0x0E); // select register
// Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
// Wire.endTransmission();
}
void loop()
{
// send request to receive data starting at register 0
Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
Wire.write((byte)0); // start at register 0
Wire.endTransmission();
Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hr, wd, dd, mo, yy)
while(Wire.available())
{
byte ss = Wire.read(); // get seconds
byte mi = Wire.read(); // get minutes
byte hh = Wire.read(); // get hours
byte wd = Wire.read();
byte dd = Wire.read();
byte mo = Wire.read();
byte yr = Wire.read();
Serial.print ("\'");
if (yr<0x10) Serial.print("0"); Serial.print(yr,HEX); Serial.print("-");
if (mo<0x10) Serial.print("0"); Serial.print(mo,HEX); Serial.print("-");
if (dd<0x10) Serial.print("0"); Serial.print(dd,HEX); Serial.print("(");
switch (wd) {
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;
default: Serial.print("Bad");
}
Serial.print(") ");
if (hh<0x10) Serial.print("0"); Serial.print(hh,HEX); Serial.print(":");
if (mi<0x10) Serial.print("0"); Serial.print(mi,HEX); Serial.print(":");
if (ss<0x10) Serial.print("0"); Serial.print(ss,HEX); Serial.println("");
}
delay(500);
}
This second program will display the time on the Serial Monitor. It is a good program for making sure that your RTC is set correctly.