loading

This time I will be showing you how to make a module for letting the Arduino find out the time. Although there are many tutorials for the Real Time Clock module I wanted to make my version of this module entirely focused on the step by step soldering. The Instructable will also try to include as much example code as possible so that the reader will get more than the basic knowledge of this module.

This module has the integrated time keeping system using a crystal oscillator. So the timing is accurate with multiple applications. This module also has a battery backup with which the module can keep track of the time even when the Arduino is programmed or turned off. Lets start off with the stuff you will learn and the applications of this module.

Stuff You Will Learn:

  • The code required to access the module and get the current time.
  • The code for setting the time.
  • A simple program with which the user can interact with the module.

Uses of The Project:

  • Once you are done with this Instructable you will be able to make your own Digital Clock.
  • You can build on the idea and make an Alarm Clock.
  • This Module is the timekeeper for many projects like The Propeller Clock, The Nixie Clock, etc.

Components Required:

Component for the Module:

Additional Components:

When I designed this module I ignored the square wave pin, Since I didn't find it useful in my application but you may add an extra pin if the need arises.

Step 1: About the DS 1307

Introduction:

Apart from the arduino the DS1307 Integrated Circuit is the core of this project since it acts as the timekeeper and tells the arduino when it should leave the appliance on. The DS 1307 is specifically designed for timekeeping, The time is fairly accurate with an error (time drift) of about 1 minute per month. If u want to eliminate this u can go for the DS3234 which has a time drift of only 1 minute per year. For our particular application we can settle for the DS1307 itself.

The beauty of the DS1307 is that it has this backup coin cell. This Coin Cell is commonly the CR2032. This battery is more than enough for the IC since the DS1307 has a fairly low power consumption the backup battery life of the cell is about a minimum of 9 years of usage.

So now that the specs have been discussed lets talk about the communication. The DS 1307 communicates with the arduino using I²C communication. Simply put the chip sends data in decimal form such that each decimal form is 4 bits of binary data also known as Binary Coded Decimal System.

Important Pins:

5V Pin: When this pin is high then the ds1307 sends the data and when it is low it runs on the backup button cell.

GND: This is the ground pin for the module. Both the ground of the battery and the power supply are tied together.

SCL: It is the i2c clock pin - Which communicates with the RTC.

SDA: It is the i2c data pin - Which communicates with the RTC.

So now that the introductions are done lets get to actually making the module. The instructable has steps of the soldering and the places of the components in the board. Hope this method is better to understand than just providing the circuit diagram.

Step 2: Assembly and Soldering - 1

So the module is only 2 x 3 cm in size, which is pretty compact. The module has a wire connector but you can also use a male or female header so that it can be directly plugged into the Arduino. Anyway apart from the square wave pin not soldered the module has all the functional features.

Making The Module:

Step 1:

Cut the prototype board to the size mentioned above and insert the coin cell holder. Then solder the bottom end to hold the cell in its place.

Step 2:

Insert the DIP socket right next to the cell holder but leave space for the crystal oscillator like in the diagram. Solder some pins to hold the socket in place.

Step 3:

Now insert the crystal Oscillator near the first and second pin of the DIP Socket as shown in the figure. Then solder it as shown.

Note 1:

This note is for showing the colour code for my 4 pin connector for reference, since yours may vary please double check that the proper connections are made.

Note 2:

Now we need to connect the battery terminals using the tracks as shown in the diagram. These connections provide the backup power.

Step 3: Assembly and Soldering - 2

Step 5:

Now insert the power pins coming from the Arduino. The positive pin goes to the eighth pin of the DS 1307. Then the ground is common for the IC and the button cell.

Step 6:

In this step we connect the other two data pins coming from the Arduino as shown in the figure. I'm sorry because I made the module a little small so there was no hole for the 10k resistor. I inserted both the resistor and the wire in the same pin and then soldered.

Step 7:

So after you inserted the wires next we need to insert 10k resistors each into the two pins. The other ends of the two resistors goes to the power pin eight of the DS 1307. Then solder up the wires, a diagram is provided for reference.

Step 8:

Since I use a connector in this module frequent usage will lead to wear and tear of the wires. So i made a joint using the cut of wire from the resistors. First insert the wire into one end and solder it to make it sturdy. Then make a U-bend and pass the wires through this U-bend and tighten the U-bend for a good grip and then solder the other end too to make a joint. The diagram explains the method better than words.

The module is finally finished so insert both the battery and the DS1307 IC into their sockets. The final diagram shows the completed module with all intact.

Step 4: Checking and Setting the Module

Once you are done assembling the module. Connect the module to the Arduino, so that the pins are inserted properly into the Arduino. The program for testing the module is given below. The code constantly updates the time through the serial port.

In-order to run the module we need two libraries we need two libraries into the Arduino software. The following steps set up the Arduino software with the libraries needed and the code.

Importing The Libraries:

  • Download the library "RealTimeClockDS1307" and save it in the desktop.
  • Open the Arduino and go to Sketch => Import Library => Add Library.
  • Then select the library saved in the desktop and click add.
  • Now paste the sample code given below and click compile. If it compiles successfully then skip the remaining steps.
  • If it doesn't import the second library "Wire" and repeat the same procedure and compile the code and it will work.

Code Working:

The code is written by "David H. Brown" I merely use it to give you an introduction to the DS1307. Anyway the Arduino communicates with the RTC Module and updates the time for every second through the Serial Monitor. The creator has given us a option to set the time when we send the command "?". The following menu appears.

