DS3231 arduino RTC Tutorial Using Adafruit Library

Posted on

DS3231 arduino RTC

DS3231 arduino RTC – This article is an update of the article How to Use the Arduino DS3231 RTC Using the RinkyDink Library.

RinkyDink’s DS3231 library is a good one. However, there is one problem when I use it for advanced, like the day of the week cannot be synchronized.

So I found a better library made by Adafruit which is RTClib. This RTClib library supports the DS3231, DS1307 and PCF8523 RTC chips.

For boards, this RTClib library supports:

  • ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V,  Metro 328,  Metro Mini
  • ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
  • ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
  • ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
  • ESP8266 : Adafruit Huzzah
  • ATmega2560 @ 16MHz : Arduino Mega
  • ATSAM3X8E : Arduino Due
  • ATSAM21D : Arduino Zero, M0 Pro
  • ATtiny85 @ 16MHz : Adafruit Trinket 5V
  • ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V

Based on the datasheet, this RTC DS3231 made by MAXIM INTEGRATED has the following features: 

  • Real time to count seconds, minutes, hours, date, month and year valid up to 2100.
  • Accuracy ±2ppm from 0°C to +40°C
  • Accuracy ±3.5ppm from -40°C to +85°C
  • Digital temperature sensor output accuracy ±3°C
  • I2C Communication (400kHz)
  • Battery backup voltage 3.3V

Download Library DS3231

To operate this RTC using Arduino, please download the RTClib library at the following link:

Download Libary DS323 RTClib

If you have, include RTClib Library that you have downloaded to the Arduino IDE by doing this:

  • Open Arduino IDE
  • Click Sketch > Include Library Add .ZIP Library
  • Look for the RTClib-master.zip Library that you have downloaded
  • Click OK

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.

DS3231 Arduino Wiring

For the circuit is not too difficult, connect 5V Arduino to VCC RTC, GND to GND, A4 to SDA and A5 to SCL. RTC DS3231 Arduino relationship as shown in the picture below:

DS3231 arduino RTC Tutorial Using Adafruit Library

Code Program To Get Time From RTC

Now, we will try to read data from RTC. The data include day, date, month, year, hour, minute and second.

#include "RTClib.h"

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"};

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!");
  }

  // the following lines set the RTC to the date & time of the computer when this sketch was compiled
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  
  // If you want to set the RTC time manually, use the line rtc.adjust
  // Example January 21, 2014 at 03.00:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
  DateTime now = rtc.now();

  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); // Show the Day
  Serial.print(", ");
  Serial.print(now.day(), DEC);     // Show the Date
  Serial.print(' ');
  Serial.print(Month[now.month()]); // Show the Month
  Serial.print(' ');
  Serial.print(now.year(), DEC);    // Show the Year
  Serial.print(", ");


  Serial.print(now.hour(), DEC);    // Show the Hour
  Serial.print(':');
  Serial.print(now.minute(), DEC);  // Show the Minute
  Serial.print(':');
  Serial.print(now.second(), DEC);  // Show the Second
  Serial.println('\n');

  delay(1000);
}

After the program is uploaded, open the Arduino IDE Serial Monitor and you will see the data that looks like this:

DS3231 arduino RTC Tutorial Using Adafruit Library

In the above program, the first line of the Mont array I wrote ” “, because the array reading starts from 0, then there is no month in month 0. From that, I added an empty character.

If you want to manually set the timing, use the command rtc.adjust(DateTime(year, month, date, hour, minute, second)); Learn more about the program below:

Set Time Using Serial

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 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
/*
   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_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));
    }
  }
}

Thank you for visiting Chip Piko’s website. Hope it is useful.

1 comment

Leave a Reply