In this tutorial, we will learn about Real Time Clock (RTC) and its interfacing with the ESP32 and OLED display.
We will use DS3231 RTC module to keep track of the correct time and display it on SPI OLED by using ESP32 as our microcontroller. ESP32 is more than a microcontroller. It has Wi-Fi and Bluetooth chip inside it and 39 GPIO pins. It supports all communication protocols like SPI, I2C, UART, etc. If you are new to ESP32 then first go through our Getting started with ESP32 tutorial.
What is RTC??
DS3231 is a RTC (Real Time Clock) module. It is used to maintain the date and time for most of the Electronics projects. This module has its own coin cell power supply using which it maintains the date and time even when the main power is removed or the MCU has gone through a hard reset. So once we set the date and time in this module it will keep track of it always. There are several types of RTC ICs available like DS1307, DS3231 etc.
We have previously used DS3231 RTC with Arduino in below projects:
Note: When using this module for the first time you have to set the date and time. You can also use RTC IC DS1307, we have previously used DS1307 with Arduino.
Getting to know about OLED Displays:
The term OLED stands for “Organic Light emitting diode” it uses the same technology that is used in most of our televisions but has fewer pixels compared to them. It is real fun to have these cool looking display modules since it will make our projects look cool. We have covered a full Article on OLED displays and its types here.
We are using a Monochrome 7-pin SSD1306 0.96” OLED display. The reason for choosing this display is that it can work on three different communications Protocols such as the SPI 3 Wire mode, SPI four wire mode and IIC mode. This tutorial will cover how to use the module in SPI 4-wire mode as it is the fastest mode of communication and the default one.
The pins and its functions are explained in the table below.
Pin Number |
Pin Name |
Other Names |
Usage |
1 |
Gnd |
Ground |
Ground pin of the module |
2 |
Vdd |
Vcc, 5V |
Power pin (3-5V tolerable) |
3 |
SCK |
D0,SCL,CLK |
Acts as the clock pin. Used for both I2C and SPI |
4 |
SDA |
D1,MOSI |
Data pin of the module. Used for both IIC and SPI |
5 |
RES |
RST,RESET |
Resets the module (useful during SPI) |
6 |
DC |
A0 |
Data Command pin. Used for SPI protocol |
7 |
CS |
Chip Select |
Useful when more than one module is used under SPI protocol |
In this tutorial we will simply operate the module in 4-Wire SPI mode, we will leave the rest for some other tutorial.
Arduino community has already given us a lot of Libraries which can be directly used to make this a lot simpler. I tried out a few libraries and found that the Adafruit_SSD1306 Library was very easy to use and had a handful of graphical options hence we will use the same in this tutorial. But, if your project has a memory/speed constraint try using the U8g Library as it works faster and occupies less program memory.
We have also interfaced OLED with Raspberry pi and with Arduino.
Material Required:
- ESP32
- DS3231 RTC module
- 7 pin 128×64 OLED display Module (SSD1306)
- Male-female wires
- Breadboard
Circuit Diagram:
Circuit diagram to connect RTC3231 to ESP board is given below:
RTC DS3231 IC uses I2C mode of communication. It has SCL, SDA, Vcc and GND pins coming out of it. Connection of RTC module with ESP32 is given below:
- SCL of RTC -> SCL of ESP32 i.e. Pin D22
- SDA of RTC -> SDA of ESP32 i.e. Pin D21
- GND of RTC -> GND of ESP32
- Vcc of RTC -> Vcc of ESP32
Here, we are using SPI mode to connect our 128×64 OLED display Module (SSD1306) to ESP32. So, it will use 7 pins. Connections with ESP32 are given as:
- CS(Chip select) pin of OLED -> PIN D5 of ESP32
- DC pin of OLED -> PIN D4 of ESP32
- RES pin of OLED -> PIN D2 of ESP32
- SDA pin of OLED -> PIN D23 i.e. MOSI of ESP32
- SCK pin of OLED -> PIN D18 i.e. SCK of ESP32
- Vdd of OLED -> Vcc of ESP32
- GND of OLED -> GND of ESP32
You need board files for your ESP32. Check in board manager drop down menu of Arduino IDE for ESP32 dev kit. If it is not there follow the steps given in the link below:
https://circuitdigest.com/microcontroller-projects/getting-started-with-esp32-with-arduino-ide
You can also use ESP12 for this project, learn here to use ESP12.
Code Explanation:
Complete code for ESP32 is given at the end of the article. Here we are explaining few important parts of code.
We need several libraries to use in our code which can be downloaded from the below links:
1. Adafruit_SSD1306 : https://github.com/adafruit/Adafruit_SSD1306
2. SPI : https://github.com/PaulStoffregen/SPI
3. Adafruit_GFX : https://github.com/adafruit/Adafruit-GFX-Library
4. RTClib : https://github.com/adafruit/RTClib
So we have included all the libraries
#include <SPI.h> // for OLED display #include <Wire.h> // for I2C with RTC module #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // for display graphics #include "RTClib.h" //to show time
Then define all the pins of OLED. You don't need to define pins for RTC module because these pins are already defined in WIRE library.
#define OLED_MOSI 23 #define OLED_CLK 18 #define OLED_DC 4 #define OLED_CS 5 #define OLED_RESET 2 Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
In setup function, we will call a function rtc.adjust(DateTime(__DATE__, __TIME__)) which will set the time according to our PC time.
void setup() { Serial.begin(9600); if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); } rtc.adjust(DateTime(__DATE__, __TIME__));
After that we call display functions to show on OLED.
display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.setTextColor(WHITE); //display.startscrollright(0x00, 0x0F); // You can uncomment this line to scroll your text on oled display.setTextSize(2); display.setCursor(0,5); display.print(" Clock "); //This will Display Clock on OLED for 3 seconds display.display(); delay(3000); }
Then finally in loop function, we will store our time in DateTime now pre-defined variable and display the time using display functions like setTextSize, setCursor, etc. Set these according to your need and use display.println function to show on OLED.
void loop() { DateTime now = rtc.now(); display.clearDisplay(); display.setTextSize(2); display.setCursor(75,0); display.println(now.second(), DEC);
So this is how you can display time on OLED using ESP32 and as you know ESP is known for its IoT capabilities, so you can use this to publish the time on internet. In next article we will show you to display Internet Time on ESP without using any RTC Module.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
#define OLED_MOSI 23
#define OLED_CLK 18
#define OLED_DC 4
#define OLED_CS 5
#define OLED_RESET 2
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
void setup()
{
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
rtc.adjust(DateTime(__DATE__, __TIME__));
display.begin(SSD1306_SWITCHCAPVCC);
display.clearDisplay();
display.setTextColor(WHITE);
//display.startscrollright(0x00, 0x0F);
display.setTextSize(2);
display.setCursor(0,5);
display.print(" Clock ");
display.display();
delay(3000);
}
void loop()
{
DateTime now = rtc.now();
display.clearDisplay();
display.setTextSize(2);
display.setCursor(75,0);
display.println(now.second(), DEC);
display.setTextSize(2);
display.setCursor(25,0);
display.println(":");
display.setTextSize(2);
display.setCursor(65,0);
display.println(":");
display.setTextSize(2);
display.setCursor(40,0);
display.println(now.minute(), DEC);
display.setTextSize(2);
display.setCursor(0,0);
display.println(now.hour(), DEC);
display.setTextSize(1);
display.setCursor(0,15);
display.println(now.day(), DEC);
display.print(daysOfTheWeek[now.dayOfTheWeek()]);
display.setTextSize(1);
display.setCursor(25,15);
display.println("-");
display.setTextSize(1);
display.setCursor(40,15);
display.println(now.month(), DEC);
display.setTextSize(1);
display.setCursor(55,15);
display.println("-");
display.setTextSize(1);
display.setCursor(70,15);
display.println(now.year(), DEC);
display.display();
}
Comments
ESP32 DS3231 RTC
First a remark related to Mr. Duaz comment dated may-27. 2019:
comment =
I can understand the use of an external RTC, as I noticed that the ESP32-RTC is not that accurate. (I believe this is already generally known.)
I wrote a little sketch, writing 3 constanly same data-points to MySQL at 30 seconds intervals. I let it ran for 24 hrs and found that the actual interval is on average 32.5 sec. (Ranging from 31 to 36 sec.) (Part of this might be due to work the Synology-NAS was doing.)
Regards,
Leo
ESP32 DS3231 RTC Alarms
Hello,
This is actually not a comment, but more a question.
First of all: I am a noob. I can do quite lot, but some things are beyond me.
I recently started working with ESP32.
I want to replace my Arduino Mega with an ESP32, doing the same work the Arduino is doing now.
The Arduino measures my Elec. Power and Gas consumption and posts this in MySQL every 5th minute. Data sent is: avg-W, hourly Wh, daily kWh, avg-dm3, hourly dm3 and daily m3. Measurements are reset at midnight. For this purpose I have a DS3231 attached to the Arduino.
I can get the ESP32 working with DS3231, time/date-wise. But I can not set 'alarms' for resetting. Because I have now clue how to set alarms, in combination with ESP32. (I can with Arduino.)
When I use the Arduino-script (or actually arduino libraries), I get all sort of fault-reports. It seems like that the libraries I use are not compatible with ESP32.(And I have used/downloaded a lot different ones.)
The only DS3231 librarie which seems to work is RTClib.h (made by JeeLab?), but I have no clue how to set the alartms. I have Googled a lot, but no succes.
Can one of you experts help or point me to the right librarie?
With best regards,
Leo
Fritzing picture shows....
Fritzing picture shows....
SCL to D21 and SDA to D22
Just below that, the text says....
SCL of RTC -> SCL of ESP32 i.e. Pin D22
SDA of RTC -> SDA of ESP32 i.e. Pin D21
The text is correct. The Fritzing image is wrong.
the esp32 has an inbuilt RTC, so why would you want to use an external one?