Try these:
 h## - set Hours [range 1..12 or 0..24]
 i## - set mInutes [range 0..59]
 s## - set Seconds [range 0..59]
 d## - set Date [range 1..31]
 m## - set Month [range 1..12]
 y## - set Year [range 0..99]
 w## - set arbitrary day of Week [range 1..7]
 t   - toggle 24-hour mode
 a   - set AM          p   - set PM

 z   - start clock     Z   - stop clock
 q   - SQW/OUT = 1Hz   Q   - stop SQW/OUT

This code will help you to set the time as well as check if the module's backup battery supply works properly. In the next tutorial I will show you how to setup a LCD Display and display the time from the RTC module. Here is the code for testing the module and an attached file of the same.

#include <Wire.h>
#include <RealTimeClockDS1307.h>

//RealTimeClock RTC;//=new RealTimeClock();

#define Display_Clock_Every_N_Seconds 10           // n.secs to show date/time
#define Display_ShortHelp_Every_N_Seconds 60       // n.secs to show hint for help
//#define TEST_Squarewave
//#define TEST_StopStart
//#define TEST_1224Switch

int count=0;
char formatted[] = "00-00-00 00:00:00x";

void setup() {
//  Wire.begin();
  Serial.begin(9600);
    pinMode(A3, OUTPUT);     //*** pin 16 (Analog pin 2) as OUTPUT   ***
  digitalWrite(A3, HIGH);   //*** pin 16 (Analog pin 2) set to LOW  ***
  pinMode(A2, OUTPUT);     //*** pin 17 (Analog pin 3) as OUTPUT   ***
  digitalWrite(A2, LOW);  //*** pin 17 (Analog pin 3) set to HIGH ***
  //*** Analog Pin settings to power RTC module ***
}
 
void loop() {
  if(Serial.available())
  {
    processCommand();
  }

  RTC.readClock();
  count++;
  if(count % Display_Clock_Every_N_Seconds == 0){
    Serial.print(count);
    Serial.print(": ");
    RTC.getFormatted(formatted);
    Serial.print(formatted);
    Serial.println();
  }
  
  if(count % Display_ShortHelp_Every_N_Seconds == 0) {
    Serial.println("Send ? for a list of commands.");
  }
#ifdef TEST_Squarewave
if(count%10 == 0)
{
  switch(count/10 % 6)
  {
    case 0:
    Serial.print("Squarewave disabled (low impedance): ");
    RTC.sqwDisable(0);
    Serial.println((int) RTC.readData(7));
    break;
    case 1:
    Serial.print("Squarewave disabled (high impedance): ");
    RTC.sqwDisable(1);
    Serial.println((int) RTC.readData(7));
    break;
    case 2:
    Serial.println("Squarewave enabled at 1 Hz");
    RTC.sqwEnable(RTC.SQW_1Hz);
    break;
    case 3:
    Serial.println("Squarewave enabled at 4.096 kHz");
    RTC.sqwEnable(RTC.SQW_4kHz);
    break;
    case 4:
    Serial.println("Squarewave enabled at 8.192 kHz");
    RTC.sqwEnable(RTC.SQW_8kHz);
    break;
    case 5:
    Serial.println("Squarewave enabled at 32.768 kHz");
    RTC.sqwEnable(RTC.SQW_32kHz);
    break;
    default:
    Serial.println("Squarewave test not defined");
  }//switch
}
#endif

#ifdef TEST_StopStart
if(count%10 == 0)
{
  if(!RTC.isStopped()) 
  {
    if(RTC.getSeconds() < 45) 
    {
      Serial.println("Stopping clock for 10 seconds");
      RTC.stop();
    }//if we have enough time
  } else {
    RTC.setSeconds(RTC.getSeconds()+11);
    RTC.start();
    Serial.println("Adding 11 seconds and restarting clock");
  }
}//if on a multiple of 10 counts
#endif

#ifdef TEST_1224Switch  
  if(count%10 == 0)
  {
    if(count %20 == 0)
    {
      Serial.println("switching to 12-hour time");
      RTC.switchTo12h();
      RTC.setClock();
    }
    else
    {
      Serial.println("switching to 24-hour time");
      RTC.switchTo24h();
      RTC.setClock();
    }
  }
#endif
}

