In this tutorial, we will learn to interface DS3231 RTC Module using ESP32 and ESP-IDF. This guide will include a brief description of the RTC module, connection with ESP32 board and then setting up a project in VS Code with ESP-IDF extension to acquire the current date/time along with the internal chip temperature and display it on the console.
Before we move ahead, make sure you have the latest version of VS Code installed on your system with the ESP-IDF extension configured.
DS3231 Precision RTC Module Introduction
The DS3231 RTC module is widely used to keep track of the current date and time. It is used in electronics projects for time keeping, data logging, building clocks, timers etc. This module runs on the DS3231S RTC chip and also contains the AT24C3 EEPRROM for accurate time keeping. The module consists of an integrated temperature compensated crystal oscillator and crystal resonator, whereby making it an extremely accurate RTC. Moreover, the accuracy of the time is maintained through a long time due to the presence of the crystal resonator.
On the backside of the RTC module, it possesses a 20mm 3V lithium coin cell holder which fits a CR2032 battery. This battery is extremely vital in tracking the time and making sure it stays correct in case the main power is cut off. Therefore, the CR2032 cell acts as a backup battery source incase the main power is lost.
The diagram below shows the front and the backside of the DS3231 RTC module. Note that the front side contains the DS3231 RTC chip and the 24C32 EEPROM whereas the backside consists of the CR2032 battery holder and the coin cell respectively.
DS3231 RTC Module Pinout
The diagram below shows the pinout of the DS3231 RTC module.
As you can see in the diagram above, the DS3231 module consists of a total of ten pins but we only require the I2C communication pins (SCL and SDA) and the power supply pins (VCC and GND) to access the current time using a single module. The I2C pins and power pins on the other side of the module are given to connect to another module (daisy chain).
33K | This pin outputs the compensated temperature and the accurate reference clock. |
SQW | This pin outputs square waves of different frequencies for example 1Hz, 4kHz, 8kHz, or 32kHz. |
SCL | This is the serial clock pin which will produce the clock signal |
SDA | This is the serial data pin which is used for sending and receiving data |
VCC | This is the power supply pin which is connected with Vin (5V) or 3.3V of ESP32. |
GND | This is the ground pin. |
Interfacing DS3231 RTC Module with ESP32
We will need the following components to connect our ESP32 board with the DS3231 Module.
- ESP32 board
- DS3231 Module
- Connecting Wires
- Breadboard
The connection of DS3231 Module with the ESP32 board is straightforward as it just involves the connection of the 4 pins (GND, VCC, SDA, and SCL) with ESP32. We have to connect the VCC terminal with Vin pin, ground with the ground (common ground), SCL of the sensor with SCL of ESP32 board, and SDA of the sensor with the SDA pin of the ESP32 board. We will use the default I2C pins of ESP32 board to connect with the sensor module.
In ESP32, the default I2C pin for SDA is GPIO21 and for SCL is GPIO22.
The connections between the devices are specified in the table below:
DS3231 Module | ESP32 |
---|---|
GND | GND |
VCC | 3.3V |
SDA | GPIO21(I2C SDA) |
SCL | GPIO22 (I2C SCL) |
Real Time Clock with ESP32 using DS3231 Module and ESP-IDF
We will build and create a project in VS Code with ESP-IDF extension. The code will output the current date/time and the internal chip temperature in the ESP-IDF terminal using the I2C device library, esp_idf_lib_helpers and ds3231.h. We will use ds3231 driver written by UncleRus.
Create Example Project
Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.
Specify the project name and directory. We have named our project ‘DS3231_ESP32.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.
In the Extension, select ESP-IDF option:
We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’
You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’
This opens the project that we created inside the EXPLORER tab. There are several folders inside our project folder. This is the same for every project which you will create through ESP-IDF Explorer.
- First, let’s add the necessary header files for the libraries required for this project. Create a new folder called ‘components’ and add the following three sub-folders under it:
- esp_idf_lib_helpers
- i2cdev
- ds3231
Add ds3231, esp_idf_lib_helpers, and i2cdev folders in ‘components’ folder by copying from this link as listed below:
ESP32 DS3231 Display Current Time and Date Code
Now head over to the main.c file. The main folder contains the source code meaning the main.c file will be found here. Go to main > main.c and open it. Copy the code given below in that file and save it.
This is an example sketch for the driver ds3231. It continuously prints the current date and time, along with the internal chip temperature in the ESP-IDF terminal.
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <ds3231.h>
#include <string.h>
void ds3231_test(void *pvParameters)
{
i2c_dev_t dev;
memset(&dev, 0, sizeof(i2c_dev_t));
ESP_ERROR_CHECK(ds3231_init_desc(&dev, 0, 21, 22));
struct tm time = {
.tm_year = 122, // (2022 - 1900)
.tm_mon = 11, // 0-based
.tm_mday = 15,
.tm_hour = 0,
.tm_min = 50,
.tm_sec = 10
};
ESP_ERROR_CHECK(ds3231_set_time(&dev, &time));
while (1)
{
float temp;
vTaskDelay(pdMS_TO_TICKS(250));
if (ds3231_get_temp_float(&dev, &temp) != ESP_OK)
{
printf("Could not get temperature\n");
continue;
}
if (ds3231_get_time(&dev, &time) != ESP_OK)
{
printf("Could not get time\n");
continue;
}
/* float is used in printf(). you need non-default configuration in
* sdkconfig for ESP8266, which is enabled by default for this
* example. see sdkconfig.defaults.esp8266
*/
printf("%04d-%02d-%02d %02d:%02d:%02d, %.2f deg Cel\n", time.tm_year + 1900 /*Add 1900 for better readability*/, time.tm_mon + 1,
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec, temp);
}
}
void app_main()
{
ESP_ERROR_CHECK(i2cdev_init());
xTaskCreate(ds3231_test, "ds3231_test", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL);
}
How the Code Works?
Firstly, we will start by including the necessary libraries for this project. This includes the ds3231 library to access the APIs for configuring and obtaining the current date/time and freertos libraries to create the task.
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <ds3231.h>
#include <string.h>
ds3231_test()
Inside the ds3231_test() function, we first create an instance of i2c_dev_t struct which is used to configure and initialize the RTC module. After that we initialize all members of this struct to zero with memset.
i2c_dev_t dev;
memset(&dev, 0, sizeof(i2c_dev_t));
/**
* I2C device descriptor
*/
typedef struct
{
i2c_port_t port; //!< I2C port number
i2c_config_t cfg; //!< I2C driver configuration
uint8_t addr; //!< Unshifted address
SemaphoreHandle_t mutex; //!< Device mutex
uint32_t timeout_ticks; /*!< HW I2C bus timeout (stretch time), in ticks. 80MHz APB clock
ticks for ESP-IDF, CPU ticks for ESP8266.
When this value is 0, I2CDEV_MAX_STRETCH_TIME will be used */
} i2c_dev_t;
Next, the ds3231_init_desc() function initializes the ds3231 device descriptor by passing dev struct, I2C port, ESP32 SDA pin and ESP32 SCL pin respectively.
ESP_ERROR_CHECK(ds3231_init_desc(&dev, 0, 21, 22));
Next we define the parameters of the tm struct which we define as ‘time.’ Inside it we specify the current year, month, date, hour, minute and second. After that, we call ds3231_set_time() to initialize the date and time as defined in the time structure. This function basically sets the time to RTC.
struct tm time = {
.tm_year = 122, // (2022 - 1900)
.tm_mon = 11, // 0-based
.tm_mday = 15,
.tm_hour = 0,
.tm_min = 50,
.tm_sec = 10
};
ESP_ERROR_CHECK(ds3231_set_time(&dev, &time));
Inside the while loop, we access the current date and time using ds3231_get_time() function and the internal chip temperature using ds3231_get_temp_float() function. After every 0.25 second, we print the internal chip temperature and the current date and time on the ESP-IDF terminal by accessing each member of the time structure.
while (1)
{
float temp;
vTaskDelay(pdMS_TO_TICKS(250));
if (ds3231_get_temp_float(&dev, &temp) != ESP_OK)
{
printf("Could not get temperature\n");
continue;
}
if (ds3231_get_time(&dev, &time) != ESP_OK)
{
printf("Could not get time\n");
continue;
}
printf("%04d-%02d-%02d %02d:%02d:%02d, %.2f deg Cel\n", time.tm_year + 1900 /*Add 1900 for better readability*/, time.tm_mon + 1,
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec, temp);
}
app_main()
Inside the app_main() function, we will first initialize the i2c device by calling i2cdev_init(). Then we will create the ds3231 task using the xTaskCreate() function.
void app_main()
{
ESP_ERROR_CHECK(i2cdev_init());
xTaskCreate(ds3231_test, "ds3231_test", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL);
}
Compiling the Sketch
To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.
idf.py -p COMX flash monitor
After the code is successfully flashed, you can view the current date and time along with the internal chip temperature on the console.
You may also like to read:
- ESP32 ESP-IDF RTC Real Time Clock with DS1307
- ESP32 ESP-IDF MQTT Publish BME680 Sensor Readings
- ESP32 ESP-IDF with MAX7219 Dot Matrix Display Module
- Interface OLED with ESP32 using ESP-IDF
- I2C LCD with ESP32 using ESP-IDF
We are a team of experienced Embedded Software Developers with skills in developing Embedded Linux, RTOS, and IoT products from scratch to deployment with a demonstrated history of working in the embedded software industry. Contact us for your projects: admin@esp32tutorials.com
https://esp32tutorials.com/esp32-esp-idf-ds3231-rtc-real-time-clock/
for this documentation I think you need to update.
Because esp idf latest version not supporting this code.