ESP8266: Reading temperature with the DS3231 RTC

The objective of this post is to explain how get the internal temperature measurements of the DS3231 using an ESP8266 and an easy to use Arduino library.


Introduction

As stated in a previous post, the DS3231 uses temperature compensation to calibrate the adjustable capacitors of its resonance circuit, in order to maintain time and date with accuracy [1].

A very useful feature of the DS3231 is that we can access those temperature measurements through its I2C interface, extending its capabilities beyond those of a simple Real Time Clock.

The objective of the post is to explain how to access those measurements using an ESP8266. It assumes the use of the Arduino IDE with the ESP8266 libraries.

To interact with this RTC from an ESP8266 board, we will use a simple library that hides the implementation details of the I2C protocol, providing us with easy to use functionalities.

This library is the same used in this post where the procedure to configure time and date and read it from the ESP8266 was described. It can be installed using the Library Manager of the Arduino IDE, as shown in figure 1.

esp8266-ds3231-library

Figure 1 – Installation of the DS3231 library using the Library Manager of the Arduino IDE.

Important: Please guarantee the installation of version 1.0.1 of the library or greater, since version 1.0.0 had an issue in one of the functions we will call to get the temperature measurements.

If you prefer a video walk through of the code, please check my YouTube channel bellow.


Hardware

The schematic is very simple and consists basically on the I2C connection between the devices, as shown in figure 2. This is exactly the same setup used in my previous post.

ESP8266 DS3231 diagram

Figure 2 – Connection between the ESP8266 and a DS3231 RTC.


Software

For the demonstration of the temperature functionality, we will just write a simple program to read the temperature from the RTC every 10 seconds and print it to the serial port.

First, we need to include the Wire library, which will be used for the I2C communication, and the RTC library, which provides easy to use functions to interact with the DS3231.

#include <wire.h> // I2C library
#include <rtcds3231.h> //RTC library

The functions to interact with the RTC are available 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 first begin the serial connection and then call the Begin method on the RtcDS3231 object we previously declared. This method will start the I2C Wire library.

In this case, to keep the code simple, we will not configure the time and date of the RTC. Check my previous post for an explanation on how to do it.

void setup() {

  Serial.begin(115200);
  rtcObject.Begin();

}

In the loop function, we will get the measurements by calling the GetTemperature method on the rtc object. This method will get the temperature value from the registers that hold them in the RTC.

The temperature is stored in two registers of the RTC and is represented as a 10-bit code with a resolution of 0.25°C [1]. Again, we don’t need to worry about these details, which is the advantage of using this great library.

As can be seen in the specification of the GetTemperature method, it will return an object of the RtcTemperature class. This class has a method, called AsFloat, which will return the temperature, as demonstrated in the code bellow.

Once we print the temperature to the serial port, we just do a delay of ten seconds before the next measurement.

void loop() {

RtcTemperature temperature = rtcObject.GetTemperature(); //read temperature

  Serial.print(temperature.AsFloat()); //print temperature as a float
  Serial.println(" C");

  delay(10000); //10 seconds delay

}

Just as a note, the RtcTemperature class defines 2 other methods:

AsWholeDegrees(): returns the integer part of the temperature measurement.
GetFractional(): returns the fractional part of the temperature measurement.

The full complete code can be seen bellow.

#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 

void setup() {

  Serial.begin(115200);
  rtcObject.Begin(); //Start I2C connection

}

void loop() {

  RtcTemperature temperature = rtcObject.GetTemperature();  //read temperature

  Serial.print(temperature.AsFloat());  //print temperature as a float
  Serial.println(" C");

  delay(10000);  //10 seconds delay

}

After uploading the code, we just need to open the serial console of the Arduino IDE, which will show a new measurement every 10 seconds.


Final notes

As seen by this post, the DS3231 has functionalities beyond just keeping time and date. By connecting it to an ESP8266, we can create a IoT device to get temperature measurements and accurately timestamp them before sending them to a server.

Since both of the devices are very cheap, this opens the path to the creation of IoT devices affordable to everyone.

Personally, I’ve used the DS3231 not only to measure time, but also to measure temperature in many projects. For example, in my smart medication dispenser prototype, I used this functionality to provide both the user and the caregiver with that information, which was a pertinent add-on without having to spend any more money on extra hardware, such as a temperature sensor.


References

[1] https://datasheets.maximintegrated.com/en/ds/DS3231.pdf


Technical details

  • ESP8266 libraries: v2.3.0
  • RTC library: V1.0.1 / v2.0.0
