Posts with «rtc» label

This Creepy Skull Shows Time With Its Eyes

Sometimes you have an idea, and despite it not being the “right” time of year you put a creepy skull whose eyes tell the time and whose jaw clacks on the hour into a nice wooden box for your wife as a Christmas present. At least, if you’re reddit user [flyingalbatross1], you do!

The eyes are rotated using 360 degree servos, which makes rotating the eyes based on the time pretty easy. The servos are connected to rods that are epoxied to the spheres used as eyes. Some water slide iris decals are put on the eyes offset from center in order to point in the direction of the minutes/hours. An arduino with a real time clock module keeps track of the time and powers the servos.

Check out the video after the break:

The jaw opens and closes on the hours – springs are screwed to the inside of the jaw to the outside of the skull behind the bones that surround the eyes; they’re hidden when the skull is in its box. A third servo is used as a winch to pull the jaw open from the inside of the bottom of the chin. When it releases, the springs close the mouth and the clack of the teeth replaces an hourly chime.

A bit late (or early) for Halloween, but it’s a really fun project. [Flyingalbatross1] has made the arduino code available, as well as showing plenty of images of how the parts are put together. Take a look at this this atomic clock-in-a-skull, or you make your own talking skull for Halloween!

via Reddit

Hack a Day 02 Feb 06:00

Arduino Tachometer Clock Fires on All Cylinders

We’re certainly no strangers to unique timepieces around these parts. For whatever reason, hackers are obsessed with finding new and interesting ways of displaying the time. Not that we’re complaining, of course. We’re just as excited to see the things as they are to build them. With the assumption that you’re just as enamored with these oddball chronometers as we are, we present to you this fantastic digital tachometer clock created by [mrbigbusiness].

The multi-function digital gauge itself is an aftermarket unit which [mrbigbusiness] says you can get online for as little as $20 from some sites. All he needed to do was figure out how to get his Arduino to talk to it, and come up with some interesting way to hold it at an appropriate viewing angle. The mass of wires coming out of the back of the gauge might look intimidating, but thanks to his well documented code it shouldn’t be too hard to follow in his footsteps if you were so inclined.

Hours are represented by the analog portion of the gauge, and the minutes shown digitally were the speed would normally be displayed. This allows for a very cool blending of the classic look of an analog clock with the accuracy of digital. He’s even got it set up so the fuel indicator will fill up as the current minute progresses. The code also explains how to use things like the gear and high beam indicators, so there’s a lot of room for customization and interesting data visualizations. For instance, it would be easy to scrap the whole clock idea and use this gauge as a system monitor with some modifications to the code [mrbigbusiness] has provided.

The gauge is mounted to a small project box with some 3D printed brackets and bits of metal rod, complete with a small section of flexible loom to cover up all the wires. Overall it looks very slick and futuristic without abandoning its obvious automotive roots. Inside the base [mrbigbusiness] has an Arduino Nano, a DS1307 RTC connected via I2C, a voltage regulator, and a push button to set the time. It’s a perfectly reasonable layout, though we wonder if it couldn’t be simplified by using an ESP8266 and pulling the time down with NTP.

We’ve seen gauges turned into a timepiece before, but we have to admit that this is probably the most practical realization we’ve seen of the idea yet. Of course if you want to outfit the garage with something a bit more authentic, you can always repurpose a Porsche brake rotor.

Decorative Light Box Lets You Guess The Time

Telling time by using the current position of the sun is nothing revolutionary — though it probably was quite the “life hack” back in ancient times, we can assume. On the other hand, showing time by using the current position of the sun is what inspired [Rich Nelson] to create the Day Cycle Clock, a color changing light box of the Philadelphia skyline, simulating a full day and night cycle in real time — servo-controlled sun and moon included.

At its core, the clock uses an Arduino with a real-time clock module, and the TimeLord library to determine the sunrise and sunset times, as well as the current moon phase, based on a given location. The sun and moon are displayed on a 1.44″ LCD which doubles as actual digital clock in case you need a more accurate time telling after all. [Rich] generally went out of his way with planning and attention to detail in this project, as you can see in the linked video, resulting in an impressively clean build surely worthy as gift to his brother. And if you want to build one for yourself, both the Arduino source code and all the mechanical parts are available on GitHub.

An interesting next iteration could be adding internet connectivity to get the current weather situation mixed into the light behavior — not that it would be the first time we’d see weather represented by light. And of course, simulating the northern lights is also always an option.

The Tide Is High, And This Clock Lets You Know

In case you happen to have an ocean nearby, you’re probably familiar with its rising and falling tides. And if mudflat hiking is a thing in your area, you’re also aware of the importance of good timing and knowing when the water will be on its way back. Tide clocks will help you to be prepared, and they are a fun alternative to your usual clock projects. If you’re looking for a starting point, [rabbitcreek] put together an Arduino-based tide clock kit for educational purposes.

If you feel like you’re experiencing some déjà vu here, this indeed isn’t [rabbitcreek]’s first tide clock project. But unlike his prior stationary clock, he has now created a small and portable, coin-cell version to take with you out on the sea. And what shape would better fit than a 3D printed moon — unfortunately the current design doesn’t offer much waterproofing.

For the underlying tide calculation itself, [rabbitcreek] uses just like in his previous project [Luke Miller]’s location-based library for the ubiquitous DS1307 and DS3213 real-time clocks. Of course, if you also want to keep track of other events on your clock, why not set up calendar events for the next rising tide?

Hack a Day 09 Sep 15:00

Arduino Clock Jots Down The Time, In UV

We’re big fans of the impractical around here at Hackaday. Sure there’s a certain appeal to coming up with the most efficient method to accomplish your goal, the method that does exactly what it needs to do without any superfluous elements. But it’s just not as much fun. If at least one person doesn’t ask “But why?”, then you probably left something on the table, design wise.

So when we saw this delightfully complex clock designed by [Tucker Shannon], we instantly fell in love. Powered by an Arduino, the clock uses an articulated arm with a UV LED to write out the current time on a piece of glow-in-the-dark material. The time doesn’t stay up for long depending on the lighting in the room, but at least it only takes a second or two to write out once you press the button.

Things are pretty straightforward inside the 3D printed case. There’s an Arduino coupled with an RTC module to keep the time, which is connected to the two standard hobby servos mounted in the front panel. A UV LED and simple push button round out the rest of the Bill of Materials. The source code is provided, so you won’t have to figure out the kinematics involved in getting the two servos to play nicely together if you want to try this one at home.

We’ve seen many clocks powered by Arduinos over the years, occasionally they even have hands. But few can boast their own robotic arm.

Linear Clock Slows the Fugit of the Tempus

We feature a lot of clocks here on Hackaday, and lately most of them seem to be Nixie clocks. Not that there’s anything wrong with that, but every once in a while it’s nice to see something different. And this electromechanical rack and pinion clock is certainly different.

[JON-A-TRON] calls his clock a “perpetual clock,” perhaps in a nod to perpetual calendars. But in our opinion, all clocks are perpetual, so we’ll stick with “linear clock.” Whatever you call it, it’s pretty neat. The hour and minute indicators are laser cut and engraved plywood, each riding on a rack and pinion. Two steppers advance each rack incrementally, so the resolution of the clock is five minutes. [JON-A-TRON] hints that this was a design decision, in part to slow the perceived pace of time, an idea we can get behind. But as a practical matter, it greatly simplified the gear train; it would have taken a horologist like [Chris] at ClickSpring to figure out how to gear this with only one prime mover.

In the end, we really like the look of this clock, and the selection of materials adds to the aesthetic. And if you’re going to do a Nixie clock build, do us a favor and at least make it levitate.


Filed under: clock hacks
Hack a Day 02 Apr 03:00

Beautiful Linear RGB Clock

Yup, another clock project. But here, [Jan] builds something that would be more at home in a modern art museum than in the dark recesses of a hacker cave. It’s not hard to read the time at all, it’s accurate, and it’s beautiful. It’s a linear RGB LED wall clock.

You won’t have to learn the resistor color codes or bizarre binary encodings to tell what time it is. There are no glitzy graphics here, or modified classic timepieces. This project is minimal, clean, and elegant. Twelve LEDs display the hours, six and nine LEDs take care of the minutes in add-em-up-coded decimal. (It’s 3:12 in the banner image.)

The technical details are straightforward: WS2812 LEDs, an Arduino, three buttons, and a RTC. You could figure that out by yourself. But go look through the log about building the nice diffusing plexi and a very clean wall-mounting solution. It’s the details that separate this build from what’s hanging on our office wall. Nice job, [Jan].


Filed under: clock hacks
Hack a Day 19 Feb 03:00
arduino  clock  clock hacks  diy  rgb led  rtc  ws2812b  

Pac-Man Clock Eats Time, Not Pellets

[Bob’s] Pac-Man clock is sure to appeal to the retro geek inside of us all. With a tiny display for the time, it’s clear that this project is more about the art piece than it is about keeping the time. Pac-Man periodically opens and closes his mouth at random intervals. The EL wire adds a nice glowing touch as well.

The project runs off of a Teensy 2.0. It’s a small and inexpensive microcontroller that’s compatible with Arduino. The Teensy uses an external real-time clock module to keep accurate time. It also connects to a seven segment display board via Serial. This kept the wiring simple and made the display easy to mount. The last major component is the servo. It’s just a standard servo, mounted to a customized 3D printed mounting bracket. When the servo rotates in one direction the mouth opens, and visa versa. The frame is also outlined with blue EL wire, giving that classic Pac-Man look a little something extra.

The physical clock itself is made almost entirely from wood. [Bob] is clearly a skilled wood worker as evidenced in the build video below. The Pac-Man and ghosts are all cut on a scroll saw, although [Bob] mentions that he would have 3D printed them if his printer was large enough. Many of the components are hot glued together. The electronics are also hot glued in place. This is often a convenient mounting solution because it’s relatively strong but only semi-permanent.

[Bob] mentions that he can’t have the EL wire and the servo running at the same time. If he tries this, the Teensy ends up “running haywire” after a few minutes. He’s looking for suggestions, so if you have one be sure to leave a comment.


Filed under: Arduino Hacks, clock hacks

Redundant Automated Water Filler For Your Coffee

We’ve always wondered why we have indoor plumbing if it isn’t hooked up to our coffee pots. We probably drink as much coffee as water anyway, so why not just hook up a water line to refill the pot? [Loose Cannon] aka [LC] has been working on just that problem, with a whole lot of extra features, creating a very robust automatically-filled, gravity-fed, vacuum-sealed water tank for whatever appliance you have that could use it, including your coffee pot.

[LC] tapped into the 1/4″ water line from the ice maker, which has the added bonus of being a common size for solenoid valves. He’s using an eTape sensor to measure the water level in the reservoir, but he ALSO is using a flow meter in the line itself to double-check that the reservoir won’t overflow. The flow meter allows a hard limit to be set for the maximum amount of water allowed into the tank. He’s used an Arduino Micro to tie the project together, which also handles a real-time clock so the tank can be filled on a schedule.

The tank that [LC] was trying to fill was vacuum-sealed as well, which made things a little trickier. Without a vacuum on the tank, the water would just run out of the overflow valve. This is an interesting project that goes way beyond the usual automatic water supplies for coffee pots we’ve seen before.


Filed under: home hacks

Tutorial – Arduino and PCF8563 real time clock IC

Use the NXP PCF8563 real-time clock IC with Arduino in chapter fifty-four of our Arduino Tutorials. The first chapter is here, the complete series is detailed here.

Updated 20/08/2013

Introduction

Recently a few people have been asking about the PCF8563 real-time clock IC from NXP – so this is a tutorial on how to use it for time, date, alarm clock and square-wave generation purposes.

The PCF8563 is another inexpensive RTC that can be used with an Arduino or other platforms due to the wide operating voltage (1 to 5.5V DC), I2C interface, and very low power consumption (when powered by a backup battery it only draws 0.25 μA). If you aren’t up to speed on the I2C interface, please review the I2C tutorials before moving forward. And please download the data sheet (.pdf).

The PCF8563 is available in various chip packages, for the curious we’re using the TSSOP8 version mounted on a breakout board:

Don’t panic – you can also get it in a breadboard-friendly DIP (through-hole) package as well, and also on a pre-built module from the usual suspects.

Demonstration Circuit

If you have a pre-made module, you can skip to the next section. However if you’re making up the circuit yourself, you will need:

  • One 32.768 kHz crystal
  • Two 1N4148 diodes*
  • One 3V coin cell (with holder)*
  • Two 10kΩ resistors
  • One 0.1 uF capacitor

And here’s the schematic:

* You can skip the diodes and battery if you don’t want a backup power supply when the main power is turned off or removed. Pin 3 is for the interrupt output (we’ll consider that later) and pin 7 is for the square-wave oscillator output.

Communicating with the PCF8563

Now to get down into the land of I2C once more. When looking through the data sheet NXP mentions two bus addresses, which have the same 7-bits finished with either a 1 for read or 0 for write. However you can just bitshift it over one bit as we don’t need the R/W bit – which gives you a bus address of 0x51.

Next you need to know which registers store the time and date – check the register map (table 4) on page 7 of the data sheet:

 There will be a few other registers of interest, but we’ll return to those later. For now, note that the time and date start from 0x02. And one more thing – data is stored in the BCD (binary-coded- decimal) format. But don’t panic, we have a couple of functions to convert numbers between BCD and decimal.

Writing the time and date is a simple matter of collating the seconds, minutes, hours, day of week, day of month, month and year into bytes, converting to BCD then sending them to the PCF8563 with seven Wire.write() functions. Reading the data is also easy, just set the pointer to 0x02 and request seven bytes of data – then run them through a BCD to decimal conversion. With a catch.

And that catch is the need to sort out unwanted bits. Revisit table 4 in the data sheet – if you see an x that’s an unused bit. If any of them are a 1 they will mess up the BCD-decimal conversion when reading the register, so they need to be eliminated just like a whack-a-mole. To do this, we perform an & (bitwise AND) operation on the returned byte and mask out the unwanted bits with a zero. How does that work?

Example – the byte for dayOfMonth is returned – we only need bits 5 to 0. So 6 and 7 are superfluous. If you use (dayOfMonth & B00111111) the & function will set bits 6 and 7 to zero, and leave the other bits as they were.

Now to put all that together in a demonstration sketch. It puts everything mentioned to work and simply sets the time to the PCF8563, and then returns it to the serial monitor. The data is kept in global variables declared at the start of the sketch, and the conversions between BCD and decimal are done “on the fly” in the functions used to send or retrieve data from the PCF8563. Read through the following sketch and see how it works for yourself:

// Example 54.1 - PCF8563 RTC write/read demonstration

#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()
// this sets the time and date to the PCF8563
{
  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()
// this gets the time and date from the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 7);
  second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit
  minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
  hour       = bcdToDec(Wire.read() & B00111111); 
  dayOfMonth = bcdToDec(Wire.read() & B00111111);
  dayOfWeek  = bcdToDec(Wire.read() & B00000111);  
  month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over
  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;
  // comment out the next line and upload again to set and keep the time from resetting every reset
  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);
}

And a quick video of this in operation:

If all you need to do is write and read the time with the PCF8563, you’re ready to go. However there’s a few more features of this unassuming little part which you might find useful, so at least keep reading…

Square-wave output

As with any clock or RTC IC, an oscillator is involved, and as mentioned earlier you can take this from pin 7 of the PCF8563. However – it’s an open-drain output – which means current flows from the supply voltage into pin 7. For example if you want to blink an LED, connect a 560Ω resistor between 5V and the anode of the LED, then connect the cathode to pin 7 of the PCF8563.

The frequency is controlled from the register at 0x0D. Simply write one of the following values for the respective frequencies:

  • 10000000 for 32.768 kHz;
  • 10000001 for 1.024 kHz;
  • 10000010 for 32 kHz;
  • 10000011 for 1 Hz;
  • 0 turns the output off and sets it to high impedance.

The following is a quick demonstration sketch which runs through the options:

// Example 54.2 - PCF8563 square-wave generator (signal from pin 7)

#include "Wire.h"
#define PCF8563address 0x51

void PCF8563oscOFF()
// turns off oscillator
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x0D);
  Wire.write(0);
  Wire.endTransmission();
}

void PCF8563osc1Hz()
// sets oscillator to 1 Hz
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x0D);
  Wire.write(B10000011);
  Wire.endTransmission();
}

void PCF8563osc32Hz()
// sets oscillator to 32 kHz
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x0D);
  Wire.write(B10000010);
  Wire.endTransmission();
}

void PCF8563osc1024kHz()
// sets oscillator to 1.024 kHz
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x0D);
  Wire.write(B10000001);
  Wire.endTransmission();
}

void PCF8563osc32768kHz()
// sets oscillator to 32.768 kHz
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x0D);
  Wire.write(B10000000);
  Wire.endTransmission();
}

void setup()
{
  Wire.begin();
}

void loop()
{
  PCF8563osc1Hz();
  delay(2000);
  PCF8563osc32Hz();
  delay(2000);
  PCF8563osc1024kHz();
  delay(2000);
  PCF8563osc32768kHz();
  delay(2000);
  PCF8563oscOFF();
  delay(2000);
}

