Interfacing DS3231 Real Time Clock RTC Module with Arduino

1,129 views

Introduction

Timekeeping is a fundamental aspect of many electronic projects, and accurate timekeeping is essential for many applications, from data logging to automation. The DS3231 Real Time Clock (RTC) module is a popular choice for timekeeping in Arduino projects due to its high accuracy and low cost. In this article, we will explore how to interface the DS3231 RTC module with an Arduino and how to utilize its features to keep precise track of time and date.

What is DS3231 RTC Module?

The DS3231 RTC module is a low-cost, highly accurate, real-time clock module that is commonly used in electronic projects. It uses a temperature-compensated crystal oscillator (TCXO) to provide high-accuracy timekeeping with an error of only a few seconds per month. The DS3231 module also includes a built-in temperature sensor, which allows it to compensate for temperature variations, further improving its accuracy.

RTC-Module-DS3231
RTC-Module-DS3231

Hardware Components

To interface a DS3231 RTC Module with Arduino, you’ll need the following hardware components to get started:

ComponentsValueQty
Arduino UNO1
USB Cable Type A to B1
DC Power for Arduino1
RTC ModuleDS32311
LCD16×21
Jumper Wires1

RTC Module DS3231 Pinout

RTC-Module-DS3231-pinout
RTC-Module-DS3231-pinout
Pin NamePin Description
VCCConnected to a positive power source.
GNDConnected to ground.
SDASerial Data pin (I2C interface)
SCLSerial Clock pin (I2C interface)
SQWSquare Wave output pin
32K32K oscillator output

DS3231 RTC Arduino Circuit

Make connections according to the circuit diagram given below.

Wiring / Connections

ArduinoRTC Module16×2 LCD
5VVCC
GNDGNDGND
3V3VCC
A4SDASDA
A5SCLSCL

Installing Arduino IDE

First, you need to install Arduino IDE Software from its official website Arduino. Here is a simple step-by-step guide on “How to install Arduino IDE“.

Installing Libraries

Before you start uploading a code, download and unzip the following libraries at /Program Files(x86)/Arduino/Libraries (default), in order to use the sensor with the Arduino board. Here is a simple step-by-step guide on “How to Add Libraries in Arduino IDE“.

Arduino Code

Now copy the following code and upload it to Arduino IDE Software.

#include <Wire.h>                   // for I2C communication
#include <LiquidCrystal_I2C.h>      // for LCD
#include <RTClib.h>                 // for RTC

LiquidCrystal_I2C lcd(0x27, 16, 2); // create LCD with I2C address 0x27, 16 characters per line, 2 lines
RTC_DS3231 rtc;                     // create rtc for the DS3231 RTC module, address is fixed at 0x68

void setup()
{
  Serial.begin(9600); // initialize serial
  lcd.init();       // initialize lcd
  lcd.backlight();  // switch-on lcd backlight
  rtc.begin();       // initialize rtc
}

void loop()
{
  updateLCD();  // update LCD text

  if (Serial.available()) {
    char input = Serial.read();
    if (input == 'u') updateRTC();  // update RTC time
  }
}


/*
   function to update RTC time using user input
*/
void updateRTC()
{


  lcd.clear();  // clear LCD display
  lcd.setCursor(0, 0);
  lcd.print("Edit Mode...");


  // ask user to enter new date and time
  const char txt[6][15] = { "year [4-digit]", "month [1~12]", "day [1~31]",
                            "hours [0~23]", "minutes [0~59]", "seconds [0~59]"
                          };
  String str = "";
  long newDate[6];

  while (Serial.available()) {
    Serial.read();  // clear serial buffer
  }

  for (int i = 0; i < 6; i++) {

    Serial.print("Enter ");
    Serial.print(txt[i]);
    Serial.print(": ");

    while (!Serial.available()) {
      ; // wait for user input
    }

    str = Serial.readString();  // read user input
    newDate[i] = str.toInt();   // convert user input to number and save to array

    Serial.println(newDate[i]); // show user input
  }

  // update RTC
  rtc.adjust(DateTime(newDate[0], newDate[1], newDate[2], newDate[3], newDate[4], newDate[5]));
  Serial.println("RTC Updated!");
}

/*
   function to update LCD text
*/
void updateLCD()
{

  /*
     create array to convert digit days to words:


     0 = Sunday    |   4 = Thursday
     1 = Monday    |   5 = Friday
     2 = Tuesday   |   6 = Saturday
     3 = Wednesday |
  */
  const char dayInWords[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};


  /*
     create array to convert digit months to words:


     0 = [no use]  |
     1 = January   |   6 = June
     2 = February  |   7 = July
     3 = March     |   8 = August
     4 = April     |   9 = September
     5 = May       |   10 = October
     6 = June      |   11 = November
     7 = July      |   12 = December
  */
  const char monthInWords[13][4] = {" ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
                                    "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
                                   };


  // get time and date from RTC and save in variables
  DateTime rtcTime = rtc.now();


  int ss = rtcTime.second();
  int mm = rtcTime.minute();
  int hh = rtcTime.twelveHour();
  int DD = rtcTime.dayOfTheWeek();
  int dd = rtcTime.day();
  int MM = rtcTime.month();
  int yyyy = rtcTime.year();


  // move LCD cursor to upper-left position
  lcd.setCursor(0, 0);


  // print date in dd-MMM-yyyy format and day of week
  if (dd < 10) lcd.print("0");  // add preceeding '0' if number is less than 10
  lcd.print(dd);
  lcd.print("-");
  lcd.print(monthInWords[MM]);
  lcd.print("-");
  lcd.print(yyyy);


  lcd.print("  ");
  lcd.print(dayInWords[DD]);


  // move LCD cursor to lower-left position
  lcd.setCursor(0, 1);


  // print time in 12H format
  if (hh < 10) lcd.print("0");
  lcd.print(hh);
  lcd.print(':');


  if (mm < 10) lcd.print("0");
  lcd.print(mm);
  lcd.print(':');


  if (ss < 10) lcd.print("0");
  lcd.print(ss);


  if (rtcTime.isPM()) lcd.print(" PM"); // print AM/PM indication
  else lcd.print(" AM");
}

Code Explanation

This Arduino code is for interfacing the DS3231 real-time clock (RTC) module with an Arduino board. The code uses the Wire library for I2C communication, the LiquidCrystal_I2C library for interfacing with an LCD, and the RTClib library for communicating with the DS3231 RTC module.

In the setup function, the code initializes the serial port, LCD, and RTC. In the loop function, the code calls the updateLCD function to display the current time and date on the LCD. The code also waits for user input from the serial port. If the user enters the letter “u”, the code calls the updateRTC function to allow the user to set the RTC time manually.

The updateRTC function prompts the user to enter the new date and time using the serial port. The user enters the new values, which are saved to an array. The code then uses the RTClib library to set the new RTC time using the values in the array.

The updateLCD function gets the current time and date from the RTC module using the RTClib library. It then prints the date in the format “dd-MMM-yyyy” and the day of the week on the first line of the LCD. On the second line, it prints the time in 12-hour format with AM/PM indication.

Overall, this code allows for easy interfacing with the DS3231 RTC module and provides a user-friendly way to set the time manually if needed.

Applications

  • Digital clocks
  • Timers and alarms
  • Data loggers and timestamping devices
  • Smart home automation systems
  • Security systems and access control
  • Industrial control systems
  • Internet of Things (IoT) devices
  • Robotics and automation systems
  • GPS-based applications
  • Aerospace and satellite systems

Conclusion

The DS3231 RTC module is an excellent timekeeping device that can be easily interfaced with an Arduino board. By utilizing the features of the DS3231 module, we can achieve accurate and reliable timekeeping for a variety of Arduino projects. Whether you are a beginner or an experienced Arduino user, this tutorial provides a simple and straightforward approach to interfacing the DS3231 RTC module with an Arduino.