Advertisements
This entry was posted in ESP8266, Microcontrollers and tagged , , , , , , , , , , . Bookmark the permalink.

14 Responses to ESP8266: Reading temperature with the DS3231 RTC

  1. Lotus49 says:

    Thank you for this. I was struggling to get my DS3231 working but I managed it by following your well laid out explanation.

    Liked by 1 person

  2. Pingback: ESP8266: DS3231 1Hz Square wave generator | techtutorialsx

  3. Pingback: ESP8266: DS3231 Alarm when seconds match | techtutorialsx

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

  5. John Quinn says:

    Greetings
    I have just copied the code above for temp on esp8266 and have run into errors compiling it.
    Errors I am getting are :-
    ”Invalid use of template-name ‘RtcDS3231’ without an argument list”
    “rtcObject was not declared in this scope”
    I have checked the code for any typing errors and checked that the library are correct, these errors also appear in the connecting DS3231 to esp8266 time code.
    have you any idea what the problem could be.

    H J Quinn

    Liked by 1 person

    • antepher says:

      Hi!
      I think the problem is related with an update of the RtcDS3231 class of the RTC library, in the newer versions. This tutorial was done with version 1.0.1. Can you confirm the version you are using?

      To check if that’s the problem, can you please change the declaration of the rtcObject from this:
      RtcDS3231 rtcObject;
      To this:
      RtcDS3231 rtcObject(Wire);
      ?

      Please let me know if it solves your problem.

      Best regards,
      Nuno Santos

      Like

    • antepher says:

      I have updated the code so it works with version 2.0.0 of the library.
      Best regards

      Like

  6. John Quinn says:

    Greetings
    The version of rtc is the current version that is on ‘Github’. rtcObject(Wire) does not work either.
    I then ran the DS3231 Simple sketch this works, so I replaced ‘RtcDS3231 rtcObject’ with ‘RtcDS3231 Rtc(Wire)’ and now both the sketch from these articles are working.
    Very strange!

    Like

  7. John Quinn says:

    Greetings
    Disregard first message, must be getting tired, need to read message before posting.
    The version of rtc is the current version that is on ‘Github’. rtcObject(Wire) does not work either.
    I then ran the DS3231 Simple sketch this works, so I replaced ‘RtcDS3231 rtcObject’ with ‘RtcDS3231 RtcDS3231 Rtc(Wire)’ and now both the sketch from these articles are working.
    Very strange!

    Like

  8. John Quinn says:

    Greetings
    Disregard first and second, must be getting tired, need to read message before posting cutting and pasting was the problem.
    The version of rtc is the current version that is on ‘Github’. rtcObject(Wire) does not work either.
    I then ran the DS3231 Simple sketch this works, so I replaced ‘RtcDS3231 rtcObject’ with ‘RtcDS3231 RtcDS3231 Rtc(Wire)’ and now both the sketch from these articles are working.
    Very strange!

    Like

  9. John Quinn says:

    I give up!!!, used the code from DS3231 Simple and it works.

    Like

    • antepher says:

      Hi!

      I also made a mistake copying and pasting (sorry, it has been a busy week :)).
      You need to change
      RtcDS3231 rtcObject;
      To this:
      RtcDS3231 rtcObject(Wire);

      Doing this change, the following code compiled fine for me with version 2.0.0 of the Rtc library. Before this change I was also getting the error you reported. Please let me know if it works for you.

      #include // I2C library
      #include //RTC library

      RtcDS3231 rtcObject(Wire);

      void setup() {

      Serial.begin(115200);
      rtcObject.Begin();

      }

      void loop() {

      RtcTemperature temperature = rtcObject.GetTemperature(); //read temperature

      Serial.print(temperature.AsFloat()); //print temperature as a float
      Serial.println(” C”);

      delay(10000); //10 seconds delay

      }

      Like

      • antepher says:

        wow, WordPress deletes the greater than and lesser than signal in comments. I must have copied the correct code and it has removed it in my original comment. Now it also removed the includes in this comment.

        You need to change
        RtcDS3231 rtcObject;
        To this:
        RtcDS3231 #TwoWire@ rtcObject(Wire);
        with # equal to lesser than signal and @ equal to greater than signal.

        Sorry for the messy comment, I didn’t notice that wordpress does this. You can also check the correct declaration of the rtcObject in this more recent post (without problems in the signals 🙂 )
        https://techtutorialsx.wordpress.com/2017/02/12/esp8266-ds3231-alarms-once-per-second/

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s