Fermion: SD3031 RTC Module Breakout Precision Wiki - DFRobot

[](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

Application

Specification

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

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

For any questions, advice or cool ideas to share, please visit the DFRobot Forum.

More Documents

DFshopping_car1.png Get Fermion: SD3031 RTC Module (Breakout) from DFRobot Store or DFRobot Distributor.

Turn to the Top