Table of Contents

macetech.com_store_images_chronodotv2.jpgmacetech.com_store_images_chronodotv22.jpg The ChronoDot is based on the Maxim DS3231SN temperature-compensated RTC (real-time clock). It contains all the internal logic to accurately count up seconds, minutes, hours, days, months, and years. While it does not know Daylight Saving Time for various locales, it is aware of things like the number of days in a particular month.

This document is intended to get a new RTC user up and running quickly. If you're NOT a new RTC user, you might want to skip this and just get the juicy details from the DS3231 datasheet. The DS3231 is controlled the same way as many other Maxim RTC chips…code for the DS1307 will likely work with the DS3231 without any modification. The only exception might be the absence of a few bytes of general-purpose memory in the DS3231, if a previous application used any of it.

The I2C Interface

The ChronoDot requires an I2C interface to read and write time information. I2C is a bidirectional logic-level communication interface, usually used to allow communication between simple devices over short distances. It requires only two wires and many devices can exist on the same communication bus if they do not have conflicting addresses. I2C works by setting output pins either to a low state, or high-impedance state (usually achieved on a microcontroller by setting the pin as an input). The SDA wire carries the data being transmitted, and the SCL wire carries the clock signal.

Devices on the I2C bus do not ever set the line high; doing so could easily damage several devices. Instead, a pull-up resistor is connected from each of the two wires to the positive power supply. These resistors bring the logic level to a high state when all devices on the bus have set their I2C pins to high impedance. For I2C, these resistors are usually between 4.7K to 47K ohms. Many microcontrollers have internal pull-ups which can be enabled in software.

Sometimes these internal pull-ups are adequate for a short I2C bus with only a few devices; other times, external resistors may need to be added. The ChronoDot has two locations for pull-up resistors, which can be soldered in place if needed and if the ChronoDot is the most convenient location for them.

<photo of chronodot resistor location>

An I2C bus usually consists of one master device (though there can be more), and one or more slave devices. The ChronoDot is always a slave device; it cannot initiate any communications. Instead, the master device must initiate all read and write operations. The master device can put data into any register on the ChronoDot, or it can request the current value of any register. These registers are where the time data is stored. To set the time, you write the desired bytes into the correct registers. To retrieve the time, you request the bytes from those same registers. The ChronoDot automatically handles counting up seconds and incrementing each register correctly.

DS3231 Registers

The time data inside the ChronoDot is organized as shown in the table below. Many registers are formatted as BCD (binary coded decimal) where each nibble determines an upper and lower digit. Some registers have special bits, and some registers have special functions like alarms or square wave output.

ADDRESS BIT 7
MSB
BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
LSB
FUNCTION RANGE
00h 0 10 Seconds Seconds Seconds 00–59
01h 0 10 Minutes Minutes Minutes 00–59
02h 0 12/24 AM/PM
20 Hour
10 Hour Hour Hours 1–12 + AM/PM
00–23
03h 0 0 0 0 0 Day Day 1–7
04h 0 0 10 Date Date Date 01–31
05h Century 0 0 10 Month Month Month/
Century
01–12 +
Century
06h 10 Year Year Year 00–99
07h A1M1 10 Seconds Seconds Alarm 1 Seconds 00–59
08h A1M2 10 Minutes Minutes Alarm 1 Minutes 00–59
09h A1M3 12/24 AM/PM
20 Hour
10 Hour Hour Alarm 1 Hours 1–12 + AM/PM
00–23
0Ah A1M4 DY/DT 10 Date Day
Date
Alarm 1 Day
Alarm 1 Date
1-7
1–31
0Bh A2M2 10 Minutes Minutes Alarm 2 Minutes 00–59
0Ch A2M3 12/24 AM/PM
20 Hour
10 Hour Hour Alarm 2 Hours 1–12 + AM/PM
00–23
0Dh A2M4 DY/DT 10 Date Day
Date
Alarm 2 Day
Alarm 2 Date
1-7
1–31
0Eh EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE Control
0Fh OSF 0 0 0 EN32kHz BSY A2F A1F Control/Status
10h SIGN DATA DATA DATA DATA DATA DATA DATA Aging Offset
11h SIGN DATA DATA DATA DATA DATA DATA DATA MSB of Temp
12h DATA DATA 0 0 0 0 0 0 LSB of Temp

