PCF8593
Arduino sketch

I happened to receive a piece of equipment with a PCF8593 RTC on board but no documentation on how to interface it.

I searched the internet but only found two programs for the Arduino.  They were both very complex C++ libraries that I didn't understand or were able to compile.  There were no example sketches with them.  For me, they were unusable.  So I found a sketch by John Boxall for the similar PCF8563 and modified that sketch for the PCF8593.

/* PCF8593 RTC write/read demonstration
   by Roger Schaefer
   http://www.rasmicro.com/
   
   adapted from a sketch for the PCF8563
   by John Boxall
   http://tronixstuff.com/2013/08/13/tutorial-arduino-and-pcf8563-real-time-clock-ic/
*/
#include "Wire.h"
#define PCF8593address 0x51

byte control, hundredths, second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte temp5;
byte temp6;
String days[] = {
  "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
int ThisYear = 2013;

byte bcdToDec(byte value)
{
  return ((value / 16) * 10 + value % 16);
}

byte decToBcd(byte value){
  return (value / 10 * 16 + value % 10);
}

void setPCF8593()
// this sets the time and date to the PCF8593
{
  Wire.beginTransmission(PCF8593address);
  Wire.write(0x00);
  Wire.write(decToBcd(control));    // location 00h
  Wire.write(decToBcd(hundredths)); // location 01h
  Wire.write(decToBcd(second));     // location 02h 
  Wire.write(decToBcd(minute));     // location 03h
  Wire.write(decToBcd(hour));       // location 04h also am/pm & 24 or 12 hr
  Wire.write(temp5);
  Wire.write(temp6);
  Wire.endTransmission();
}

void readPCF8593()
// this gets the time and date from the PCF8593
{
  Wire.beginTransmission(PCF8593address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8593address, 5);
  second     = bcdToDec(Wire.read());             // location 02h
  minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
  hour       = bcdToDec(Wire.read() & B00111111); // location 04h
  temp5      = Wire.read();                       // location 05h 
  temp6      = Wire.read();                       // location 06h 
  dayOfMonth = bcdToDec((temp5) & B00111111);  
  month      = bcdToDec((temp6) & B00011111);      
  year       = (temp5 >> 6);
  dayOfWeek  = (temp6 >> 5);
}

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  ThisYear = ((ThisYear / 4) * 4);  //  change to last leap year
  ////////////////////////////////////////////////////
  // change the following to set your initial time
  ///////////////////////////////////////////////////
  control = 0;
  hundredths = 0;
  second = 45;
  minute = 59;
  hour = 23;
  dayOfWeek = 1;    // 0 to 6
  dayOfMonth = 31;
  month = 3;    
  year = 2;        // 0 to 3
  temp5 = ((year << 6) | decToBcd(dayOfMonth));
  temp6  = ((dayOfWeek << 5) | decToBcd(month));
  // comment out the next line and upload again 
  // to set and keep the time from resetting every reset
  setPCF8593();
}

void loop()
{
  readPCF8593();
  Serial.print(days[dayOfWeek]); 
  Serial.print(" ");
  Serial.print(month, DEC);  
  Serial.print("/");
  Serial.print(dayOfMonth, DEC);  
  Serial.print("/");
  Serial.print((ThisYear + 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(3000);
}

 

The time and date setpoint is hard coded in the setup() function.  That should be modified for the current conditions.  Better yet, code in a way to set the clock from keyboard input or directly from a time standard like your computer's time.

What differentiates the PCF8593 from other Real Time Clock IC's is a register for hundredths of a second and an alarm that can be set for any point of time in the year.

The demonstration sketch, above, does not use any of these features but they would not be difficult to add.

Schematic; click for larger view.

   

Roger's Embedded Microcontrollers Home Page     


This page written by Roger Schaefer. Last updated June 2, 2014