Learn how to use the DS3231 real-time clock with an Arduino. In this post we’ll go over basics, the data sheet, wiring it to the Arduino, importing the DS3231 library for Arduino, programming in Arduino, and testing. As a bonus we’ll go over the breadboard wiring for the example of using a 1602 LCD. I hope you enjoy it! Also please check-out the YouTube video below for more details.
The DS3231 is a real-time clock (RTC) that can be used in electronic-related projects. The DS3231 operates with a built-in 3 volt-battery (CR2032) that allows keeping up with the time even after power has been removed from the VCC/GND pins. Think about this in terms of your computer keeping up with time even if you unplug the power from it. As you see, this can have many applications where you want your devices and projects to keep track of time regardless of power status or if we choose to change the code that’s running on our Arduino. It’s also good to know that the RTC DS3231 also has the capability of storing two programmable alarms for a specific time of the day. Another interesting feature is that this RTC is able to ensure accurate time keeping by using a TCXO (temperature compensated crystal oscillator), which helps protect against the external temperature effects that normally affect crystals used for time-keeping. The net accuracy protection just mentioned is specified as plus or minus 2 minutes per year (not bad at all considering the cost of this device)!
The DS3231 RTC is able to keep up time (seconds, minutes, hours), day of the week, and date (day of month, month, and year). It will even account for leap years (days with a Feb 29th), and it’s great that they can be bought at a low cost (see links at the bottom of this page for a few of the many options on where the DS3231 RTC can be purchased).
Operating Voltage
The supply voltage (Vcc for this sensor) should be in the range of 2.3V – 5.5V, with the typical voltage being 3.3V. From a battery perspective, a simple CR2032 3V lithium coin cell battery can be used. For more details on sensors specifications, see the datasheet.
Other relevant device specifications
Operating temperature range: 0 degrees Celsius to +70 degrees Celsius (32 deg F to 158 deg F).
Storage temperature range: -40 degrees Celsius to +85 degrees Celsius (-40deg F to 185 deg F).
Active Supply Current: 200µA to 300µA (actual depends on Vcc voltage – see datasheet).
Standby Supply Current: 110µA to 170µA (actual depends on Vcc voltage – see datasheet).
Timekeeping Battery Current: 0.84µA to 1.0µA (actual depends on VBAT voltage – see datasheet).
Connecting to Arduino
As you can see below, the connection to Arduino is very simple, with only 4 wires being needed (connecting to Vcc, GND, SCL, and SDA), see below for details:
VCC – Connected to Arduino UNO 5V output (can also connect to the 3.3V output).
GND – Connected to Arduino GND.
SCL – Connected to Arduino SCL pin (serial clock pin) for I2C communication protocol.
SDA – Connected to Arduino SDA pin (serial data pin) for I2C communication protocol.

Downloading the DS3231 RTC library
This example uses a Library from Rinky-Dink Electronics which can be found on this link: http://www.rinkydinkelectronics.com/library.php?id=73
Scroll down to the download section and download the DS3231 zip file. If you need further details note that a manual is also attached on the website listed above.