Connecting the ChronoDot

In this example, an Arduino will be the I2C bus master. The Arduino would typically also contain the application code that makes use of the time information; usually this involves triggering an output at an appropriate time.

The CR1632 battery must be installed, or the ChronoDot will not keep time when power is removed. The CR1632 battery included with the ChronoDot should last at least seven years under normal conditions. <insert battery into ChronoDot>

Wiring the ChronoDot to the Arduino is extremely simple: ChronoDot VCC - Arduino 5V ChronoDot GND - Arduino GND ChronoDot SDA - Arduino SDA (A4) ChronoDot SCL - Arduino SCL (A5)

When using the Arduino and ChronoDot alone, pull-up resistors are not usually needed (the internal pull-up resistors on the Arduino are sufficient).

Talking to the ChronoDot

If you were confused at all by the description of I2C above, don't worry. Arduino and most other micro controller platforms have pre made I2C libraries that handle everything for you. All you have to do is know the address of your I2C device and what bytes to read and write, and the I2C library takes care of the rest. When using the Arduino, the I2C library is called Wire. Simply click on Sketch > Import Library > Wire after starting a new sketch, or type in “#include <Wire.h>” at the beginning of your sketch. Put “Wire.begin();” in your setup{} function, and you're ready to send and receive bytes over I2C.

The first important piece of information you'll need is the ChronoDot device address. This makes sure all your requests go to the correct device, otherwise the ChronoDot will ignore whatever is happening on the I2C bus. The Arduino Wire library uses 7-bit addresses; the ChronoDot's address is HEX 0x68 or DEC 104.

Next, you will need to know what data to access, and how it is formatted. In the ChronoDot/DS3231 and other similar RTC devices, register 0 contains seconds. Here's how to read that register:

byte i = 0;
Wire.beginTransmission(0x68);
Wire.write((byte)0);
Wire.endTransmission();
Wire.requestFrom(0x68, 1);

while(Wire.available()) {
  i = Wire.read();
}

If everything went smoothly, the variable “i” should now contain whatever was in the seconds register at the time the Arduino requested it.

Writing data is very similar:

Wire.beginTransmission(0x68);
Wire.write((byte)0);
Wire.write((byte)0);
Wire.endTransmission();

In this case, we just zeroed the seconds register, and it will resume counting up from there.

As seen in the DS3231 register table, the number received directly from the ChronoDot will not be usable without some formatting or conversion. The seconds register is pretty simple, it's BCD. We can convert a BCD value to a raw number by taking the top nibble (four bits) and multiplying by 10, and then adding the value of the bottom nibble. In code, this is one possible way:

i = ((i & 0b11110000)»4)*10 + (i & 0b00001111);

Several of the ChronoDot registers can be converted exactly like that, but several need special treatment. However, that is probably best shown rather than explained. The code example at the end of this article doesn't do much in terms of actually using the time values it receives from the ChronoDot, but it contains a large number of pre made functions you can use to build your own application.

Shortcuts

Instead of building your own ChronoDot application from scratch, you may want to start with some of the other excellent examples and libraries available from various developers.

For the Arduino, the excellent Time library supports the ChronoDot and other similar devices, provides many useful functions, and allows syncing the time in various ways. http://arduino.cc/playground/Code/Time

If you don't have space for the Time library, you may find Stephanie Maks' ChronoDot Library provides a great head start. https://github.com/Stephanie-Maks/Arduino-Chronodot

For other micro controllers, nearly any code designed for the DS1307 will work with the ChronoDot without any modification.