void processCommand() {
  if(!Serial.available()) { return; }
  char command = Serial.read();
  int in,in2;
  switch(command)
  {
    case 'H':
    case 'h':
    in=SerialReadPosInt();
    RTC.setHours(in);
    RTC.setClock();
    Serial.print("Setting hours to ");
    Serial.println(in);
    break;
    case 'I':
    case 'i':
    in=SerialReadPosInt();
    RTC.setMinutes(in);
    RTC.setClock();
    Serial.print("Setting minutes to ");
    Serial.println(in);
    break;
    case 'S':
    case 's':
    in=SerialReadPosInt();
    RTC.setSeconds(in);
    RTC.setClock();
    Serial.print("Setting seconds to ");
    Serial.println(in);
    break;
    case 'Y':
    case 'y':
    in=SerialReadPosInt();
    RTC.setYear(in);
    RTC.setClock();
    Serial.print("Setting year to ");
    Serial.println(in);
    break;
    case 'M':
    case 'm':
    in=SerialReadPosInt();
    RTC.setMonth(in);
    RTC.setClock();
    Serial.print("Setting month to ");
    Serial.println(in);
    break;
    case 'D':
    case 'd':
    in=SerialReadPosInt();
    RTC.setDate(in);
    RTC.setClock();
    Serial.print("Setting date to ");
    Serial.println(in);
    break;
    case 'W':
    Serial.print("Day of week is ");
    Serial.println((int) RTC.getDayOfWeek());
    break;
    case 'w':
    in=SerialReadPosInt();
    RTC.setDayOfWeek(in);
    RTC.setClock();
    Serial.print("Setting day of week to ");
    Serial.println(in);
    break;
    
    case 't':
    case 'T':
    if(RTC.is12hour()) {
      RTC.switchTo24h();
      Serial.println("Switching to 24-hour clock.");
    } else {
      RTC.switchTo12h();
      Serial.println("Switching to 12-hour clock.");
    }
    RTC.setClock();
    break;
    
    case 'A':
    case 'a':
    if(RTC.is12hour()) {
      RTC.setAM();
      RTC.setClock();
      Serial.println("Set AM.");
    } else {
      Serial.println("(Set hours only in 24-hour mode.)");
    }
    break;
    
    case 'P':
    case 'p':
    if(RTC.is12hour()) {
      RTC.setPM();
      RTC.setClock();
      Serial.println("Set PM.");
    } else {
      Serial.println("(Set hours only in 24-hour mode.)");
    }
    break;

    case 'q':
    RTC.sqwEnable(RTC.SQW_1Hz);
    Serial.println("Square wave output set to 1Hz");
    break;
    case 'Q':
    RTC.sqwDisable(0);
    Serial.println("Square wave output disabled (low)");
    break;
    
    case 'z':
    RTC.start();
    Serial.println("Clock oscillator started.");
    break;
    case 'Z':
    RTC.stop();
    Serial.println("Clock oscillator stopped.");
    break;
    
    case '>':
    in=SerialReadPosInt();
    in2=SerialReadPosInt();
    RTC.writeData(in, in2);
    Serial.print("Write to register ");
    Serial.print(in);
    Serial.print(" the value ");
    Serial.println(in2);
    break;    
    case '<':
    in=SerialReadPosInt();
    in2=RTC.readData(in);
    Serial.print("Read from register ");
    Serial.print(in);
    Serial.print(" the value ");
    Serial.println(in2);
    break;

    default:
    Serial.println("Unknown command. Try these:");
    Serial.println(" h## - set Hours [range 1..12 or 0..24]");
	Serial.println(" i## - set mInutes [range 0..59]");
	Serial.println(" s## - set Seconds [range 0..59]");
	Serial.println(" d## - set Date [range 1..31]");
    Serial.println(" m## - set Month [range 1..12]");
    Serial.println(" y## - set Year [range 0..99]");
    Serial.println(" w## - set arbitrary day of Week [range 1..7]");
    Serial.println(" t   - toggle 24-hour mode");
    Serial.println(" a   - set AM          p   - set PM");
    Serial.println();
    Serial.println(" z   - start clock     Z   - stop clock");
    Serial.println(" q   - SQW/OUT = 1Hz   Q   - stop SQW/OUT");
    Serial.println();
    Serial.println(" >##,###  - write to register ## the value ###");
    Serial.println(" <##      - read the value in register ##");
    
  }//switch on command
  
}

//read in numeric characters until something else
//or no more data is available on serial.
int SerialReadPosInt() {
  int i = 0;
  boolean done=false;
  while(Serial.available() && !done)
  {
    char c = Serial.read();
    if (c >= '0' && c <='9')
    {
      i = i * 10 + (c-'0');
    }
    else 
    {
      done = true;
    }
  }
  return i;
}

Step 5: About the Library

Before going to display the time in the LCD. I wanted to discuss about the library that we imported. I omitted the library which needs the square wave data since the module has no square wave output pin. Lets discuss about the various keywords involved in this library with some examples.

KEYWORDS:

Start Clock:

RTC.start();

This can be used to start up the clock and it will start ticking from the time when it was stopped. This command should be used when first using the module in-order to start the module.

Stop Clock:

RTC.stop();

With this line the module can be paused and clock wont tick until the start command is given. It is used with the start clock command to control the module's state.

Read Clock:

RTC.readClock();

After the clock is turned on using the Start command. You need to read the data from the RTC module. This is done by the readClock function. This function is essential before the latter commands can be used.

Reading the time:

//integers for holding the various time values.
int hours = 0;
int minutes = 0;
int seconds = 0;
int dates = 0;
int months = 0;
int years = 0;
int date = 0;
//syntax for setting the values to the integers
RTC.readClock();   //This line is essential for the other commands to work.
//Commands for getting the individual time values.
hours = RTC.getHours();
minutes = RTC.getMinutes();
seconds = RTC.getSeconds();
dates = RTC.getDate();
months = RTC.getMonth();
years = RTC.getYear();
date = RTC.getDayofWeek();
//finally just print the stored data (refer next step).

So once the readClock is called. Next we need to store the individual values in integers. We create integers for holding the values. The getDayofWeek function give the day it is in the week. With the first day being Monday and the last is Sunday. Note that this method is very inefficient when compared to the code in the previous steps but this will help you understand the working of the various functions in the library.

NOTE:

//extra code for finding out whether its AM or PM when the clock is in 12h mode.
//declare an integer and string.
int AP = 0;
String TZ;
//then read the data from the module.
ampm = RTC.isPM();
//use an if loop to find out whether its AM or PM.
if(ampm == 1)
{
    am = "PM";
}
else
{
    am ="AM";
}

This extra line of code will display whether its AM or PM when in 12-hour mode. When you set it to 24-hour mode remove this code.

Writing the time:

RTC.setHours(4);
RTC.setMinutes(35);
RTC.setSeconds(14);
RTC.setDate(9);
RTC.setMonth(6);
RTC.setYear(14);
RTC.set24h();
//RTC.setAM();
RTC.setPM();
RTC.setDayofWeek(1);<br>

So these are the commands for setting the time for the Module. As you can see i have set the time for 4:35:14 PM with the date as 9/6/14. Apart from these commands there is the set24h command which directly sets the clock into 24hour mode and set AM and PM for setting it into 12hour mode. The setDayofWeek is used to set the day.

Time commands:

//These commands deal with the settings in the module.

