DS1307 Real Time Clock & Arduino

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
  • RTC module (ebay: ds1307 RTC module or search that on sparkfun)
  • some switches for the adjustments

I’ll start with my breadboard:

rtc_photo

I have translated what I did into Fritzing which may be more clear:

time_bb

… and the schematic:

time_schem

Note that the switches don’t have pull up resistors as I utilised the internal pull up resisters of the digital Arduino pins.

So once implemented, and the code is on the Arduino, if the terminal is opened it will behave like this:

serial

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s