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! In the first time the problem was that you reprogrammed the Real Time Clock to the same values. So, every time that program runs from the beginning, it erases any previous values and puts the ones defined in this line of code:
    RtcDateTime currentTime = RtcDateTime(16,05,18,21,20,0);

    On the second time, it should have worked fine as long as the device has been kept connected to any power source. Did you leave it connected to VCC or with a backup battery (not mentioned in the diagram of figure 2)? Only when powered it keeps counting the time.

    1. Thanks for reply,..
      Its CMOS problem after replacing battery it working fine.

      now i connect one relay in 12th pin in esp. i want to turn on and turn off the relay based on ON Duration and OFF Duration in loop.

      1. Awesome 🙂

        Well, depends on the relay you are using. If it is one of those digitally controllable relays, you just need to use the digitalWrite function to activate/deactivate the pin of the ESP and change the state of the relay:

        http://www.ebay.com/sch/i.html?_sacat=0&_sop=15&_nkw=5v+relay+module&rt=nc&LH_BIN=1

        Although they are rated for 5V, I think they work well with 3.3v as supply and control voltages.

        Just a word of caution, I don’t know if you are experienced in working with the main power supply and relays, but be careful because it is dangerous if you don’t know what you are doing. If you are not experienced, please seek guidance from someone with experience. Stay safe!

        1. I’m Student Relay is not problem here, i need know how to set ON Duration and OFF Duration of relay. Example- ON Duration : 30min OFF Duration : 20min . this process should be in repeat mode.

          1. You can do it in multiple ways.

            – Keeping some kind of internal timekeeping that is synchronized with the RTC.
            For example, you program the DS3231 to generate an alarm every minute. When the number of minutes with the relay ON is reached, you turn OFF the relay and start counting the minutes again. When the number of minutes with relay OFF is reached, you turn the relay ON and start counting again.

            Here is an example on how to set the DS3231 to generate an alarm interrupt each second:
            https://techtutorialsx.wordpress.com/2017/02/12/esp8266-ds3231-alarms-once-per-second/

            I have only a tutorial for generating an alarm each second, but the RTC also supports generating an alarm each minute:
            https://github.com/Makuna/Rtc/wiki/RtcDS3231-AlarmTwo

            I’m counting on doing a post on that too but I’m having some busy days.

            – Other alternative is programming the alarms for triggering at specific times.
            For example, the relay starts working ON at 12:00, so you set an alarm for 12:30. When the alarm triggers, you turn OFF the relay and set a new alarm for 12:50. When it triggers again, you turn it ON and set a new alarm. And so on.

            Here you have an example on how to configure the DS3231 to generate an alarm when the seconds match a certain value:
            https://techtutorialsx.wordpress.com/2017/02/04/esp8266-ds3231-alarm-when-seconds-match/

            But again, the RTC also supports generating an alarm when the minutes match:
            https://github.com/Makuna/Rtc/wiki/RtcDS3231-AlarmTwo

            In both cases, you may want to check how to use external interrupts with the ESP8266:
            https://techtutorialsx.wordpress.com/2016/12/11/esp8266-external-interrupts/

            You have other alternatives, but these are two simple ones.

  2. Hi! In the first time the problem was that you reprogrammed the Real Time Clock to the same values. So, every time that program runs from the beginning, it erases any previous values and puts the ones defined in this line of code:
    RtcDateTime currentTime = RtcDateTime(16,05,18,21,20,0);
    On the second time, it should have worked fine as long as the device has been kept connected to any power source. Did you leave it connected to VCC or with a backup battery (not mentioned in the diagram of figure 2)? Only when powered it keeps counting the time.

    1. Thanks for reply,..
      Its CMOS problem after replacing battery it working fine.
      now i connect one relay in 12th pin in esp. i want to turn on and turn off the relay based on ON Duration and OFF Duration in loop.

      1. Awesome 🙂
        Well, depends on the relay you are using. If it is one of those digitally controllable relays, you just need to use the digitalWrite function to activate/deactivate the pin of the ESP and change the state of the relay:
        http://www.ebay.com/sch/i.html?_sacat=0&_sop=15&_nkw=5v+relay+module&rt=nc&LH_BIN=1
        Although they are rated for 5V, I think they work well with 3.3v as supply and control voltages.
        Just a word of caution, I don’t know if you are experienced in working with the main power supply and relays, but be careful because it is dangerous if you don’t know what you are doing. If you are not experienced, please seek guidance from someone with experience. Stay safe!

        1. I’m Student Relay is not problem here, i need know how to set ON Duration and OFF Duration of relay. Example- ON Duration : 30min OFF Duration : 20min . this process should be in repeat mode.

          1. You can do it in multiple ways.
            – Keeping some kind of internal timekeeping that is synchronized with the RTC.
            For example, you program the DS3231 to generate an alarm every minute. When the number of minutes with the relay ON is reached, you turn OFF the relay and start counting the minutes again. When the number of minutes with relay OFF is reached, you turn the relay ON and start counting again.
            Here is an example on how to set the DS3231 to generate an alarm interrupt each second:
            https://techtutorialsx.wordpress.com/2017/02/12/esp8266-ds3231-alarms-once-per-second/
            I have only a tutorial for generating an alarm each second, but the RTC also supports generating an alarm each minute:
            https://github.com/Makuna/Rtc/wiki/RtcDS3231-AlarmTwo
            I’m counting on doing a post on that too but I’m having some busy days.
            – Other alternative is programming the alarms for triggering at specific times.
            For example, the relay starts working ON at 12:00, so you set an alarm for 12:30. When the alarm triggers, you turn OFF the relay and set a new alarm for 12:50. When it triggers again, you turn it ON and set a new alarm. And so on.
            Here you have an example on how to configure the DS3231 to generate an alarm when the seconds match a certain value:
            https://techtutorialsx.wordpress.com/2017/02/04/esp8266-ds3231-alarm-when-seconds-match/
            But again, the RTC also supports generating an alarm when the minutes match:
            https://github.com/Makuna/Rtc/wiki/RtcDS3231-AlarmTwo
            In both cases, you may want to check how to use external interrupts with the ESP8266:
            https://techtutorialsx.wordpress.com/2016/12/11/esp8266-external-interrupts/
            You have other alternatives, but these are two simple ones.

  3. Pingback: ESP8266: DS3231 alarms once per second | techtutorialsx

  4. Pingback: ESP8266: DS3231 alarms once per second | techtutorialsx

  5. He man.
    Well, this is weird for me but I am learning so maybe I do something completely wrong here.
    I have tested your little sketch on an empty NodeMCU E12 and it worked.
    Now I would like to add it to my sketch that always worked but I get an error.
    This error:
    no matching function for call to ‘RtcDateTime::RtcDateTime(int, int, int, int, int, int)’ in this line: RtcDateTime currentTime = RtcDateTime(17, 04, 13, 16, 10, 0); //define date and time object
    Does this mean I have a conflict with a library or with the extinction code?
    Hope it’s an easy one

    1. Hi! Well that’s really weird. But please give me some more information so I can try to reproduce the error.

      Are you importing the Wire library in your sketch? Also, are you importing other libraries apart from the ones in this post?

      Also, what is the version of your RTC library?

      Can you also show me how you are calling that section in your code?

  6. He man.
    Well, this is weird for me but I am learning so maybe I do something completely wrong here.
    I have tested your little sketch on an empty NodeMCU E12 and it worked.
    Now I would like to add it to my sketch that always worked but I get an error.
    This error:
    no matching function for call to ‘RtcDateTime::RtcDateTime(int, int, int, int, int, int)’ in this line: RtcDateTime currentTime = RtcDateTime(17, 04, 13, 16, 10, 0); //define date and time object
    Does this mean I have a conflict with a library or with the extinction code?
    Hope it’s an easy one

    1. Hi! Well that’s really weird. But please give me some more information so I can try to reproduce the error.
      Are you importing the Wire library in your sketch? Also, are you importing other libraries apart from the ones in this post?
      Also, what is the version of your RTC library?
      Can you also show me how you are calling that section in your code?

  7. Weird story on this one for me.
    I have tested this sketch on an empty NodeMCU E12 without any problems. Used every line like in the description.
    Now I would like to ad it on a sketch with an oled display but get this error.
    no matching function for call to ‘RtcDateTime::RtcDateTime(int, int, int, int, int, int)’
    Because I am just in an learning state I am very confused now.
    Do I have a library problem or a conflict on the I2C bus or…
    Checked every thing twice but can’t see any wrong typing/mismatch

  8. Weird story on this one for me.
    I have tested this sketch on an empty NodeMCU E12 without any problems. Used every line like in the description.
    Now I would like to ad it on a sketch with an oled display but get this error.
    no matching function for call to ‘RtcDateTime::RtcDateTime(int, int, int, int, int, int)’
    Because I am just in an learning state I am very confused now.
    Do I have a library problem or a conflict on the I2C bus or…
    Checked every thing twice but can’t see any wrong typing/mismatch

  9. What going on with this reply?
    Every time I have to log in twice but the reply is of gone or it puts an old one in place!
    I have placed a reply on what antepher said on April 14, 2017 at 6:29 pm but see now an old reply .
    So, here it goes again.
    If I put this in the top of the sketch:
    #if defined(ESP8266)
    #include
    #else
    #include
    #endif

    It works on an oled display.
    So far so good, but if I use an Liquidcrystel lcd, the lcd doesn’t show anything any more.
    It looks to me that this library conflicts with other library’s.

    (well, let’s see if this get posted here correctly!)

    1. Hi! It’s weird, I’ve received two similar comments indeed.
      Your includes have disappeared, I think WordPress removes stuff between greater than and lesser than signals, probably due to security reasons.

      Please share the code again, but remove the greater than and lesser than signals 🙂

      1. Well antepher. Thanks for your response but I have given up on this wordpress (uhm) nonsense. I log in to wordpress, type a reply and have to log in again to see the reply but sometimes it is just gone. About the sketch. It is now more and more one big mess because of all the errors that are coming up. I know that it was/is in developer state but know it is just a mess. Guess I have to start over.

          1. Hi antepher.
            Sorry for taking your time on this. I have started all over and it is starting to working well. I had some problems with different kind of library’s and that did make up the error, I guess. I was not aware of the different locations. Had one in My documents. One in users/…. and one in the program folder of Arduino. Now I am able to get the day of week and made it all work on a Liquid-crystal LCD. Thanks again. Your page did help me, even with falling and standing up again.

            1. Hi! No problem, always feel free to ask 🙂 I’m glad it is now working.

              To avoid that kind of issues, I always try to install the libraries via Arduino IDE Library Manager. It may help you reducing these kind of problems in the future.

              That’s the spirit 🙂 many times, when working with microcontrollers and electronics, we face some weird issues. The important is that we try different approaches until we succeed. Many times, starting again from the beginning like you did is the best option.

              Good luck with your project!

  10. What going on with this reply?
    Every time I have to log in twice but the reply is of gone or it puts an old one in place!
    I have placed a reply on what antepher said on April 14, 2017 at 6:29 pm but see now an old reply .
    So, here it goes again.
    If I put this in the top of the sketch:
    #if defined(ESP8266)
    #include
    #else
    #include
    #endif
    It works on an oled display.
    So far so good, but if I use an Liquidcrystel lcd, the lcd doesn’t show anything any more.
    It looks to me that this library conflicts with other library’s.
    (well, let’s see if this get posted here correctly!)

    1. Hi! It’s weird, I’ve received two similar comments indeed.
      Your includes have disappeared, I think WordPress removes stuff between greater than and lesser than signals, probably due to security reasons.
      Please share the code again, but remove the greater than and lesser than signals 🙂

      1. Well antepher. Thanks for your response but I have given up on this wordpress (uhm) nonsense. I log in to wordpress, type a reply and have to log in again to see the reply but sometimes it is just gone. About the sketch. It is now more and more one big mess because of all the errors that are coming up. I know that it was/is in developer state but know it is just a mess. Guess I have to start over.

          1. Hi antepher.
            Sorry for taking your time on this. I have started all over and it is starting to working well. I had some problems with different kind of library’s and that did make up the error, I guess. I was not aware of the different locations. Had one in My documents. One in users/…. and one in the program folder of Arduino. Now I am able to get the day of week and made it all work on a Liquid-crystal LCD. Thanks again. Your page did help me, even with falling and standing up again.

            1. Hi! No problem, always feel free to ask 🙂 I’m glad it is now working.
              To avoid that kind of issues, I always try to install the libraries via Arduino IDE Library Manager. It may help you reducing these kind of problems in the future.
              That’s the spirit 🙂 many times, when working with microcontrollers and electronics, we face some weird issues. The important is that we try different approaches until we succeed. Many times, starting again from the beginning like you did is the best option.
              Good luck with your project!

Leave a Reply

Discover more from techtutorialsx

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

Continue reading