Using a DS3231 RTC with TimeAlarms

I'm fairly new to Arduino and have adopted a project to create a four outlet timer using an Uno R3, DS3231 RTC module, I2C LCD 16x2 and a 4 relay module. Each of the outlets will be individually programmable.

All was going well until I tried to decipher how to use the DS3231 to set the time for TimeAlarms. Probably something simple, but Googling the various RTC libraries and descriptions has brought me to this forum for assistance :confused:

So here's an attempt to use clarifying questions to express where I'm trying to go with a sketch:

  • What RTC library is best (or recommended)? A library that has documentation to clearly call out the functions and provide usage examples would be great.
  • What code is required to initialize the RTC and then pass the time to TimeAlarms?
  • What code is required to display the time on an I2C LCD?

Thanks!

What RTC library is best (or recommended)? A library that has documentation to clearly call out the functions and provide usage examples would be great.

I strongly recommend the Jack Christensen library DS3232RTC , which works for the DS3231 and it is available at https://github.com/JChristensen/DS3232RTC It is designed to be integrated with the time and time alarms library, and is a drop in replacement for all DS1307sketches.

What code is required to initialize the RTC and then pass the time to TimeAlarms?

The setSynchProvider() function of the time library will link the RTC to the internal clock used with TimeAlarms. It will all be self evident from the example programs.

What code is required to display the time on an I2C LCD?

I strongly recommend that you the new library by Bill Perry designed for these LCD's called hd44780 which is available through the library manager. It is "plug and play". There is no mystery about the backpack and the special"constructor" to get it running.

Most excellent, thanks cattledog - my sketch is up and running!

I did find one issue with the TimerRTC.ino example sketch on the library page - Alarm.delay has to be used in place of delay when using Time/TimeAlarms.

Hello cattledog:

The JChristensen ds3231 library is presenting an unusual result - after running overnight the printDigits(second()); no longer displays values between 00 and 59; instead it starts displaying three digits (000) and appears to be counting up to 1000.

I’m guessing this has to do with a usage note for the library, but this is only a guess:

“When using the DS3232RTC library, the user is responsible for ensuring that reads and writes do not exceed the device’s address space (0x00-0x12 for DS3231, 0x00-0xFF for DS3232); no bounds checking is done by the library.”

Any ideas?

#include <Time.h> // http://playground.arduino.cc/code/time
#include <TimeAlarms.h> // http://playground.arduino.cc/code/time
#include <DS3232RTC.h> //https://github.com/JChristensen/DS3232RTC

//In void setup()

    setSyncProvider(RTC.get);   // Get the time from the RTC
    if(timeStatus() != timeSet) 
        Serial.println("Unable to sync with the RTC");
    else
        Serial.println("RTC has set the system time");

//In void loop()

  digitalClockDisplay();  // Print the current time at the beginning of the LCD second row
  Alarm.delay(250);

void digitalClockDisplay(void)
{
    // Display time in the time in second row of the LCD
    lcd.setCursor(0,1);
    lcd.print(hour());
    printDigits(minute());
    printDigits(second()); 
}

void printDigits(int digits)
{
    // utility function for digital clock display: prints preceding colon and leading 0
    lcd.print(':');
    if(digits < 10) 
        lcd.print('0');
    lcd.print(digits); 
}

try using this function instead:

void digitalClockDisplay(void)
{
    // Display time in the time in second row of the LCD
    char currentTime[9];
    snprintf(currentTime, sizeof(currentTime), "%2d:%2d:%2d", hour(), minute(), second());
    lcd.setCursor(0,1);
    lcd.print(currentTime);
}

Google snprinf() and C++ Format Specifiers to learn how to create a nice char buffer to send to a display

Thank you BulldogLowell - that is some elegant code!

I've updated my sketch with the code and will see if the time display behaves over time.

A nice feature to add would be a leading zero for minutes and seconds when their value is less than 10. The current code displays:

8: 9: 5

Would be great to display this as:

8:09:05

or

08:09:05

"%2d:%02d:%02d" for 8:09:05

or

"%02d:%02d:%02d" for 08:09:05

Pete

Thanks Pete, I'll give that a try!

el_supremo: "%2d:%02d:%02d" for 8:09:05

or

"%02d:%02d:%02d" for 08:09:05

Pete

whoops, I forgot the zeroes!

Sprintf is a good solution, but your original problem is not a problem with the library, but rather a problem with your code, and a lesson in cursor management with the lcd displays with the hd44780 controller.

Unlike the serial monitor, anything printed on the lcd screen is persistent. There is internal memory in the hd44780 controller, and you always need to be aware of clearing or overwriting any previous information.

In your case, the time data written to the lcd needs to occupy 8 spaces. If not, then when the data occupies less then 8 space, the trailing number will be displayed. The printDigits function insures that all hr/minute/second data is written with 2 digits with preceeding 0 if less than 10. Since your hours are 0-24, you need to use the two digits function on them as well.

The ‘:’ colon is really not part of two digits, and is probably better in the display function and not the two digits function. Otherwise, you will need to have a conditional test to remove the colon from before the hours.

void digitalClockDisplay(void)
{
   // Display time in the time in second row of the LCD
   lcd.setCursor(0,1);
   //lcd.print(hour());
   printDigits(hour());
   lcd.print(':');
   printDigits(minute());
   lcd.print(':');
   printDigits(second()); 
}

void printDigits(int digits)
{
   // utility function for digital clock display: prints preceding colon and leading 0
  // lcd.print(':');
   if(digits < 10) 
       lcd.print('0');
   lcd.print(digits); 
}

Thank you all!

This code has been part of a project to develop an Aquarium Outlet Controller with Time and Temperature events.

I've posted the project on Instructables:

Instructables Aquarium Contoller Project