Setting up the PCF8563 for use with Arduino

Introduction

Last post I started a discussion about some of the most common real-time clocks out there, and people gave some feedback to update the article. At the end, I chose the PCF8563 from NXP to use on the first smd version of my smartwatch (Arduino compatible). Of course all RTCs are fairly accurate, some more than the others, and as we’ve seen, from 2 to 20 ppm, but the real deal for this project was to use a module that consumes the least power possible, and on this IC is from 0.5uA (standby) to 200uA (I2C interface active).

Its main features:

  • Year, month, day, weekday, hours, minutes, and seconds;
  • Needs a 32.768 kHz quartz crystal;
  • Clock operating voltage: 1.0 V to 5.5 V at room temperature;
  • Low backup current; typical 0.25 uA at VDD = 3.0 V and Tamb = 25 ºC;
  • 100 or 400 kHz two-wire I2C-bus interface (at VDD = 1.8 V to 5.5 V);
  • Programmable clock output for peripheral devices (32.768 kHz, 1.024 kHz, 32 Hz, and 1 Hz);
  • Alarm and timer functions;
  • Integrated oscillator capacitor;
  • Internal Power-On Reset (POR);
  • I2C-bus slave address: read A3h and write A2h;
  • Open-drain interrupt pin;

Now our problem is: how to get the most out of our clock, that means, the best precision? How to set up its pins correctly? How to read/write? And how to put it on low power consumption mode?

Pinout configuration

The version we are going to use is the DIP8 package. It has the following pins:

pcf8563 pin sop8 dip

  • OSCI: oscillator input (32.768kHz);
  • OSCO: oscillator output(32.768kHz);
  • INT: interrupt output (can be used to wake up the Arduino – Pins 2 and 3);
  • VSS: ground;
  • SDA: serial data (A4 pin from Arduino);
  • SCL: serial clock (A5 pin from Arduino);
  • CLKOUT: clock output (for set up or other uses);
  • VDD: supply voltage (or 3.3V from Arduino Pro Mini);

Finding the best configuration for the clock

pcf8563 set upIf you want a better watch, you need to set up correctly the real-time clock. As this module uses external oscillators and capacitors, a fine tune is needed. That means, we need to find the correct value to the capacitor placed on the OSCI pin so it compensates small variations on the crystal itself. To do that, you will need an oscilloscope. You will connect the probe and a pull-up resistor on the CLKOUT pin, and will measure the frequency there. This way you can alter the Ct capacitor for best value possible. If you don’t have an oscilloscope, than you will have to use a pre-determined value. More information on this can be found on the user manual, here. On the datasheet is stated that is possible to achieve 5 ppm accuracy with these clocks, however, over the internet people argue that its precision is around 20 ppm (source needed).

Backup battery and placing the components

One really useful thing to do is to use a spare battery to supply the PCF8563. It is not mandatory, however. As the module consumes low power, if one use a spare battery, you might never miss the time, and never have to set it up again. To use one battery dedicated ford this purpose, you have to follow as the figure shows. pcf8563 spare batteryNow it is possible to place the IC on a prototype board to test the module with the Arduino code. It is needed to place some extra capacitors. In my case I used R1 (figure) as 330 Ohms, C1 (between VDD and VSS) 100 nF, and the capacitor Ct from OSCI 22 pF. Next connect SDA and SCL to pins A4 and A5 respectively. In my protoboard I used pull-up resistors on the I2C pins because I made a bare bones Arduino Pro Mini. The resistors are usually between 2K and 10K Ohms. The diodes are the 4148.

 The Arduino Code

First of all, if you are using a backup battery for your RTC module, you have to set the time. Following this website, written by John Boxall, I found really useful their code. The standard Time.h library from Arduino does not work for this RTC, because it was made for the DS1307. I found too many problems adapting it. The read and write code:

#include "Wire.h"
#define PCF8563address 0x51
 
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
 
byte bcdToDec(byte value){
  return ((value / 16) * 10 + value % 16);
}
 
byte decToBcd(byte value){
  return (value / 10 * 16 + value % 10);
}
 
void setPCF8563(){
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.write(decToBcd(second));  
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));     
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(dayOfWeek));  
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}
 
void readPCF8563(){
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 7);
  second     = bcdToDec(Wire.read() & B01111111); 
  minute     = bcdToDec(Wire.read() & B01111111); 
  hour       = bcdToDec(Wire.read() & B00111111); 
  dayOfMonth = bcdToDec(Wire.read() & B00111111);
  dayOfWeek  = bcdToDec(Wire.read() & B00000111);  
  month      = bcdToDec(Wire.read() & B00011111);  
  year       = bcdToDec(Wire.read());
}
 
void setup(){
  Wire.begin();
  Serial.begin(9600);
  // change the following to set your initial time
  second = 0;
  minute = 28;
  hour = 9;
  dayOfWeek = 2;
  dayOfMonth = 13;
  month = 8;
  year = 13;
  setPCF8563();
}
 
void loop(){
  readPCF8563();
  Serial.print(days[dayOfWeek]); 
  Serial.print(" ");  
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/20");
  Serial.print(year, DEC);
  Serial.print(" - ");
  Serial.print(hour, DEC);
  Serial.print(":");
  if (minute < 10){
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");  
  if (second < 10){
    Serial.print("0");
  }  
  Serial.println(second, DEC);  
  delay(1000);
}

Other features described on John’s page is the usage of the square wave output, the self-awareness clock accuracy and the alarm of the clock. As this topic is already covered, I’ll leave this behind for now. Another time I might increment this post.

Next steps

Now that we know how to correctly mount, read and write this clock, it is possible to make the Arduino take advantage of that. Next post I will show how to make an Arduino Pro Mini bare bones, on the prototype board, and how to put it into low power and power down mode, and we will figure out the lowest power consumption possible for our system in order for it to keep counting time and saving energy.

Where to go from here

Advertisements

One thought on “Setting up the PCF8563 for use with Arduino

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s