ESP8266: Connection to DS3231 RTC

Introduction

The objective of this post is to explain how to connect the ESP8266 to a DS3231 Real Time Clock. It also explains how to create a simple program to configure the time and date of the RTC and to measure it periodically.

If you prefer, you can check a video tutorial on my YouTube Channel:

Hardware

For this tutorial, we consider the use of the DS3231 Real Time Clock (described in more detail in this previous post) integrated in an easy to use board, which can be bought at eBay for less than 1 euro. This board is shown in figure 1.

We also assume the use of the ESP8266 libraries for the Arduino IDE. You can check here how to configure the Arduino IDE to support the ESP8266.

 DS3231 based board.
Figure 1 – DS3231 based board.

The hardware diagram to connect this board (which we called DS3231, for simplicity) to the ESP8266 is very easy and is shown in figure 2.

Connection diagram between the ESP8266 and the DS3231.
Figure 2 – Connection diagram between the ESP8266 and the DS3231.

As can be seen in the diagram, the DS3231 uses an I2C interface to interact with microcontrollers. Since we are using the Arduino IDE, we have the Wire library available to handle the I2C protocol in the ESP8266, which we will later use when creating the program to interact with the RTC.

As described in the documentation of the ESP8266 libraries for the Arduino IDE, the default pins for the I2C in the Wire library  are pins 4 (SDA) and 5 (SDL). If you are using a NodeMCU board, take into consideration that the board pins don’t correspond to the ESP8266 pins (check here the correct mapping).

The tests were performed using a NodeMCU board, a very cheap and easy to use ESP8266 board.

Software Library

As usual, the Arduino Environment provides a wide range of libraries to interface with different devices, and the DS3231 is no exception. So, we use the library shown in figure 3 which, as stated in the description, is tested on the ESP8266.

Library to interact with the DS3231 from the ESP8266.
Figure 3 – Library to interact with the DS3231 from the ESP8266.

This library provides easy to use functions to interface with the RTC, without the need for the programmer to worry about the low level details of the I2C protocol. Besides that, it comes with some code samples to help us get started.

We can install it using the library manager of the Arduino IDE.

Software

As stated before, we will create a simple program to configure the time and date of the real time clock and then read it from 20 to 20 seconds and print it to the serial console.

First, we need to include the newly installed library that allows us to interact with the DS3231 and also the Arduino library that implements the communication with I2C devices (wire library):

#include <Wire.h> //I2C library
#include <RtcDS3231.h> //RTC library

The functions to interact with the RTC are provided as methods of the RtcDS3231 class. So, we declare an object of this class before the setup function:

RtcDS3231 rtcObject;

Update: If you are using version 2.0.0 of the library or greater, then you need to declare the object as follows:

RtcDS3231<TwoWire> rtcObject(Wire);

In the setup function, we begin the serial connection and then we call the Begin method on the RtcDS3231 object we previously declared. By analyzing the source code for this method, we can see that it only starts the I2C Wire library by calling the Wire.begin() method.  Nevertheless this is just a detail that we don’t need to worry about.

To make things simple and the code cleaner, the RTC library uses another class, called RtcDateTime, which allows us to create objects to hold the date and time information. This is easier to maintain than having to define a different variable to hold all the parameters from seconds to years.

So, we declare an object of this class and pass the parameters, from year to second, in the constructor. Finally, we call the setDateTime method on the RtcDS3231 object and pass it the RtcDateTime object that holds the date and time information.

All those steps to execute in the setup function are shown bellow:

void setup() {
 
  Serial.begin(115200);  //Starts serial connection
  rtcObject.Begin();     //Starts I2C
 
  RtcDateTime currentTime = RtcDateTime(16, 05, 18, 21, 20, 0); //define date and time object
  rtcObject.SetDateTime(currentTime);                           //configure the RTC with object
 
}

Finally, we will read the current date and time from the RTC in the main loop function. In this simple example, we will poll the RTC every 20 seconds.

To get a the current time and date, we call the GetDateTime method on our previously defined RtcDS3231 object (which we named “rtcObject”). This method will return a RtcDateTime object, as we used before in the setup function.

The RtcDateTime class has a method for getting each of the parameters of date and time. We will use those methods to get them and print them to a string (using the sprintf function).

Once we have all the information of date and time on a string, we send it to the serial port, to get the output on the serial console of the Arduino IDE.

In the end of the main loop, we put a delay of 20 seconds. Check the whole main loop code below:

void loop() {
 
  RtcDateTime currentTime = rtcObject.GetDateTime();    //get the time from the RTC
 
  char str[20];   //declare a string as an array of chars
 
  sprintf(str, "%d/%d/%d %d:%d:%d",     //%d allows to print an integer to the string
          currentTime.Year(),   //get year method
          currentTime.Month(),  //get month method
          currentTime.Day(),    //get day method
          currentTime.Hour(),   //get hour method
          currentTime.Minute(), //get minute method
          currentTime.Second()  //get second method
         );
 
  Serial.println(str); //print the string to the serial port
 
  delay(20000); //20 seconds delay
 
}

Note: Although this example uses a char array, we could also use a string object to print the time and date parameters. Nevertheless, it is important to know that we can use char arrays as strings, which is more efficient. Also, in pure C, there are no objects, so strings are always arrays of chars.

You can check the full source code bellow, with both declarations of the RtcDS3231 objects for versions 1.0.1 and 2.0.0.

#include <Wire.h>       //I2C library
#include <RtcDS3231.h>  //RTC library
 
//RtcDS3231 rtcObject;              //Uncomment for version 1.0.1 of the rtc library
RtcDS3231<TwoWire> rtcObject(Wire); //Uncomment for version 2.0.0 of the rtc library
 
void setup() {
 
  Serial.begin(115200);  //Starts serial connection
  rtcObject.Begin();     //Starts I2C
 
  RtcDateTime currentTime = RtcDateTime(16, 05, 18, 21, 20, 0); //define date and time object
  rtcObject.SetDateTime(currentTime); //configure the RTC with object
 
}
 
void loop() {
 
  RtcDateTime currentTime = rtcObject.GetDateTime();    //get the time from the RTC
 
  char str[20];   //declare a string as an array of chars
 
  sprintf(str, "%d/%d/%d %d:%d:%d",     //%d allows to print an integer to the string
          currentTime.Year(),   //get year method
          currentTime.Month(),  //get month method
          currentTime.Day(),    //get day method
          currentTime.Hour(),   //get hour method
          currentTime.Minute(), //get minute method
          currentTime.Second()  //get second method
         );
 
  Serial.println(str); //print the string to the serial port
 
  delay(20000); //20 seconds delay
 
}

Testing

After uploading the code and opening the serial console from the Arduino IDE, we should get a result similar to the one presented in figure 4.

Output of the program in the serial console of the Arduino IDE.
Figure 4 – Output of the program in the serial console of the Arduino IDE.

Final Notes

This was just a simple tutorial about a basic interaction with the DS3231. So, it is similar to an example provided by the author of the library, which I also encourage you to try.

Nevertheless, this RTC has some more functionalities, which will be explored in other tutorials.

Technical details

  • ESP8266 libraries: v2.3.0
  • RTC library: V1.0.1 / V2.0.0

120 thoughts on “ESP8266: Connection to DS3231 RTC”

  1. Even when I change the data to current time, when I compile it gives me the same time displaying “2009/85/165 37:165:85” do you have any idea why?

    1. Hi,

      That’s weird, I never ran into that issue.

      Maybe it is some problem while setting the initial values. If you copy and paste exactly my code, does that still happen?

      My guesses are either a change in the library API that is causing some configuration problems with the code (what version are you using?) or some electronic problem in the connection that is preventing you from writing the initial content.

      Also, do you have an extra DS3231 where you can test to check if there is no defect in the unit you are currenly using?

      Best regards,
      Nuno Santos

  2. Even when I change the data to current time, when I compile it gives me the same time displaying “2009/85/165 37:165:85” do you have any idea why?

    1. Hi,
      That’s weird, I never ran into that issue.
      Maybe it is some problem while setting the initial values. If you copy and paste exactly my code, does that still happen?
      My guesses are either a change in the library API that is causing some configuration problems with the code (what version are you using?) or some electronic problem in the connection that is preventing you from writing the initial content.
      Also, do you have an extra DS3231 where you can test to check if there is no defect in the unit you are currenly using?
      Best regards,
      Nuno Santos

  3. hi
    i want to use a proximity sensor and want to start counting when the sensor signal is ON and PAUSE when the sensor signal is OFF and counter from the pause point when the sensor is ON again.
    how to do that using NodeMcu and RTC

    1. Hi!

      Sorry, I’ve never used any proximity sensor on the NodeMCU or any other ESP8266 board.

      You will need to find out what proximity sensor device you will use and try to find a suitable Arduino library that also works for the ESP8266.

      Best regards,
      Nuno Santos

  4. hi
    i want to use a proximity sensor and want to start counting when the sensor signal is ON and PAUSE when the sensor signal is OFF and counter from the pause point when the sensor is ON again.
    how to do that using NodeMcu and RTC

    1. Hi!
      Sorry, I’ve never used any proximity sensor on the NodeMCU or any other ESP8266 board.
      You will need to find out what proximity sensor device you will use and try to find a suitable Arduino library that also works for the ESP8266.
      Best regards,
      Nuno Santos

    1. as per the above code, Diagram when i copied and pasted it is working, now i want to change the pins of SDA/SCl to GPIo4,GPIo0.
      when it is changing it is showing same error, how can i change the pins

      1. Hi!

        Have you been able to solve the initial problem with the wrong date time values?

        Regarding changing the pins, I haven’t tested but from what I’ve seen in this library example, you can call the Wire.begin() method, passing as input the SDA and SCL pins you want to use.

        You need to perform this call in the setup function, before the rtcObject.begin call

        The examples is here:
        https://github.com/Makuna/Rtc/blob/master/examples/DS1307_Simple/DS1307_Simple.ino

        Let me know if it works 🙂

        Best regards,
        Nuno Santos

    1. as per the above code, Diagram when i copied and pasted it is working, now i want to change the pins of SDA/SCl to GPIo4,GPIo0.
      when it is changing it is showing same error, how can i change the pins

      1. Hi!
        Have you been able to solve the initial problem with the wrong date time values?
        Regarding changing the pins, I haven’t tested but from what I’ve seen in this library example, you can call the Wire.begin() method, passing as input the SDA and SCL pins you want to use.
        You need to perform this call in the setup function, before the rtcObject.begin call
        The examples is here:
        https://github.com/Makuna/Rtc/blob/master/examples/DS1307_Simple/DS1307_Simple.ino
        Let me know if it works 🙂
        Best regards,
        Nuno Santos

Leave a Reply