Installing the DS3231 RTC Library
Once the DS3231 zip library has been downloaded, you need to import it within the Arduino IDE. For this, go to the top menu, then click Sketch, Include Library, Add .Zip Library… Then, find the file in the folder in which you downloaded the zip library, select the zip file and click open to import into Arduino IDE. Refer to the two images below for more details.
Arduino Code
The RTC will provide the Arduino with the relevant time/date information when the appropriate code is included in Arduino IDE, but to get the correct time and date, you must first tell the DS3231 what the current time and date is. This means we will have two separate Arduino codes. One to set the time/date and one to read the time/date. Once the time and date is set, the DS3231 will keep it in memory (as long as the built-in battery provides power) and you will be able to simply read the time/date.
Arduino Code – Set DS3231 RTC date and time
Please refer to the Arduino code below for the code to set the date and time on the DS3231 RTC. Note that there are 3 critical functions that are executed in the code below:
- rtc.setDOW(day) to set the day of the week (with day of week entered inside the parenthesis).
- rtc.setTime(hh,mm,ss) where the time is set in 24-hour format entering the hour as under “hh” section, minutes under “mm” section, and seconds under “ss” section.
- stc.setDate(dd,mm,yyyy) where the day is entered in the “dd” section, the month under the “mm” section, and the year on the “yyyy” section.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Arduino Code - DS3231 Clock Setup #include <DS3231.h> // Init the DS3231 using the hardware interface DS3231 rtc(SDA, SCL); // Code from the Demo Example of the DS3231 Library void setup() { // Setup Serial connection Serial.begin(9600); // Uncomment the next line if you are using an Arduino Leonardo //while (!Serial) {} // Initialize the rtc object rtc.begin(); // The following lines can be uncommented to set the date and time rtc.setDOW(SATURDAY); // Set Day-of-Week rtc.setTime(11, 56, 6); // Set the time (24hr format) rtc.setDate(14, 11, 2020); // Set the date to the current day, month, year } void loop() { } |
Arduino Code – Read DS3231 date and time
Please refer to the Arduino code below for the code to read the date and time on the DS3231 RTC. In the example code the day of week, date, and time are being printed out on the serial monitor. This is just an example, so you could use the day/date/time info in any other way to activate a system logic (i.e. run a water sprinkling system on Tuesday evenings from 7:30pm until 7:40pm). The critical functions shown on the code are:
- rtc.getDOWStr() – To get a string (text data type) with the day of the week
- rtc.getDateStr() – To get a string (text data type) with the date
- rtc.getTimeStr() – To get a string (text data type) with the time
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//Arduino Code - DS3231 Clock Read #include <DS3231.h> // Init the DS3231 using the hardware interface DS3231 rtc(SDA, SCL); // Code from the Demo Example of the DS3231 Library void setup() { // Setup Serial connection Serial.begin(9600); // Uncomment the next line if you are using an Arduino Leonardo //while (!Serial) {} // Initialize the rtc object rtc.begin(); } void loop() { // Send Day-of-Week Serial.print(rtc.getDOWStr()); Serial.print(" "); // Send date Serial.print(rtc.getDateStr()); Serial.print(" -- "); // Send time Serial.println(rtc.getTimeStr()); // Wait one second before repeating :) delay (1000); } |
Run Arduino Code
First – Run the code to set the RTC time and date
Next – Run the code to read the RTC time and date and open the Serial Monitor
*Note that you only need to run the first code when you need to set the time and date. Once you set the date and time on the DS3231 RTC, the time/date will be stored. Only re-run the first code if you need to change the time for any reason (i.e. change of time zone, daylight savings, battery died and need to reset, etc).
The screenshots below show what you should see when you test the two Arduino codes listed above. Once you run it, go ahead and then disconnect the power from the Arduino, reconnect it, and then connect back to your computer. No need to re-deploy any of the Arduino codes to your Arduino, simply open the Serial Monitor and you should see the output still showing the correct day of the week, date, and time. Isn’t that cool?


