[](Product Link)
Introduction
This real-time clock(RTC) module employs the SD3031 chip with integrated crystal oscillator and temperature compensator, so it offers high-precision timing and stability. At 25℃, the accuracy remains at ±3.8ppm (±0.32832 seconds/day).
The SD3031 can be powered by button cell batteries, which enables accurate timing even when the main power to the device is interrupted. The RTC keeps track of seconds, minutes, hours, day of the week, date of the month, month and year, and it automatically adjusts the date at the end of the month, including leap year corrections. Besides, SD3031 features built-in 70Byte SRAM for low-power data storage.
Note: According to the latest air cargo regulations, special items such as batteries, magnets and liquids will be strictly audited for air transport, so the RTC module does not come with batteries. Please purchase them locally. The button cell model that goes with the module is CR1220.
Features
- Low power consumption, operating current of only 1.8µA when powered by button cell battery
- High accuracy, ±3.8ppm@25℃
- Integrated temperature compensator, small temperature drift
- Allow reading button cell voltage
- Built-in 70Byte SRAM
Application
- Event Reminder
- Countdown Devices
- MCU External Wake-up Source
- Clock & Alarm Output
- IoT Data Collection & Storage
Specification
- Supply Voltage: 3.3V
- I2C Address: 0×32
- SRAM: 70 Byte (0x2C-0x71)
- Timing Range: 2000 - 2099 year
- Operating Temperature: -10℃ to +70℃
- Timing Accuracy: ±3.8ppm @ 25℃
- Dimension: 22.5×21mm/0.89×0.83"
Board Overview
Num | Silkscreen | Description |
---|---|---|
1 | VCC | Power + |
2 | GND | Power - |
3 | SCL | I2C clock line |
4 | SDA | I2C data line |
5 | INT | Active-low interrupt or 1Hz square wave output |
6 | NC | NC |
7 | 32K | 32.768KHz pulse output |
Tutorial for Arduino
Requirements
- Hardware
- DFRduino UNO R3 (or similar) x 1
- Fermion: SD3031 RTC Module (Breakout) x 1
- DuPont Wires
- Software
- Arduino IDE
- Download and install the SD3031 library and sample codes (About how to install the library?)
Connection Diagram
Sample Code 1 - Set and Read Time
The temperature will update once every 60s when the module is powered by VCC and update once every 600s when powered by battery.
/*!
* @file getTime.ino
* @brief Run this routine, set the internal clock first, and then circularly get clock, temperature and voltage data
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.0
* @date 2022-07-27
* @url https://github.com/DFRobot/DFRobot_SD3031
*/
#include "DFRobot_SD3031.h"
DFRobot_SD3031 rtc;
void setup()
{
Serial.begin(115200);
/*Wait for the chip to be initialized completely, and then exit*/
while(rtc.begin() != 0){
Serial.println("Failed to init chip, please check if the chip connection is fine. ");
delay(1000);
}
rtc.setHourSystem(rtc.e24hours);//Set display format
rtc.setTime(2021,7,27,14,59,0);//Initialize time
// //Get internal temperature
// Serial.print(rtc.getTemperatureC());
// Serial.println(" C");
// //Get battery voltage
// Serial.print(rtc.getVoltage());
// Serial.println(" V");
}
void loop()
{
sTimeData_t sTime;
sTime = rtc.getRTCTime();
Serial.print(sTime.year, DEC);//year
Serial.print('/');
Serial.print(sTime.month, DEC);//month
Serial.print('/');
Serial.print(sTime.day, DEC);//day
Serial.print(" (");
Serial.print(sTime.week);//week
Serial.print(") ");
Serial.print(sTime.hour, DEC);//hour
Serial.print(':');
Serial.print(sTime.minute, DEC);//minute
Serial.print(':');
Serial.print(sTime.second, DEC);//second
Serial.println(' ');
/*Enable 12-hour time format*/
// Serial.print(rtc.getAMorPM());
// Serial.println();
delay(1000);
}
Result
Sample Code 2 - Interrupt
/*!
* @file interrupt.ino
* @brief Run this routine, set internal clock and interrupt trigger first, interrupt will be triggered when the set time is reached
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.0
* @date 2022-07-27
* @url https://github.com/DFRobot/DFRobot_SD3031
*/
#include "DFRobot_SD3031.h"
volatile int8_t alarmFlag = 0;
DFRobot_SD3031 rtc;
#define PIN 2
void setup()
{
Serial.begin(115200);
/*Wait for the chip to be initialized completely, and then exit*/
while(rtc.begin() != 0){
Serial.println("Failed to init chip, please check if the chip connection is fine. ");
delay(1000);
}
rtc.setHourSystem(rtc.e24hours);//Set display format
rtc.setTime(2022,7,27,23,59,55);//Set default time
//Countdown timer, schedule alarm and daily timed alarm can't be used at the same time
//rtc.countDown(3);//Countdown
//rtc.setAlarm(2022,7,28);//Set schedule alarm
rtc.setAlarm(rtc.eEveryDay,24,0,0);//Set daily timed alarm
#if defined(ESP32)||defined(ARDUINO_SAM_ZERO)
attachInterrupt(digitalPinToInterrupt(D7)/*Query the interrupt number of the D6 pin*/,interrupt,FALLING);
#elif defined(ESP8266)
attachInterrupt(digitalPinToInterrupt(D5)/*Query the interrupt number of the D6 pin*/,interrupt,FALLING);
#else
/* The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------
* | | DigitalPin | 2 | 3 | |
* | Uno, Nano, Mini, other 328-based |--------------------------------------------|
* | | Interrupt No | 0 | 1 | |
* |-------------------------------------------------------------------------------------|
* | | Pin | 2 | 3 | 21 | 20 | 19 | 18 |
* | Mega2560 |--------------------------------------------|
* | | Interrupt No | 0 | 1 | 2 | 3 | 4 | 5 |
* |-------------------------------------------------------------------------------------|
* | | Pin | 3 | 2 | 0 | 1 | 7 | |
* | Leonardo, other 32u4-based |--------------------------------------------|
* | | Interrupt No | 0 | 1 | 2 | 3 | 4 | |
* |--------------------------------------------------------------------------------------
*/
/* The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------------------------------------------------------------
* | micro:bit | DigitalPin |P0-P20 can be used as an external interrupt |
* | (When using as an external interrupt, |---------------------------------------------------------------------------------------------|
* |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
* |-------------------------------------------------------------------------------------------------------------------------------------------|
*/
attachInterrupt(digitalPinToInterrupt(2), interrupt, FALLING);
#endif
}
void loop()
{
sTimeData_t sTime;
sTime = rtc.getRTCTime();
Serial.print(sTime.year, DEC);//year
Serial.print('/');
Serial.print(sTime.month, DEC);//month
Serial.print('/');
Serial.print(sTime.day, DEC);//day
Serial.print(" (");
Serial.print(sTime.week);//week
Serial.print(") ");
Serial.print(sTime.hour, DEC);//hour
Serial.print(':');
Serial.print(sTime.minute, DEC);//minute
Serial.print(':');
Serial.print(sTime.second, DEC);//second
Serial.println(' ');
/*Enable 12-hour time format*/
// Serial.print(rtc.getAMorPM());
// Serial.println();
if(alarmFlag == 1){
rtc.clearAlarm();
alarmFlag = 0;
Serial.println("Alarm clock is triggered.");
delay(1000);
}else{
delay(1000);
}
}
void interrupt(void)
{
alarmFlag = 1;
}
Result
Sample Code 3 - Countdown
/*!
* @file countDown.ino
* @brief Run this routine to implement the countdown function
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.0
* @date 2022-07-27
* @url https://github.com/DFRobot/DFRobot_SD3031
*/
#include "DFRobot_SD3031.h"
DFRobot_SD3031 rtc;
volatile int8_t alarmFlag = 0;
void setup()
{
Serial.begin(115200);
/*Wait for the chip to be initialized completely, and then exit*/
while(rtc.begin() != 0){
Serial.println("Failed to init chip, please check if the chip connection is fine. ");
delay(1000);
}
#if defined(ESP32)||defined(ARDUINO_SAM_ZERO)
attachInterrupt(digitalPinToInterrupt(D7)/*Query the interrupt number of the D6 pin*/,interrupt,FALLING);
#elif defined(ESP8266)
attachInterrupt(digitalPinToInterrupt(D5)/*Query the interrupt number of the D6 pin*/,interrupt,FALLING);
#else
/* The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------
* | | DigitalPin | 2 | 3 | |
* | Uno, Nano, Mini, other 328-based |--------------------------------------------|
* | | Interrupt No | 0 | 1 | |
* |-------------------------------------------------------------------------------------|
* | | Pin | 2 | 3 | 21 | 20 | 19 | 18 |
* | Mega2560 |--------------------------------------------|
* | | Interrupt No | 0 | 1 | 2 | 3 | 4 | 5 |
* |-------------------------------------------------------------------------------------|
* | | Pin | 3 | 2 | 0 | 1 | 7 | |
* | Leonardo, other 32u4-based |--------------------------------------------|
* | | Interrupt No | 0 | 1 | 2 | 3 | 4 | |
* |--------------------------------------------------------------------------------------
*/
/* The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------------------------------------------------------------
* | micro:bit | DigitalPin |P0-P20 can be used as an external interrupt |
* | (When using as an external interrupt, |---------------------------------------------------------------------------------------------|
* |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
* |-------------------------------------------------------------------------------------------------------------------------------------------|
*/
attachInterrupt(digitalPinToInterrupt(2), interrupt, CHANGE);
#endif
rtc.countDown(10);
Serial.println("start");
}
void loop()
{
if(alarmFlag == 1){
rtc.countDown(10);
alarmFlag = 0;
Serial.println("Alarm clock is triggered.");
}
}
void interrupt(void)
{
alarmFlag = 1;
}
Result
Sample Code 4 - Read & Write SRAM
/*!
* @file getTimeAndTemperature.ino
* @brief Run this routine to read and write RAM data in the RTC module
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.0
* @date 2022-07-27
* @url https://github.com/DFRobot/DFRobot_SD3031
*/
#include "DFRobot_SD3031.h"
DFRobot_SD3031 rtc;
void setup()
{
uint8_t data= 0;
Serial.begin(115200);
/*Wait for the chip to be initialized completely, and then exit*/
while(rtc.begin() != 0){
Serial.println("Failed to init chip, please check if the chip connection is fine. ");
delay(1000);
}
rtc.writeSRAM(0x2D,2);//Address Range 0x2c~0x71
delay(1000);
data = rtc.readSRAM(0x2D);
Serial.print("data:");
Serial.println(data);
delay(100);
rtc.clearSRAM(0x2D);
delay(100);
data = rtc.readSRAM(0x2D);
Serial.print("data:");
Serial.println(data);
}
void loop()
{
delay(1000);
}
Result
Sample Code 5 - 32K Square Wave Output
/*!
* @file control32k.ino
* @brief Run this routine to control pin 32K to output square wave
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.0
* @date 2022-07-27
* @url https://github.com/DFRobot/DFRobot_SD3031
*/
#include "DFRobot_SD3031.h"
DFRobot_SD3031 rtc;
void setup()
{
uint8_t data= 0;
Serial.begin(115200);
/*Wait for the chip to be initialized completely, and then exit*/
while(rtc.begin() != 0){
Serial.println("Failed to init chip, please check if the chip connection is fine. ");
delay(1000);
}
rtc.enable32k();
delay(1000);
rtc.disable32k();
}
void loop()
{
delay(1000);
}
Main API Functions
/**
* @struct sTimeData_t
* @brief Structure for storing time data
*/
typedef struct{
uint16_t year;
uint8_t month;
uint8_t day;
String week;
uint8_t hour;
uint8_t minute;
uint8_t second;
}sTimeData_t;
/**
* @fn getRTCTime
* @brief Get information of year in RTC module
* @return Return the obtained year
*/
sTimeData_t getRTCTime(void);
/**
* @fn getAMorPM
* @brief output AM or PM of time
* @return AM or PM, 24 hours mode return empty string
*/
String getAMorPM();
/**
* @brief Set clock as 24-hour or 12-hour format
* @param mode Clock calculation method
*/
void setHourSystem(eHours_t mode){ _mode = mode; };
/**
* @fn setTime
* @brief Set time into RTC and take effect immediately
* @param year 2000~2099
* @param month 1~12
* @param day 1~31
* @param week 0~6
* @param hour 0~23
* @param minute 0~59
* @param second 0~59
* @return None
*/
void setTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second);
/**
* @fn setAlarm
* @brief Set the data for triggering alarm
* @param year 2000~2099
* @param month 1~12
* @param day 1~31
* @return None
*/
void setAlarm(uint16_t year, uint8_t month, uint8_t day);
/**
* @enum eWeek_t
* @brief The day of week enumeration
*/
typedef enum{
eSunday = 0x01,
eMonday = 0x02,
eTuesday = 0x04,
eWednesday = 0x08,
eThursday = 0x10,
eFriday = 0x20,
eSaturday = 0x40,
eEveryDay = 0x7f,
eWorkday = 0x3e,
}eWeek_t;
/**
* @fn setAlarm
* @brief Set the Alarmnumber object
* @param week
* @n ---------------------------------------------------------------------------------------------------------
* @n | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
* @n ---------------------------------------------------------------------------------------------------------
* @n | | Saturday | Friday | Thursday | Wednesday | Tuesday | Monday | Sunday |
* @n ---------------------------------------------------------------------------------------------------------
* @param hour 0~23
* @param minute 0~59
* @param second 0~59
*/
void setAlarm(uint8_t week,uint8_t hour, uint8_t minute, uint8_t second);
FAQ
Q:Encountering I2C address conflicts? A: For a comprehensive guide on identifying and resolving I2C address conflicts in embedded systems, check out this detailed article: How to Resolve I2C Address Conflicts. It covers practical hardware and software solutions to ensure smooth communication in your IoT devices.
For any questions, advice or cool ideas to share, please visit the DFRobot Forum.