Programming the ChronoDot DS3231 Real Time Clock

In my last post, I introduced my new hobby tinkering with the Arduino microcontroller. I also mentioned a timer that I’m building to power some lamps in my living room.

Since the Arduino doesn’t have a clock built into it, there is an interesting problem wherein there is no way to ensure that the Arduino will turn the relays on and off when I want it to. Enter the Real Time Clock (RTC). It’s a small clock chip with a battery. You program it once to set the time, and from then on it will keep time rather well. The one I have will keep time within a minute or two per year, which is plenty accurate enough for turning on lamps.

The biggest issue I’ve run into is that it has been hard to figure out how to program it with the right time. There are example sketches (program code) out there that will do it, but not exactly as I need it.

The code I got from Jack Christensen over at Adventures in Arduinoland assumes that the clock is set to UTC time, not local time, and the examples that I have found all set the clock to local time. Setting to UTC is important because it automatically adjusts for daylight savings time. It’s also easier to program the code for use anywhere in the world (share it with others) when it is based on UTC time.

So because I had such a hard time, I modified the example that is found here to set the clock to UTC, and figured out how I needed to modify it here. All you need to do is paste this into the Arduino programmer, modify the variable for the UTC offset to fit your timezone, and upload it. (I’m in UTC – 5, so mine is set to float UTCOffset = -5.0; It is set as a float for those locations that may be offset by an amount that is not a whole hour (for example, Nepal is UTC +5.75). If you’re powering the RTC from the pins, you’ll have to uncomment those and modify them to fit your configuration.

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

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

RTC_DS1307 RTC;

float UTCOffset = -5.0;    // Your timezone relative to UTC



void setup () {
    Serial.begin(9600);
        
    
    // Uncomment the following lines to use pins 4 & 5 as power and ground for the RTC
    
    // pinMode(4, OUTPUT);
    // digitalWrite(4, HIGH);  // HIGH for power
    // pinMode(5, OUTPUT);
    // digitalWrite(5, LOW);   // LOW for ground
        
    Wire.begin();
    RTC.begin();
    
    RTC.adjust(DateTime(__DATE__, __TIME__));  // sets the clock to the time when this sketch is compiled
    delay(1000);
    DateTime now = RTC.now();
    DateTime UTCTime(now.unixtime() - 3600 * UTCOffset);   // Adjust the time from local to UTC
    RTC.adjust(UTCTime);
    
}

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 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);
}

Comments are closed.