//Checks whether the clock is running.
RTC.isStopped();
//Check whether it is AM or PM depending on the output(given above).
RTC.isPM();
//Checks whether the clock is in 24hour mode.
RTC.is12hour();
//Toggles between the 12hour mode and 24hour mode.
RTC.switchTo24h();

These are the commands that control the settings inside the clock.

I have explained as much as I can about this library. If you find any flaws or something I missed please comment about it so that it can be as accurate as possible.

Step 6: Displaying the Time (Simple Method)

Now that the module is checked, now lets work on getting the time data to display on the LCD. The LCD module can be easily connected to the Arduino. The circuit diagram for connecting the LCD module is shown. The code for displaying the time is given below.

Before that I have made two versions of this code. One with the ordinary LCD connected to the Arduino. This is the simplest version but this will occupy most of the pins in the Arduino. So I came up with an alternative, using a Shift register to send data to the LCD module using only 2 pins. So you may choose whichever is more convenient for you.

Normal Version:

More pins but simpler!

So connect up the LCD as shown in the breadboard diagram. Then just upload the code into the Arduino and the date and time will be displayed in the LCD Display. So here's the code.

CODE:

#include <Wire.h>
#include <RealTimeClockDS1307.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define Display_Clock_Every_N_Seconds 10 
#define Display_ShortHelp_Every_N_Seconds 60
String tz;
int hours = 0;
int minutes = 0;
int seconds = 0;
int dates = 0;
int months = 0;
int years = 0;
int ap = 0;
void setup() {
  Serial.begin(9600);
  lcd.begin(16,2); 
  pinMode(A3, OUTPUT);
  digitalWrite(A3, HIGH);
  pinMode(A2, OUTPUT);
  digitalWrite(A2, LOW);
}

void loop() {
  RTC.readClock();
    if(ap == 1)
    {
    tz = "PM";
    }
    else
    {
    tz ="AM";
    }
    lcd.home();
    hours = RTC.getHours();
    minutes = RTC.getMinutes();
    seconds = RTC.getSeconds();
    ap = RTC.isPM();
    dates = RTC.getDate();
    months = RTC.getMonth();
    years = RTC.getYear();
    lcd.print(hours);
    lcd.print(":");
    lcd.print(minutes);
    lcd.print(":");
    lcd.print(seconds);
    lcd.print(" ");
    lcd.print(tz);
    lcd.setCursor(0, 1);
    lcd.print(dates);
    lcd.print(":");
    lcd.print(months);
    lcd.print(":");
    lcd.print(years);
    delay(250);
    lcd.clear();
    lcd.home();
    lcd.print(hours);
    lcd.print(" ");
    lcd.print(minutes);
    lcd.print(" ");
    lcd.print(seconds);
    lcd.print(" ");
    lcd.print(tz);
    lcd.setCursor(0, 1);
    lcd.print(dates);
    lcd.print(" ");
    lcd.print(months);
    lcd.print(" ");
    lcd.print(years);
    delay(250);
    lcd.clear();
}

After connecting the RTC module and uploading the code. The LCD will display the time in the top row and the date in the bottom row. This version is useful for learning the basic commands and let you to use these commands in your future projects.

Step 7: Displaying the Time (Shift Register Version)

Shift Register LCD Version:

This version used The Shift Register module to send data to the LCD using only two pins instead of six pins. This module can be bought but I wanted to make it. The full instructions on making the module are given in this link COMING SOON!!!. So just connect the two pins of the Arduino to the module and upload the code given below and the same output will be observed like in the simple version.

CODE:

#include <Wire.h>
#include <RealTimeClockDS1307.h>
#include <LiquidCrystal_SR.h>

LiquidCrystal_SR lcd(8,7,TWO_WIRE);

#define Display_Clock_Every_N_Seconds 10 
#define Display_ShortHelp_Every_N_Seconds 60
String tz;
int hours = 0;
int minutes = 0;
int seconds = 0;
int dates = 0;
int months = 0;
int years = 0;
int ap = 0;
void setup() {
//  Wire.begin();
  Serial.begin(9600);
  lcd.begin(16,2); 
  
    pinMode(A3, OUTPUT);
  digitalWrite(A3, HIGH);
  pinMode(A2, OUTPUT);
  digitalWrite(A2, LOW);
}

void loop() {
  RTC.readClock();
    ap = RTC.isPM();
    if(ap == 1)
    {
    tz = "PM";
    }
    else
    {
    tz ="AM";
    }
    lcd.home();
    hours = RTC.getHours();
    minutes = RTC.getMinutes();
    seconds = RTC.getSeconds();
    dates = RTC.getDate();
    months = RTC.getMonth();
    years = RTC.getYear();
    lcd.print(hours);
    lcd.print(":");
    lcd.print(minutes);
    lcd.print(":");
    lcd.print(seconds);
    lcd.print(" ");
    lcd.print(tz);
    lcd.setCursor(0, 1);
    lcd.print(dates);
    lcd.print(":");
    lcd.print(months);
    lcd.print(":");
    lcd.print(years);
    delay(250);
    lcd.clear();
    lcd.home();
    lcd.print(hours);
    lcd.print(" ");
    lcd.print(minutes);
    lcd.print(" ");
    lcd.print(seconds);
    lcd.print(" ");
    lcd.print(tz);
    lcd.setCursor(0, 1);
    lcd.print(dates);
    lcd.print(" ");
    lcd.print(months);
    lcd.print(" ");
    lcd.print(years);
    delay(250);
    lcd.clear();
}

This second code uses a different library if you already have this module, please use this library for the above code to work.

We finally reached the end of this instructable. I hope that after reading this the viewer has obtained more than the basic knowledge of the DS1307 RTC Module. If you have any corrections or suggestions please comment below. Till next time bye.