Example Application
There are many uses to the DS3231 RTC module. One simple example is using it to display the time and date on an LCD (1602 LCD). I’ll be covering the 1602 LCD in more detail in a separate post (1602 LCD – Learn how to use with Arduino).
Arduino Code – RTC DS3231 with 1602 LCD
The Arduino code below is very similar to the one previously shown to read the day of week, date, and time on the Serial Monitor. In this case it is assumed that the first code (to set day of week, date, and time) has been run and the RTC is ready to go. Next, go ahead and wire your Arduino as shown on the image above, and then proceed to run the Arduino code shown below.
Note that on the post where I got over how to use the 1602 LCD display I show two methods for connecting the 1602 LCD display to an Arduino UNO. One method is the conventional method, where many outputs from the 1602 LCD are connected to the Arduino UNO digital inputs. The other methods is the I2C method, were the outputs from the 1602 LCD go to an I2C module, which then send the LCD output’s info as a signal to be entered on the Arduino’s I2C’s pins. Given the RTC DS3231 was already using the I2C pins, I decided to use the conventional method for this simple example.
Once you complete and test this example, the result should be what’s shown on the image above:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//Arduino Code - RTC 3231 with 1602LCD Conventional #include <LiquidCrystal.h>// include the library code LiquidCrystal lcd(9,10,4,5,6,7);// Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7) void setup() { lcd.begin(16, 2); // set up the LCD's number of columns and rows: } void loop() { lcd.setCursor(0,0); // set the cursor to column 0, line 0 lcd.print("Time: "); lcd.print(rtc.getTimeStr()); lcd.setCursor(0,1); // set the cursor to column 0, line 1 lcd.print("Date: "); lcd.print(rtc.getDateStr()); delay(1000); //No need to run faster since it should only change 1 second at a time lcd.clear(); // Clears the display } |
Example Application #2
Another example is using the RTC to sound off an alarm at a specified time of day. This examples uses the buzzer shown on a previous post (HC-SR501 PIR Sensor) to generate the alarm sound. As shown on the previously mentioned post, an 2N2222 transistor is used as a switch to power the KY-012 buzzer to avoid drawing power directly from the Arduino IO pins. In this example, we take the output of the DS3231 RTC and compare it against a desired timing in which we want to sound off an alarm. Once that time comes, the alarm (the buzzer) will go off for 10 seconds. Please see the breadboard diagram and Arduino code below for more details.
Arduino Code – RTC DS3231 alarm with KY-012 Buzzer
The code for this example shares many similarities with the ones shown on the examples above. The main differences are that the output showing the current time (as a string) is split into variables for hour (HH), minutes (MM), and seconds (SS). The variables for hour and minutes are then compared against the desired alarm time to determine when to sound off the alarm. The seconds variable is then used to compare against the range of seconds for which the alarm (buzzer) will go off. See code below for details:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <DS3231.h> // Init the DS3231 using the hardware interface DS3231 rtc(SDA, SCL); String timex2 = "Test";//Variable that will be used to store the output of the current time reading String T_Hour_S = "0";//Variable that will be used to store the hour of the current time as a string (in 24hrs format) String T_Min_S = "0";//Variable that will be used to store the minute of the current time as a string String T_Sec_S = "0";//Variable that will be used to store the seconds of the current time as a string int T_Sec = 0;//Variable that will be used to store the seconds of the current time as an integer int Buzzer = 7;//GPIO 7 --- Digital Output to Transistor int Buzzer_State = 0;//Variable to handle the state of the buzzer (on or off) void setup() { // Setup Serial connection Serial.begin(9600); pinMode(Buzzer, OUTPUT); //Step pin as output // Initialize the rtc object rtc.begin(); } void loop() { Serial.println(rtc.getTimeStr()); timex2=rtc.getTimeStr();//Gets the current time and stores it as a string T_Hour_S=timex2.substring(0,2);//Extracts the hour as a sub-string from the whole time string T_Min_S=timex2.substring(3,5);//Extracts the minutes as a sub-string from the whole time string T_Sec_S=timex2.substring(6,8);//Extracts the seconds as a sub-string from the whole time string T_Sec=T_Sec_S.toInt();//Converts the seconds string to integer that will be used for determining if the seconds are between a predefined range for the alarm //For If statement below, state the time (hour and minute) in which alarm will sound off with hours in 24h format if ((T_Hour_S=="14") && (T_Min_S=="14")){//Defines the hour and minute in which the alarm will go off, hours and minutes must be defined with two characters (i.e. "08" and not "8") if ((T_Sec>0) && (T_Sec<10)){ //Alarm would go off for 10 seconds Serial.println("Alarm"); digitalWrite(Buzzer, HIGH); //Turn on the buzzer } else{ digitalWrite(Buzzer, LOW); //Turn off the buzzer } } else{ digitalWrite(Buzzer, LOW); //Turn off the buzzer } // Wait one second before repeating :) delay (1000); } |
Components used in this example
*As an Amazon & Ebay Associate I earn from qualifying purchases.
Component | Link |
Arduino UNO | https://amzn.to/3uYVAMC https://ebay.us/veZdKX |
DS3231 RTC Module | https://amzn.to/3v2FjXh https://ebay.us/W7mbqh |
1602 LCD (with I2C module) | https://amzn.to/2P146LY https://ebay.us/sofDTP |
Breadboard (Elenco 9440) | https://amzn.to/3x23dnq https://ebay.us/FcwSdb |
Electronic Component Kit (includes buzzer) | https://amzn.to/3gj4r7O https://ebay.us/AdnfMw |
This is amaizing code. At Least i start to get some hope . But still how can i set it in accordance to week schedule