Using uRTCLib.h for DS3231

Hi all,

First time posting questions here. I hope this is a quick question.

I am trying to develop a simple alarm clock using DS3231. I followed some example codes from the internet that uses uRTCLib.h. One thing I don't understand.

void [set] (const uint8_t, const uint8_t, const uint8_t, const uint8_t, const uint8_t, const uint8_t, const uint8_t)
or
rtc.set(rtc_sec, rtc_min, rtc_hr, rtc_dayofweek, rtc_dayofmonth, rtc_month, rtc_year);

Is this set function for 24 hours mode only? If I set it to 12 hours first using
rtc.set_12hour_mode(1);
then in rtc.set there is no way to enter AM or PM for the hour. That's why I think rtc.set is for 24 hours mode only. Is that right?

If that is true, what is the proper sequence to set up 12 hours mode? I think I have to enter the hour in rtc.set in 24 hours mode, then use rtc.set_12hour_mode(1) to convert to 12 hours mode. Is that right? I appreciate any help.

I can't answer the question with certainty. But the beauty of Arduino is that you can easily test :wink:

As far as I understand the library the rtc.set_12hour_mode() modifies the hour register of the RTC by adding or subtracting 12 and setting the 12/24 hour flag. You have the source code of the library on your computer so you can look it up; on github: https://github.com/Naguissa/uRTCLib/blob/master/src/uRTCLib.cpp#L723

You can also subtract 12 from the hour if the hour is greater than 12; and keep an AM/PM flag if you want to use a 12 hour clock.

Looking at the source code for the function

you can see that it basically transfer into the registers starting from register at address 0 the different bytes you passed as parameters (Bcd encoded) up to register at address 6

You first need to understand how the BCD (Binary-Coded Decimal) encoding works: It is a way of representing decimal numbers using binary, where each decimal digit is stored as a 4-bit binary value.

For example, in standard 8-bit binary, the decimal number 45(dec) is represented as:

45(dec) → 101101(binary)

But in BCD, each decimal digit is stored separately in 4 bits:

4(dec) → 0100 (binary)
5(dec) → 0101 (binary)

So, 45(dec) would be encoded as 0100 0101(BCD)

Then you need to look at what is expected in those registers

For the hour register, you can now see that

➜ In 12-hour mode, bit 6 is the AM/PM flag (1 for PM, 0 for AM), bit 5 is set to 1 for hours 10-12, and bits 4-0 represent the units digit of the hour (1-9).

➜ In 24-hour mode, bit 6 is always 0, bit 5 represents the tens digit for hours 10-23, and bits 4-0 represent the units digit of the hour (0-9).

So if you want to use the set() function in 12h mode you need to build the hour byte according to what the register expects, calculating the time in 12h mode and setting the bits 6 / 5 / 4 in the right way.

Alternatively, you can force the 24h mode, update the time, and force the 12h mode back and let the library do the bit work for you.

Thank you sterretje for the reply.

Thank you Jackson for the detailed explanation. Going through each bit to understand what's going on is very helpful.
I guess I will try the alternative method you described first because playing with the bits is going to take more work.
Again appreciate the help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.