Arduino RTClib explained

p1403360560_ds1307_small

One of the main functionalities of the clock will be… suprise surprise, keep track of time!

For this task we’ll interface with a DS1307 RTC using the RTClib. You can just include that library and forget how it works. But that’s not the way this blog works. Let’s dive a little deeper.

RTC Library

This nice RTC library will let us “talk” to the RTC without problem. I’ll split this post in three parts:

  • First a check on the header.
  • Second, a quick check on the DS1307 itself. (You can’t implement if you don’t know what to implement)
  • Last, the implementation of the library.

Disclaimer and small print: It seems I’ve been using an old RTClib, which works but has less functionality that the one linked. I’m not even sorry.

RTCLib Header

This section is a nice stroll through the header of the RTClib.

Ok, a class DateTime . Makes sense. What does this class provide?

A Bunch of functions related to recorded time (and public ). Those are clearly the functions that we are meant to use. Create a DateTime from an uint32_t or a bunch of: year, month,… etc. For this library, probably, create a datetime from the RTC itself.

After the creation, we can check the value of the time with the “getters” ( year() , month() ,…), I personally like that there’s also a dayOfTheWeek() function :-D, even if I don’t use it.

It has a separation of time since 1/1/2000 and the more standard time, the epoch time.

As protected, we have the data storage. Nothing too fancy.

Finally, there are two other classes:

RTC_DS1307 and RTC_Millis . Both classes seem to provide the same functionality via the functions: adjust() begin() now() . The now() function returns the date with the previously defined DateTime instance.

For our case, we don’t care about the Millis class, we are interested in the RTC_DS1307, that will give us the functionality to connect with the TinyRTC module.

DS1307 Datasheet(before implementing)

Before going into the functions, let’s see what are we talking to, the DS1307. For that, we’ll bring in a corresponding datasheet and look up how it works. From there, we gather the following:

  • It is indeed an I2C serial device.
  • It stores and counts the time. (Duh, an RTC)
  • It has 8 registers. (7 for time, 1 for control)
  • The time is stored in BCD format.
  • Day of the week is user defined.
  • When reset (or first power) the time is 01/01/00 01 00:00:00 (MM/DD/YY DOW HH:MM:SS)

Of course it has a plethora of information, but for us, the most important thing is the defined registers:

DS1307 RTC registers

DS1307 RTC registers

I’ll explain specifics of the registers when (if) they are needed. It is also the first time in my life I stumble upon the BCD format. It won’t be discussed in depth here, suffice to say that each digit is stored separately (24 is stored as two digits, 0010 and 0100 instead of 0001 1000 ).

And even more important, the ID to address the device:

(…)the slave address byte contains the 7-bit DS1307 address, which is 1101000(…)
— DS1307 Datasheet

RTCLib Implementation

We’ll skip the implementation of DateTime. You can check if yourself in github. But Let’s see how the RTC_DS1307 class manages.

First off, the basic defines and includes

  • Wire.h : Arduino provided library to connect to I2C devices.
  • avr/pgmspace.h : Program space utilities library for AVR architecture. Not necessary for the following explanation, but I’ll use it in the future.
  • RTClib.h : The defined RTCLib
  • DS1307_ADDRESS : Self explained. The I2C address to DS1307 RTC
  • ARDUINO100 : Select Arduino library to load accordingly to IDE

The ARDUINO100 define selects which version of the RTC_DS1307 class to compile. Here we’ll discuss the ARDUINO100 = TRUE version of later Arduinos.

The list of functions used for this implementation is:

Let’s go step by step:

bcd2bin and bin2bcd

This two functions move the bits up and down to translate between BCD format and more common base-2 binary. We won’t enter into specifics, but those are used to write/read registers.

begin

Okay. Begin is a dummy function. NEXT!

isrunning

Two parts. A signal tramsission to the DS1307 and a request of information. The respective function descriptions can be read from the Arduino Wire library documentation.

  • beginTransmission : Starts an I2C transmission.
  • write : writes something to the bus
  • endTransmission : Writes the End transmission to the bus.
  • requestFrom : Request N bytes from the device
  • receive : Read bytes

The initial trasmission writes i , with value 0, always. Why name it i is beyond my comprehension.

Second, we request 1 byte. That will be the first register, and returns the value of the most significant bit. From the datasheet this bit is CH (Clock Halt). If this bit is set to 1, means that the oscillator is disabled, otherwise (zero) it is enabled.

As the function name suggests. It will retrieve the current time, and return it formatted as a DateTime instance (we discussed it in earlier sections).

This time we’ll request 7 bytes (registers). As seen on the datasheet, the bytes are recieved in the following order: seconds, minutes, hours, day, date, month, year. This function simply reads and process the data using the bcd functions, that do some magic.

Between hour and day, the function skips one byte. This byte is the day of the week byte. This implementation of RTClib skips this value. The latest and greatest version probably uses it.

adjust

This is exactly the same as the now function but inverted. Write the registers instead of reading

Conclusion

Know your libraries, it may save you some time in the future.

To be fair, when I wrote the clock application I simply used the library without diving into it. Of course I had a look into the header file, but since it simply worked, there was no reason the check.

While writing this blog post, I realized it was getting quite boring, and the basics of how to use this RTC were already covered in so many other posts. So I decided to focus in the RTClibrary (for those who want to know). And maybe (just maybe) I’ll write a post on how to use the lib, but I’m sure that the linked pages are enough for everyone to wire an RTC to an Arduino.


Источник: jcastellssala.com