Arduinos & Real Time Clocks

11 years ago | 28 December, 2012 | X minute read.

Intro

originally published on wordpress.com

This is a demonstration of how to use a real time clock with Arduino.

This can be helpful when making clocks as well as keeping logs of events.

Parts

  • Arduino Uno (or similar)
  • RTC module (eBay / SparkFun: ds1307 RTC module
  • some tactile switches for the adjustment push-buttons

Circuit

I planned what I did using Fritzing Note: The switches don't have pull up resistors as I utilised the internal pull up resisters of the digital Arduino pins.

Here is the Fritzing schematic:

Fritzing Circuit Schematic

Here is the Fritzing virtual breadboard layout:

Fritzing Breadboard Layout

Here is the actual circuit on a breadboad:

Breadboarded Circuit

Once implemented, and the code is on the Arduino, if the Serial Monitor is opened you should see something like this:

Arduino IDE Serial Monitor

This is handy as the buttons allow for the adjustment of time on the RTC by using an on-board time variable as an intermediary step.

The source code below is commented and should help further.

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup()  {
  Serial.begin(9600); // start the serial connectio
  n to the PC.

  pinMode(2, INPUT);       // set pin 2 as an input
  digitalWrite(2, HIGH);   // activate internal pullup resistor on pin 2
  pinMode(3, INPUT);       // set pin 3 as an input
  digitalWrite(3, HIGH);   // activate internal pullup resistor on pin 3
  pinMode(4, INPUT);       // set pin 4 as an input
  digitalWrite(4, HIGH);   // activate internal pullup resistor on pin 4

  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  setSyncInterval(60);        // set the number of seconds between re-sync

  if(timeStatus()!= timeSet)
     Serial.println("Unable to sync with the RTC.");
  else
     Serial.println("RTC has been read.");
}

void loop()
{
  if (digitalRead(2) == LOW) {         // Zero the minutes!
                                       // setting the onboard time to 0 minutes.
    setTime(hour(),0,second(),day(),month(), year());
    RTC.set(now());                    // sending the onboard time to the RTC.
    Serial.println("Minutes Reset.");  // send confirmation to the PC.

  }

  // *** had to adjust the adjustTime function in the Time library.
  // Inside Time.cpp, the adjustTime method was replaced with:
  //
  //  void adjustTime(long adjustment){
  //    setTime(sysTime + adjustment);
  //  }
  //

  if (digitalRead(3) == LOW) {         // add an hour!
    adjustTime(3600);                  // adjust onboard time by +3600 seconds (1hr) ***
    RTC.set(now());                    // sending the onboard time to the RTC.
    Serial.println("Added an hour.");  // send confirmation to the PC.
  }

  if (digitalRead(4) == LOW) {         // add a minute!
    adjustTime(60);                    // adjust onboard time by +60 seconds (1min) ***
    RTC.set(now());                    // sending the onboard time to the RTC.
    Serial.println("Added a minute."); // send confirmation to the PC.
  }

  // this section is for setting the rtc chip from the serial terminal.
  if(Serial.available()){
     time_t t = processSyncMessage();
     if(t >0)
     {
        RTC.set(t);   // set the RTC and the system time to the received value
        setTime(t);
     }
  }

  digitalClockDisplay();  // sends an update of the time to the PC.
  delay(1000);            // wait for a bit.
}

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

}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*  code to process time sync messages from the serial port   */
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message

time_t processSyncMessage() {
  // return the time if a valid sync message is received on the serial port.
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c);
    if( c == TIME_HEADER ) {
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){
        c = Serial.read();
        if( c >= '0' && c <= '9'){
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
        }
      }
      return pctime;
    }
  }
  return 0;
}

ARDUINO, BASIC, BEGINNER, DS1307, ELECTRONICS, LEARNING, MICROCONTROLLER, REAL TIME CLOCK, RTC