<p>Connect the oscilator's case do GND, it can gain accuracy :).</p>
<p>Thanks for that!!! I forgot about grounding the oscillator's case!!!</p>
I can't download this pdf canu help me
<p>#include &lt;DS1307RTC.h&gt;</p><p>#include &lt;LiquidCrystal.h&gt;</p><p>#include &lt;Wire.h&gt;</p><p>#include &lt;Time.h&gt;</p><p>LiquidCrystal lcd(12,11,10,7,6,5,4);</p><p>void setup() {</p><p> Serial.begin(9600);</p><p> while (!Serial) ; // wait for serial</p><p> delay(200);</p><p> Serial.println(&quot;DS1307RTC Read Test&quot;);</p><p> Serial.println(&quot;-------------------&quot;);</p><p>}</p><p>void loop() {</p><p> tmElements_t tm;</p><p> if (RTC.read(tm)) {</p><p> Serial.print(&quot;Ok, Time = &quot;);</p><p> print2digits(tm.Hour);</p><p> Serial.write(':');</p><p> print2digits(tm.Minute);</p><p> Serial.write(':');</p><p> print2digits(tm.Second);</p><p> Serial.print(&quot;, Date (D/M/Y) = &quot;);</p><p> Serial.print(tm.Day);</p><p> Serial.write('/');</p><p> Serial.print(tm.Month);</p><p> Serial.write('/');</p><p> Serial.print(tmYearToCalendar(tm.Year)-2000);</p><p> Serial.println();</p><p> lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.</p><p> lcd.clear(); // start with a blank screen</p><p> lcd.setCursor(0,0); </p><p>lcd.print(tm.Hour); </p><p>lcd.print(&quot;:&quot;); </p><p>lcd.print(tm.Minute); </p><p>lcd.print(&quot;:&quot;); </p><p> lcd.print(tm.Second); // change this text to whatever you like. keep it clean.</p><p> lcd.setCursor(0,1); // set cursor to column 0, row 1</p><p> lcd.print(tm.Day);</p><p> lcd.print(&quot;/&quot;); </p><p> lcd.print(tm.Month);</p><p> lcd.print(&quot;/&quot;); </p><p> lcd.print(tmYearToCalendar(tm.Year)-2000);</p><p> } else {</p><p> if (RTC.chipPresent()) {</p><p> Serial.println(&quot;The DS1307 is stopped. Please run the SetTime&quot;);</p><p> Serial.println(&quot;example to initialize the time and begin running.&quot;);</p><p> Serial.println();</p><p> } else {</p><p> Serial.println(&quot;DS1307 read error! Please check the circuitry.&quot;);</p><p> Serial.println();</p><p> }</p><p> delay(9000);</p><p> }</p><p> delay(1000);</p><p>}</p><p>void print2digits(int number) {</p><p> if (number &gt;= 0 &amp;&amp; number &lt; 10) {</p><p> Serial.write('0');</p><p> }</p><p> Serial.print(number);</p><p>}</p>
<p>I used the RTC control sketch from Vaughters and found it to be useful for inclusion in my own projects. I've dumped it below with some of my own tiny additions.</p><p>The image attached is of a stripboard version</p><p>/* RTC Control v1.001</p><p> * by &lt;http://www.combustory.com&gt; John Vaughters</p><p> *</p><p> * THIS CODE IS FREE FOR ANYTHING - There is no Rocket Science here. No need to create some long GPL statement.</p><p> *</p><p> * Credit to:</p><p> * Maurice Ribble - <a href="http://www.glacialwanderer.com/hobbyrobotics" rel="nofollow"> http://www.glacialwanderer.com/hobbyrobotics </a> for RTC DS1307 code</p><p> * BB Riley - Underhill Center, VT &lt;brianbr@wulfden.org&gt; For simplification of the Day of Week and month</p><p> * and updating to Arduino 1.0 </p><p> * peep rada - from Arduino Forum - Found that only 32 registers per I2C connection was possible </p><p> * </p><p> * With this code you can set the date/time, retreive the date/time and use the extra memory of an RTC DS1307 chip. </p><p> * The program also sets all the extra memory space to 0xff.</p><p> * Serial Communication method with the Arduino that utilizes a leading CHAR for each command described below. </p><p> *</p><p>FOR DIY RTC: <a href="https://www.instructables.com/id/Arduino-Real-Time-Clock-DS1307/" rel="nofollow"> https://www.instructables.com/id/Arduino-Real-Time...</a></p><p>*****Connections*****!!</p><p>RTC ---- UNO V3 ---- NANO V3.0G</p><p>5V -- 5V -- 5V</p><p>GND -- GND -- GND</p><p>SCL -- A5 -- A3</p><p>SDA -- A4 -- A2</p><p> ****Commands:*****!!</p><p> * T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99) - T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year) -</p><p> * T - Sets the date of the RTC DS1307 Chip. </p><p> * Example to set the time for 25-Jan-2012 @ 19:57:11 for the 4 day of the week, use this command - T1157194250112</p><p> * Q(1-2) - (Q1) Memory initialization (Q2) RTC - Memory Dump </p><p> * R - Read/display the time, day and date</p><p> *</p><p> * ---------------------------------------------------------</p><p> * Notes:</p><p> * Version 1.0</p><p> * Moving this code to Version 1.0 because this code has been updated to Arduino v1.0 and the features have</p><p> * been well tested and improved in a collaborative effort.</p><p> * - Fixed the issue of not being able to access all the registers - JWV</p><p> * - Added initialization for all non-time registers - JWV</p><p> * - Added Dump of all 64 registers - JWV</p><p> * - Some Date/Time reformatting and cleanup of display, added Day/Month texts - BBR</p><p> * - Made compatible with Arduino 1.0 - BBR</p><p> * - Added Rr command for reading date/time - BBR</p><p> * - Made commands case insensitive - BBR</p><p> * - Create #define varibles to support pre Arduino v1.0 - JWV</p><p> * Version 0.01</p><p> * Inital code with basics of setting time and the first 37 registers and dumping the first 32 registers. </p><p> * The code was based on Maurice Ribble's original code.</p><p> * </p><p> */</p><p>#include &quot;Wire.h&quot;</p><p>#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address</p><p>// Arduino version compatibility Pre-Compiler Directives</p><p>#if defined(ARDUINO) &amp;&amp; ARDUINO &gt;= 100 // Arduino v1.0 and newer</p><p> #define I2C_WRITE Wire.write </p><p> #define I2C_READ Wire.read</p><p>#else // Arduino Prior to v1.0 </p><p> #define I2C_WRITE Wire.send </p><p> #define I2C_READ Wire.receive</p><p>#endif</p><p>// Global Variables</p><p>int command = 0; // This is the command char, in ascii form, sent from the serial port </p><p>int i;</p><p>long previousMillis = 0; // will store last time Temp was updated</p><p>byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;</p><p>byte test;</p><p>byte zero;</p><p>char *Day[] = {&quot;&quot;,&quot;Sun&quot;,&quot;Mon&quot;,&quot;Tue&quot;,&quot;Wed&quot;,&quot;Thu&quot;,&quot;Fri&quot;,&quot;Sat&quot;};</p><p>char *Mon[] = {&quot;&quot;,&quot;Jan&quot;,&quot;Feb&quot;,&quot;Mar&quot;,&quot;Apr&quot;,&quot;May&quot;,&quot;Jun&quot;,&quot;Jul&quot;,&quot;Aug&quot;,&quot;Sep&quot;,&quot;Oct&quot;,&quot;Nov&quot;,&quot;Dec&quot;};</p><p>// Convert normal decimal numbers to binary coded decimal</p><p>byte decToBcd(byte val)</p><p>{</p><p> return ( (val/10*16) + (val%10) );</p><p>}</p><p>// Convert binary coded decimal to normal decimal numbers</p><p>byte bcdToDec(byte val)</p><p>{</p><p> return ( (val/16*10) + (val%16) );</p><p>}</p><p>// 1) Sets the date and time on the ds1307</p><p>// 2) Starts the clock</p><p>// 3) Sets hour mode to 24 hour clock</p><p>// Assumes you're passing in valid numbers, Probably need to put in checks for valid numbers.</p><p>void setDateDs1307() </p><p>{</p><p> second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. </p><p> minute = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48));</p><p> hour = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48));</p><p> dayOfWeek = (byte) (Serial.read() - 48);</p><p> dayOfMonth = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48));</p><p> month = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48));</p><p> year= (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48));</p><p> Wire.beginTransmission(DS1307_I2C_ADDRESS);</p><p> I2C_WRITE(zero);</p><p> I2C_WRITE(decToBcd(second) &amp; 0x7f); // 0 to bit 7 starts the clock</p><p> I2C_WRITE(decToBcd(minute));</p><p> I2C_WRITE(decToBcd(hour)); // If you want 12 hour am/pm you need to set</p><p> // bit 6 (also need to change readDateDs1307)</p><p> I2C_WRITE(decToBcd(dayOfWeek));</p><p> I2C_WRITE(decToBcd(dayOfMonth));</p><p> I2C_WRITE(decToBcd(month));</p><p> I2C_WRITE(decToBcd(year));</p><p> Wire.endTransmission();</p><p>}</p><p>// Gets the date and time from the ds1307 and prints result</p><p>void getDateDs1307()</p><p>{</p><p> // Reset the register pointer</p><p> Wire.beginTransmission(DS1307_I2C_ADDRESS);</p><p> I2C_WRITE(zero);</p><p> Wire.endTransmission();</p><p> Wire.requestFrom(DS1307_I2C_ADDRESS, 7);</p><p> // A few of these need masks because certain bits are control bits</p><p> second = bcdToDec(I2C_READ() &amp; 0x7f);</p><p> minute = bcdToDec(I2C_READ());</p><p> hour = bcdToDec(I2C_READ() &amp; 0x3f); // Need to change this if 12 hour am/pm</p><p> dayOfWeek = bcdToDec(I2C_READ());</p><p> dayOfMonth = bcdToDec(I2C_READ());</p><p> month = bcdToDec(I2C_READ());</p><p> year = bcdToDec(I2C_READ());</p><p> if (hour &lt; 10)</p><p> Serial.print(&quot;0&quot;);</p><p> Serial.print(hour, DEC);</p><p> Serial.print(&quot;:&quot;);</p><p> if (minute &lt; 10)</p><p> Serial.print(&quot;0&quot;);</p><p> Serial.print(minute, DEC);</p><p> Serial.print(&quot;:&quot;);</p><p> if (second &lt; 10)</p><p> Serial.print(&quot;0&quot;);</p><p> Serial.print(second, DEC);</p><p> Serial.print(&quot; &quot;);</p><p> Serial.print(Day[dayOfWeek]);</p><p> Serial.print(&quot;, &quot;);</p><p> Serial.print(dayOfMonth, DEC);</p><p> Serial.print(&quot; &quot;);</p><p> Serial.print(Mon[month]);</p><p> Serial.print(&quot; 20&quot;);</p><p> if (year &lt; 10)</p><p> Serial.print(&quot;0&quot;);</p><p> Serial.println(year, DEC);</p><p>}</p><p>void setup() {</p><p> Wire.begin();</p><p> Serial.begin(57600); </p><p> zero=0x00;</p><p> Serial.println(&quot;Ready&quot;);</p><p>}</p><p>void loop() {</p><p> if (Serial.available()) { // Look for char in serial queue and process if found</p><p> command = Serial.read();</p><p> if (command == 84 || command == 116) { //If command = &quot;Tt&quot; Set Date</p><p> setDateDs1307();</p><p> getDateDs1307();</p><p> Serial.println(&quot; &quot;);</p><p> }</p><p> else if (command == 82 || command == 114) { //If command = &quot;Rr&quot; Read Date ... BBR</p><p> getDateDs1307();</p><p> Serial.println(&quot; &quot;);</p><p> }</p><p> else if (command == 81 || command == 113) { //If command = &quot;Qq&quot; RTC1307 Memory Functions</p><p> delay(100); </p><p> if (Serial.available()) {</p><p> command = Serial.read(); </p><p> if (command == 49) { //If command = &quot;1&quot; RTC1307 Initialize Memory - All Data will be set to </p><p> // 255 (0xff). Therefore 255 or 0 will be an invalid value. </p><p> Wire.beginTransmission(DS1307_I2C_ADDRESS); // 255 will be the init value and 0 will be considered </p><p> // an error that occurs when the RTC is in Battery mode.</p><p> I2C_WRITE(0x08); // Set the register pointer to be just past the date/time registers.</p><p> for (i = 1; i &lt;= 24; i++) {</p><p> I2C_WRITE(0Xff);</p><p> delay(10);</p><p> } </p><p> Wire.endTransmission();</p><p> Wire.beginTransmission(DS1307_I2C_ADDRESS); </p><p> I2C_WRITE(0x21); // Set the register pointer to 33 for second half of registers. Only 32 writes per connection allowed.</p><p> for (i = 1; i &lt;= 33; i++) {</p><p> I2C_WRITE(0Xff);</p><p> delay(10);</p><p> } </p><p> Wire.endTransmission();</p><p> getDateDs1307();</p><p> Serial.println(&quot;: RTC1307 Initialized Memory&quot;);</p><p> }</p><p> else if (command == 50) { //If command = &quot;2&quot; RTC1307 Memory Dump</p><p> getDateDs1307();</p><p> Serial.println(&quot;: RTC 1307 Dump Begin&quot;);</p><p> Wire.beginTransmission(DS1307_I2C_ADDRESS);</p><p> I2C_WRITE(zero);</p><p> Wire.endTransmission();</p><p> Wire.requestFrom(DS1307_I2C_ADDRESS, 32);</p><p> for (i = 0; i &lt;= 31; i++) { //Register 0-31 - only 32 registers allowed per I2C connection</p><p> test = I2C_READ();</p><p> Serial.print(i);</p><p> Serial.print(&quot;: &quot;);</p><p> Serial.print(test, DEC);</p><p> Serial.print(&quot; : &quot;);</p><p> Serial.println(test, HEX);</p><p> }</p><p> Wire.beginTransmission(DS1307_I2C_ADDRESS);</p><p> I2C_WRITE(0x20);</p><p> Wire.endTransmission();</p><p> Wire.requestFrom(DS1307_I2C_ADDRESS, 32); </p><p> for (i = 32; i &lt;= 63; i++) { //Register 32-63 - only 32 registers allowed per I2C connection</p><p> test = I2C_READ();</p><p> Serial.print(i);</p><p> Serial.print(&quot;: &quot;);</p><p> Serial.print(test, DEC);</p><p> Serial.print(&quot; : &quot;);</p><p> Serial.println(test, HEX);</p><p> }</p><p> Serial.println(&quot; RTC1307 Dump end&quot;);</p><p> } </p><p> } </p><p> }</p><p> Serial.print(&quot;Command: &quot;);</p><p> Serial.println(command); // Echo command CHAR in ascii that was sent</p><p> }</p><p> command = 0; // reset command </p><p> delay(100);</p><p> }</p><p>//*****************************************************The End***********************</p>
<p>Congrats!!!. The module looks really cool!!</p>
<p>I am trying to do the same project on arduino uno. But I am not getting any value on my i2c and everything remains initialised and stuck at 0. I tried the same on tm4c123g launchpad but to no avails. Can anyone please help?</p>
How to change set the correct time.I used the above comment<br>&quot;void setup() {<br> <br>RTC.setHours(07);<br>RTC.setMinutes(24);<br>RTC.setSeconds(30);<br>RTC.setDate(11);<br>RTC.setMonth(9);<br>RTC.setYear(2016);<br>}&quot;<br><br>but I could not fix it.please help us.
<p>how about the serial communication between the arduino and visual basic sir?</p>
<p>sir,in my project of smart sprinkler ,the sprinkler should automatically get on for a set duration(for ex- if i set the timer on for 5-6 am everyday the sprinkler should get on automatically on the assigned days.)So, how can it be done by using a RTC(real time clock module for arduino.)??</p>
<p>Hi, i&acute;am working on a project like what you want.Maybe I&acute;ll finish this week, I think. It will have the time and on/off set point.Now I&acute;am working on the &quot;OFF&quot; set point.You can buy a cheap timer that will do the work, but you want to do it with arduino ,right?Regards!</p>
<p>help me please. Please teach me on how to remove the testings without changing the way it works. I tried removing it, but it becomes error. I'm clueless</p>
<p>In your example you are using Analog pin 4,5. How can I change this in the code? I would like to use Analog ping 0,1 on my arduino micro.</p><p>Is the real time clock affects other analog pin read values on any other way?</p>
<p>Great work. </p>
<p>Ok I finally got brave and built the DS1307 RTC kit from Adafruit. Since I only had the 16x2 LCD with buttons I had to change the pin assignments. But for a beginner I got it to work the first time. Guess you CAN teach an old dog new tricks.</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Nice work...sir.</p><p>Please share your code.Actually i m fresher in this domain i am nw working arduino interfacing with sensor include rtc.so i need it.please help me sir.</p><p>my email id is: roy.rajdip1@gmail.com</p>
<p>Yes is too good</p>
How to set time?
<p>Cant you just use a clock signal from the Arduino using time keeping libraries instead of a crystal oscillator??</p>
<p>i need ur help......</p><p>while displaying time using this code it displays as 45:165:85</p><p> 165/165/165</p><p>please help me to solve this,,,im stuck with this,,,,</p>
<p>Can we use a ready made RT module. If yes, would the wiring and coding remain same?</p>
<p>Can we use a ready-made DS1307 clock module? If yes, then will the wiring remain same?</p>
<p>did u not program A4 and A5?</p>
<p>how can i use the real time clock to switch a 12v dc relay at set time</p>
<p>Everytihing is nice and great my only problem is that in the first testing ds1307_sketch when i open the serial monitor it just runs and runs i mean i can't see what is written how to stop it means so that stays like in your screen shot of the menu mine is runnig too fast <br>my options are selected autoscroll no line ending and 9600 baud<br>thank you!</p>
<p>This video Arduino with RTC Plis like and Subscribe Share</p><p><a href="https://www.youtube.com/watch?v=q3MvkfzpVAY" rel="nofollow">http://www.youtube.com/watch?v=q3MvkfzpVAY</a></p>
<p>i had a little trouble with serial communication with ds1307_sketch.ino. Problem was that serial command didnt have enough time to get to buffer. So i added dealy of 100ms as a first line to processcommand function.</p>
<p>good job MR, IS THE BEST</p>
<p>Nice and good job ! :) This works only with 5V ? Won't work with 3.3V ?</p>
<p>Thanks a lot for explaining this project thoroughly. I am electronics students and currently learning arduino. I made this project with the help of your tutorial and it works fine for me. It shows same output as in video and pics. But my question is if i want to make alarm and i add some instructions at the end of program than is it possible to works?</p><p>For example :</p><p> if (hours==8 &amp;&amp; minutes==15 &amp;&amp; seconds&lt;=34) </p><p> { </p><p> digitalWrite(led,HIGH); </p><p> } </p><p>else if (hours==13 &amp;&amp; minutes==00 &amp;&amp; seconds()&lt;=19 ) </p><p> { </p><p> digitalWrite(led,HIGH); </p><p> }</p>
<p>Great tutorial! Very helpful indeed! I'm gonna use this to make my next Arduino project.. Thanks!!!</p>
<p>Thank you :) hope it gives you new ideas for an interesting project!</p>
<p>Thanks for the thorough instructions, but I have a question. Why did you connect the A2 and A3 arduino connections to the power and ground of the module (instead of the V5 and Ground arduino connections to the power and ground of the module).</p>
<p>The way I made it is just for convenience so that the module can be inserted with the 4-pin header into the analog pins of A0-A3 and the module is up and running!...............suppose you need to use those extra two analog pins just connect it to V5 and GND of the Arduino. There is no other reason other than for the convenience of the connections!!!</p>
<p>Great tutorial! Very helpful indeed! I'm gonna use this to make my next Arduino project.. Thanks!!!</p>
<p>interesting project.<br>Just two considerations: The DS3107 is not really very accurate. The DS3231 is compatible and much more accurate.<br>Though selfbuild is always nice to do... you may wonder if you should for the RTC as a Module, including a 24C32 EEPROM is available for abt 1 euro. I think the chip by itself is already more expensive.</p><p><a href="http://www.aliexpress.com/item/Hot-Sale-DS3231-AT24C32-IIC-Precision-RTC-Real-Time-Clock-Memory-Module-For-Arduino-Free-Shipping/32245922853.html" rel="nofollow">http://www.aliexpress.com/item/Hot-Sale-DS3231-AT2...</a></p>
<p>Hi,</p><p>Very useful project. Where can I get DS1307 in India? It is not available on ebay.in</p><p>Can you also tell me how much will it cost to do the whole project in Rs.? I see modules available for Rs.300 on ebay. Is it worth to build your own?</p><p>Thanks and keep up the great work!</p><p>Mohan</p>
<p>Get the IC from this website its a very reliable site (http://www.onlinetps.com/shop/index.php?main_page=product_info&amp;cPath=12_52&amp;products_id=140) And making the board will cost you less than 70<img alt="INR" height="10" src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Indian_Rupee_symbol.svg/7px-Indian_Rupee_symbol.svg.png" style="vertical-align: baseline;" width="7"> plus you will improve your circuit prototyping skills!!!!</p>
<p>the module on eBay that u link to is not a shift register but an I2C interface. :-)<br>The 2 wire shiftregister interface works well, as I have built a couple myself. In parts it will cost u about 80 eurocents. The I2C interface you refer to, currently costs 94 eurocents (free shipping) on Aliexpress.<br>I am all for self build... but with those prices it gets harder and harder to justify :-)<br>Nevertheless... the 2wire shiftregister is easy to build and works well. The I2C interface ofcourse frees up 2 pins as it shares A4 and A5 with the RTC.</p><p>https://arduinodiy.wordpress.com/2014/01/12/two-wire-interface-for-lcd/</p>
<p>Neat project! </p>
<p>thanks</p>

About This Instructable

252,345views

175favorites

License:

Bio: I am currently doing my BE in mechanical engineering but im more interested in physics and robotics and such stuff.I am new here hope ... More »
More by Naren_Murali:Balancing Instructable Robot Arduino Real Time Clock (DS1307) 3 Arduino Pins to 24+ Output Pins 
Add instructable to: