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

33 thoughts on “ESP8266: Reading temperature with the DS3231 RTC”

Leave a Reply

Discover more from techtutorialsx

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

Continue reading