What is RTC?
Real-time clocks (RTCs) are integrated circuits that keep track of the current date and time even when there is a power outage. There are several types of RTCs available in the market, but among the most popular are the DS1302, DS1307, and DS3231. In this article we will learn how to read RTC Arduino ESP DS1307 and DS3231)
Dallas Semiconductor (now a part of Maxim Integrated) is the original manufacturer of the DS1302, DS1307, and DS3231 real-time clock (RTC) integrated circuits. These RTCs are widely used in various electronic projects and are available from many electronic component distributors.
Comparison Table of DS1302, DS1307 and DS3231
here’s a more in-depth comparison table between the DS1302, DS1307, and DS3231 RTCs:
Feature DS1302 DS1307 DS3231 Pin Configuration Interface Serial I2C I2C Oscillator 32.768kHz 32.768kHz Temperature-compensated crystal oscillator (TCXO) Accuracy ±2.5% at 25°C ±2.0% at 25°C ±2ppm Operating Voltage 2.0V to 5.5V 2.0V to 5.5V 2.3V to 5.5V Operating Temperature Range -40°C to +85°C -55°C to +125°C -40°C to +85°C Battery-backed SRAM No 56 bytes No Pin Count 8 8 8 Date/Time Registers 8 7 8 Trickle-charge feature Yes No No Cost Low Medium High
Note: The above table is a general comparison and the actual specifications may vary depending on the manufacturer.
As can be seen from the table, the DS3231 offers the highest accuracy. It also has a wider operating voltage range compared to the DS1302 and DS1307. On the other hand, the DS1307 offers battery-backed SRAM, which can be useful for storing data during power outages. The DS1302 has the advantage of being low-cost and having a trickle-charge feature, which allows it to be powered by a small battery even when the main power supply is off.
How it works?
An RTC chip will continue to count time as long as it is supplied with a voltage source. 2 voltage sources can turn on this chip, VCC and Vbat. VCC is the voltage that comes from the main circuit, while Vbat is the voltage that comes from the backup battery (3.3V)
When the chip is given a VCC voltage, the chip will automatically select the VCC voltage to run the system, but when the VCC is disconnected or goes out, the chip will automatically switch to the backup battery voltage. The backup battery is usually a flat battery such as the CR2032 type which has a voltage of 3V.
As long as electrical voltage is available, this RTC chip will continue to output time data sent via the I2C protocol pins (SDA and SCL). A microcontroller such as the Arduino Uno board, will retrieve this data via I2C communication as well.
RTC Module
When we use an RTC chip such as DS1302, DS1307, or DS3231, we need several other separate components such as a crystal, backup battery, resistors, and diodes.
Things like that will make things a bit troublesome if we want to develop fast hardware. Therefore, we can use the RTC module.
In the RTC module, all the components mentioned above are soldered on one PCB board, so using it is much easier and faster, you can search on Google for a variant RTC Module:
RTC Library for Arduino
To make it easier to read data from the RTC using the Arduino platform, we need a library. We will use the RTClib library by Adafruit.
For installation instructions for this library, I have created a separate article which you can read here.
Wiring
a. DS1307 to Arduino Uno
b. DS3231 to Arduino Uno
c. DS3231 NodeMCU ESP8266
The Code
Read RTC Data
Now, we will try to read data from RTC. Data includes day, date, month, year, hour, minute and second.
#include "RTClib.h"
RTC_DS1307 rtc;
// RTC_DS3231 rtc;
char daysOfTheWeek[7][7] = {"Ahad", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};
char Month [13][10] = {" ", "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"};
void setup () {
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("No RTC Detected!");
Serial.flush();
abort();
}
if (! rtc.isrunning()) {
Serial.println("RTC not Running!");
}
}
void loop () {
DateTime now = rtc.now();
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(", ");
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(Month[now.month()]);
Serial.print(' ');
Serial.print(now.year(), DEC);
Serial.print(", ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
delay(1000);
}
The Result
After the program is uploaded, open the Arduino IDE Monitor series and you will see data that appears as follows:
Adafruit I2CDevice h No such file or directory
If you get this error, you must install the BusIO library by Adafruit. For step install, please read Adafruit I2CDevice h No such file or directory.
If The time is not Correct, let’s Set the Time!
Manual Set
If you want the time on the RTC to be the same on the computer, copy this command and paste it into the setup() function:
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
If you want the RTC time to be set manually, use the following command in setup():
// Example January 21, 2014 at 03.00:
rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
Using Serial Monitor
Now we will create a program with which we can set the RTC manually.
Pay attention to the command rtc.adjust(DateTime(year, month, date, hour, minute, second));, this will make the program will set the time at the same time.
For example, if we only want to change the date or time, how do we do that?
Here I include the complete program. This program will display RTC data on the Serial Monitor
To change the data, send the following characters to the serial monitor:
- TG to change the Date
- BL to change the Moon
- TH for changing the Year
- JM to change Hours
- MT to change Minutes
- DT to change Seconds
/*
www.chippiko.com
This program will display RTC data on Serial Monitor
To change the data, send the following characters to the serial monitor:
- TG to change Date
- BL to change the Moon
- TH for changing Year
- JM to change Hours
- MT to change Minutes
- DT to change Seconds
*/
#include "RTClib.h"
RTC_DS1307 rtc;
// RTC_DS3231 rtc;
char daysOfTheWeek[7][10] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char Month [13][10] = {" ", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
String read_string = " ";
int read_int = 0;
void setup () {
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("RTC Not Found");
Serial.flush();
abort();
}
if (rtc.lostPower()) {
Serial.println("RTC is losing power, let's set the time!");
}
}
void loop () {
readRTC();
setRTC();
delay(1000);
}
void readRTC()
{
DateTime now = rtc.now();
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(", ");
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(Month[now.month()]);
Serial.print(' ');
Serial.print(now.year(), DEC);
Serial.print(", ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println('\n');
}
void setRTC() {
DateTime now = rtc.now();
while (Serial.available() > 0) {
read_string = Serial.readStringUntil('\n');
read_string.trim();
delay(100);
// The day cannot be changed because it will change itself according to the date
if (read_string == "TG") {
Serial.print("Insert the date: ");
//Wait a moment for new data to be sent
while (!Serial.available()) {}
read_int = Serial.parseInt();
Serial.println(read_int);
rtc.adjust(DateTime(now.year(), now.month(), read_int, now.hour(), now.minute(), now.second()));
}
if (read_string == "BL") {
Serial.print("Insert month: ");
//Wait a moment for new data to be sent
while (!Serial.available()) {}
read_int = Serial.parseInt();
Serial.println(read_int);
rtc.adjust(DateTime(now.year(), read_int, now.day(), now.hour(), now.minute(), now.second()));
}
if (read_string == "TH") {
Serial.print("Insert Year: ");
//Wait a moment for new data to be sent
while (!Serial.available()) {}
read_int = Serial.parseInt();
Serial.println(read_int);
rtc.adjust(DateTime(read_int, now.month(), now.day(), now.hour(), now.minute(), now.second()));
}
if (read_string == "JM") {
Serial.print("Insert hour: ");
//Wait a moment for new data to be sent
while (!Serial.available()) {}
read_int = Serial.parseInt();
Serial.println(read_int);
rtc.adjust(DateTime(now.year(), now.month(), now.day(), read_int, now.minute(), now.second()));
}
//Jika menit
if (read_string == "MT") {
Serial.print("Insert minute: ");
//Wait a moment for new data to be sent
while (!Serial.available()) {}
read_int = Serial.parseInt();
Serial.println(read_int);
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), read_int, now.second()));
}
if (read_string == "DT") {
Serial.print("Insert second: ");
//Wait a moment for new data to be sent
while (!Serial.available()) {}
read_int = Serial.parseInt();
Serial.println(read_int);
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), read_int));
}
}
}
Displays RTC in AM/PM Format
Now, let’s learn how to display the time format in 12 hours i.e. AM and PM. By default, the program above will display the time in a 24-hour format such as:
- 9.14
- 14.20
- 18.30
With 12 hour format, the time displayed is:
- 9.14 AM
- 2.20 PM
- 6.30 PM
The basic commands are:
(h > 12) ? h – 12 : ((h == 0) ? 12 : h), DEC
and
(h < 12) ? ” AM” : ” PM”
Here is the code:
#include "RTClib.h"
RTC_DS1307 rtc;
// RTC_DS3231 rtc;
char daysOfTheWeek[7][7] = {"Ahad", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};
char Month [13][10] = {" ", "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"};
int h = 0;
void setup () {
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("Tidak ada RTC");
Serial.flush();
abort();
}
}
void loop () {
DateTime now = rtc.now();
h = now.hour();
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); // Menampilkan Hari
Serial.print(", ");
Serial.print(now.day(), DEC); // Menampilkan tanggga
Serial.print(' ');
Serial.print(Month[now.month()]); // Menampilkan bulan
Serial.print(' ');
Serial.print(now.year(), DEC); // Menampilkan tahun
Serial.print(", ");
Serial.print((h > 12) ? h - 12 : ((h == 0) ? 12 : h), DEC); // Menampilkan jam
Serial.print(':');
Serial.print(now.minute(), DEC); // Menampilkan menit
Serial.print(':');
Serial.print(now.second(), DEC); // Menampilkan detik
Serial.print((h < 12) ? " AM" : " PM");
Serial.println('n');
delay(1000);
}
The results displayed are as follows:
Now, open the serial monitor on Arduino IDE. Please follow the instructions. Done. I hope this Build an RTC Arduino ESP (DS1307 & DS3231) article is useful.