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

122 thoughts on “ESP8266: Connection to DS3231 RTC”

    1. Hi!

      Sorry, didn’t understand what problem you are experiencing. Could you please clarify so we can try to help you? 🙂

      Best regards,
      Nuno Santos

    1. Hi!
      Sorry, didn’t understand what problem you are experiencing. Could you please clarify so we can try to help you? 🙂
      Best regards,
      Nuno Santos

    1. Hi! unfortunately I haven’t yet had the chance to test it.

      Nonetheless, since it works with a generic I2C interface, my guess is that it should work.

      Let us know if you have the change to test it 🙂

      Best regards,
      Nuno Santos

    1. Hi! unfortunately I haven’t yet had the chance to test it.
      Nonetheless, since it works with a generic I2C interface, my guess is that it should work.
      Let us know if you have the change to test it 🙂
      Best regards,
      Nuno Santos

  1. When doing the wiring, What do you call pin 4 and 5? D4 and D5?
    Moreover , why is this on pin 4 and 5, can we change that? one more thing on the nodeMcu I can Notice Pins called CLK or SD0 , should we use them instead as there are dedicated for Clock purposes. Thank you

  2. How is the made accurate when it’s set at the time of compiling… i.e. there is a delay in the compiling of the sketch so already several seconds will be lost.

  3. Folowed your instruction but only see:

    23:04:25.898 -> 2000/1/1 0:0:0
    23:04:45.925 -> 2000/1/1 0:0:0
    23:05:05.902 -> 2000/1/1 0:0:0

    Using an ESP-01 SDA-GP02 and SCL -> GP01

Leave a Reply to rahbrokCancel reply

Discover more from techtutorialsx

Subscribe now to keep reading and get access to the full archive.

Continue reading