And the resulting waveforms from slowest to highest frequency. Note the sample was measured from a point between the LED and resistor, so the oscillations don’t vary between the supply voltage and zero:

Self-awareness of clock accuracy

The PCF8563 monitors the oscillator and supply voltage, and if the oscillator stops or the voltage drops below a certain point – the first bit of the seconds register (called the VL bit) is set to 1. Thus your sketch can tell you if there’s a chance of the time not being accurate by reading this bit. The default value is 1 on power-up, so you need to set it back to zero after setting the time in your sketch – which is done when you write seconds using the code in our example sketches. Then from that point it can be monitored by reading the seconds register, isolating the bit and returning the value.

Examine the function checkVLerror() in the following example sketch. It reads the seconds byte, isolates the VL bit, then turns on D13 (the onboard LED) if there’s a problem. The only way to restore the error bit to “OK” is to re-set the time:

// Example 54.3 - PCF8563 RTC write/read demonstration with error-checking

#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()
// this sets the time and date to the PCF8563
{
  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()
// this gets the time and date from the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 7);
  second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit
  minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
  hour       = bcdToDec(Wire.read() & B00111111); 
  dayOfMonth = bcdToDec(Wire.read() & B00111111);
  dayOfWeek  = bcdToDec(Wire.read() & B00000111);  
  month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over
  year       = bcdToDec(Wire.read());
}

void checkVLerror()
// this checks the VL bit in the seconds register
// and turns on D13 if there's a possible accuracy error
{
  byte test;
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 1);
  test = Wire.read(); 
  test = test & B10000000;
  if (test == B10000000)
  {
    // error
    digitalWrite(13, HIGH);
    Serial.println("Uh-oh - possible accuracy error");
  } else 
  if (test != B10000000)
  {
    digitalWrite(13, LOW);
  }
}

void setup()
{
  Wire.begin();
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.begin(9600);
  // change the following to set your inital time
  second = 0;
  minute = 42;
  hour = 11;
  dayOfWeek = 2;
  dayOfMonth = 13;
  month = 8;
  year = 13;
  // comment out the next line and upload again to set and keep the time from resetting every reset
  // 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);  
  checkVLerror();
  delay(1000);
}

And now for a demonstration of the error-checking at work. We have the PCF8563 happily returning the data to the serial monitor. Then the power is removed and restored. You see D13 on the Arduino-compatible board turn on and then the error is displayed in the serial monitor:

This function may sound frivolous, however if you’re building a real product or serious project using the PCF8563, you can use this feature to add a level of professionalism and instil confidence in the end user.

Alarm Clock

You can use the PCF8563 as an alarm clock, that is be notified of a certain time, day and/or day of the week – at which point an action can take place. For example, trigger an interrupt or turn on a digital output pin for an external siren. Etcetera. Using the alarm in the sketch is quite similar to reading and writing the time, the data is stored in certain registers – as shown in the following table from page seven of the data sheet:

However there is a catch – the MSB (most significant bit, 7) in the registers above is used to determine whether that particular register plays a part in the alarm. For example, if you want your alarm to include hours and minutes, bit 7 needs to be set to 1 for the hour and minute alarm register. Don’t panic – you can easily set that bit by using a bitwise OR (“|”) and B10000000 to set the bit on with the matching data before writing it to the register.

Checking if the alarm has occurred can be done with two methods – software and hardware. Using software you check bit 3 of the register at 0x01 (the “AF” alarm flag bit). If it’s 1 – it’s alarm time! Then you can turn the alarm off by setting that bit to zero. Using hardware, first set bit 1 of register 0x01 to 1 – then whenever an alarm occurs, current can flow into pin 3 of the PCF8563. Yes – it’s an open-drain output – which means current flows from the supply voltage into pin 3. For example if you want to turn on an LED, connect a 560Ω resistor between 5V and the anode of the LED, then connect the cathode to pin 3 of the PCF8563. To turn off this current, you need to turn off the alarm flag bit as mentioned earlier.

Now let’s put all that into a demonstration sketch. It’s documented and if you’ve been following along it shouldn’t be difficult at all:

// Example 54.4 - PCF8563 alarm clock demonstration

#include "Wire.h"
#define PCF8563address 0x51

byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte alarmMinute, alarmHour, alarmDay, alarmDayOfWeek;
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 setPCF8563alarm()
// this sets the alarm data to the PCF8563
{
  byte am, ah, ad, adow;
  am = decToBcd(alarmMinute);
  am = am | 100000000; // set minute enable bit to on
  ah = decToBcd(alarmHour);
  ah = ah | 100000000; // set hour enable bit to on
  ad = decToBcd(alarmDay);
  ad = ad | 100000000; // set day of week alarm enable bit on
  adow = decToBcd(alarmDayOfWeek);
  adow = ad | 100000000; // set day of week alarm enable bit on

  // write alarm data to PCF8563
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x09);
  Wire.write(am);  
  Wire.write(ah);

  // optional day of month and day of week (0~6 Sunday - Saturday)
  /*
  Wire.write(ad);
  Wire.write(adow);  
  */
  Wire.endTransmission();

  // optional - turns on INT_ pin when alarm activated  
  // will turn off once you run void PCF8563alarmOff()
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x01);
  Wire.write(B00000010);
  Wire.endTransmission();
}

void PCF8563alarmOff()
// turns off alarm enable bits and wipes alarm registers. 
{
  byte test;
  // first retrieve the value of control register 2
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x01);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 1);
  test = Wire.read();

  // set bit 3 "alarm flag" to 0
  test = test - B00001000;

  // now write new control register 2  
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x01);
  Wire.write(test);
  Wire.endTransmission();
}

void checkPCF8563alarm()
// checks if the alarm has been activated
{
  byte test;
  // get the contents from control register #2 and place in byte test;
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x01);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 1);
  test = Wire.read();
  test = test & B00001000; // isolate the alarm flag bit
  if (test == B00001000) // alarm on?
  {
    // alarm! Do something to tell the user
    Serial.println("** alarm **");
    delay(2000);

    // turn off the alarm
    PCF8563alarmOff();
  }
}

void setPCF8563()
// this sets the time and date to the PCF8563
{
  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()
// this gets the time and date from the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 7);
  second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit
  minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
  hour       = bcdToDec(Wire.read() & B00111111); 
  dayOfMonth = bcdToDec(Wire.read() & B00111111);
  dayOfWeek  = bcdToDec(Wire.read() & B00000111);  
  month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over
  year       = bcdToDec(Wire.read());
}

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // change the following to set your initial time
  second = 50;
  minute = 44;
  hour = 13;
  dayOfWeek = 1;
  dayOfMonth = 19;
  month = 8;
  year = 13;
  // comment out the next line and upload again to set and keep the time from resetting every reset
  setPCF8563();

  alarmMinute = 45;
  alarmHour = 13;
  // comment out the next line and upload again to set and keep the alarm from resetting every reset  
  setPCF8563alarm();
}

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);

  // alarm?
  checkPCF8563alarm();
}

This is the same as the example 54.1, however we’ve added the required functions to use the alarm. The required alarm data is stored in the global bytes:

byte alarmMinute, alarmHour, alarmDay, alarmDayOfWeek;

and is written to the PCF8563 using the function:

void setPCF8563alarm()

Note the use of bitwise OR (“|”) to add the enable bit 7 to the data before writing to the register. The interrupt pin is also set to activate at the end of this function, however you can remove that part of the code if unnecessary. We also demonstrate checking the alarm status via software using the function:

void checkPCF8563alarm()

which simply reads the AF bit in the register at 0x01 and let’s us know if the alarm has occurred via the Serial Monitor. In this function you can add code to take action for your required needs. It also calls the function:

void PCF8563alarmOff()

which retrieves the contents of the register at 0x01, sets the AF bit to zero and writes it back. We do this to preserve the status of the other bits in that register. For the curious and non-believers you can see this sketch in action through the following video, first the software and then the hardware interrupt pin method (an LED comes on at the alarm time and is then turned off:

Conclusion

Hopefully you found this tutorial useful and now have the confidence to use the PCF8563 in your own projects. Furthermore I hope you learned something about the I2C bus and can have satisfaction in that you didn’t take the lazy option of using the library. People often say to me “Oh, there’s a library for that”, however if you used every library – you’d never learn how to interface things for yourself. One day there might not be a library! And then where would you be? So learning the hard way is better for you in the long run.

And if you enjoy my tutorials, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a second printing) “Arduino Workshop” from No Starch Press.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino and PCF8563 real time clock IC appeared first on tronixstuff.

Tronixstuff 13 Aug 03:18
arduino  clock  i2c  ic  nxp  pcf8563  real  real time clock  rtc  time  tronixstuff  tutorial