In this tutorial you learn how to make a blinking clock with a difference!

Updated 18/03/2013

Followers of my website would realise that I tend to make too many clocks in those tutorials. Well, I like making clocks… so here is another one. However this time I have tried to make the most simple version possible. Usually projects will have many LEDs, or perhaps an LCD, buzzers, buttons, all sorts of things. Which looks great and will impress many. But the other day I thought to myself … “how few things do you need to show the time?”

So here is my answer to that question: Blinky the one-eyed clock …

It reminds me of the giant killer orb from The Prisoner… Using a minimal Arduino bootloader system, a DS1307 real time clock IC and an RGB diffused LED … we can make a clock that blinks the time, using the colours of the LED to note different numerical values. For example, if the time is 12:45, the clock will blink red 12 times, then show blue for a second (think of this as the colon on a digital clock) then blink four times in green (for forty minutes), then blink three times in red for the individual minutes. If there is a zero, blink blue quickly. Then the clock will not display anything for around forty seconds, then repeat the process. Here he (she, it?) is blinking the time:

Setting the clock is simple. It is set to start at 12:00 upon power up. So for the first use you have to wait until about five seconds before midday or midnight, then power it up. To save cost it doesn’t use a backup lithium battery on the real-time clock IC, but you could if you really wanted to. If you would like to follow my design process narrative, please read on. If you only want the sketch and schematic, 😦 head to the bottom of this article.

Design process narrative…

So let’s get started!

The first thing to do was test the RGB LED for brightness levels, so I just connected it to the digital output pins of my Eleven via suitable current-limiting resistors. Each LED is going to be different, so to ensure maximum brightness without causing any damage you need to calculate the appropriate resistor values. This is quite easy, the formula is: resistor (ohms) = voltage drop / LED current So if you have a 5 V supply, and LED that needs only 2 volts, and draws 20 milliamps (0.2 amps) , the calculation will be: resistor = (5-2)/0.02 = 150 ohms. To be safe I used a 180 ohm resistor. The LED was tested with this simple sketch:

```/*
*/

int red = 2;
int green = 3;
int blue = 4;
int d = 300;
void setup()
{
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
}

void loop()
{
digitalWrite(red, HIGH);
delay(d);
digitalWrite(red, LOW);
delay(d);
digitalWrite(green, HIGH);
delay(d);
digitalWrite(green, LOW);
delay(d);
digitalWrite(blue, HIGH);
delay(d);
digitalWrite(blue, LOW);
delay(d);
}```

It was interesting to alter the value of d, the delay variable, to get an idea for an appropriate blinking speed. Originally the plan was to have the LED in a photo frame, but it was decided to mount a ping-pong ball over the LED for a retro-style look.  Here is a short video of the result of the test:

If you are going to use a ping-pong ball, please be careful when cutting into it with a knife, initially it may require a lot of force, but once the knife cuts through it does so very quickly:

Now it was time to develop the sketch to convert time into blinks. The sketch itself is quite simple. Read the hours and minutes from the DS1307 timer IC; convert the hours to 12 hour time; then blink an LED for the number of hours, display another colour for the colon; divide the minutes by ten and blink that in another colour; then the modulus of minutes and ten to find the individual minutes, and blink those out. Here is the first sketch I came up with. Finally, the code was tested using the Eleven board and my DS1307 real time clock shield. It is best to use existing hardware while testing, before committing to purchasing new hardware and so on. So here it is on the breadboard:

And telling the time! In this example, the time is 3:45…

But perhaps that was a little bland. By using analogWrite() we can control the brightness of the LED segments. So now there are two more functions, whiteGlow() and blueGlow(); whose purpose is to make the display “glow” by increasing then decreasing the brightness. And scale back the amount of blinking, to increase battery life and make blinky less obvious. So now the display will glow white to announce the forthcoming display of time, wait a second, blink the time (with a blue glowing colon) then stay dark for ten seconds before repeating the process. Here is a quick demonstration of this display style:

Here is the sketch for the above demonstration, and the final one I will use with the hardware prototype. Once happy with the sketch, I put a fresh ATmega328 with Arduino bootloader in the board and programmed it with the blinky sketch, to be used in the final product.

Next was to build my own hardware. My last hardware unknown is the amount of current the circuit draws. Once I know this the correct voltage regulator and power supply can be decided upon. I had a fair idea it would be less than 100 milliamps, so I put a 6V battery onto supply duty via a 78L05 5V regulator (data sheet), and recorded the result:

So it varies, between 20.5 and 46 mA. As it only reaches 46 mA for a short time, we could consider the constant draw to be averaged out at 30 mA. I really want this to be able to run from a battery, but without having an external lead-acid battery lurking around, it will need a plug-pack with an output voltage greater than 7V DC. Another alternative would be to run it from a USB socket, a nice source of 5V. If doing so, there wouldn’t be a need for the 78L05 regulator. Which brings us to the  circuit diagram, which includes the power regulator:

It does not allow for programming in the circuit, so you will need to program the microcontroller on another Arduino or compatible board, then transfer it to the blinky circuit board as described above. At this stage I tested it again, but using a solderless breadboard. In doing so you can make final hardware checks, and  generally make sure everything works as it should. This is also a good stage to double-check you are happy with the display behaviour, default time and so on.

Time to solder up the circuit on some stripboard. Blank stripboard varies, but luckily I found this and a nice box to hold it in:

Stripboard does vary between retailers and so on, so you will need to work out the layout with your own board. In doing so, please double-check your work – follow the layout against the schematic and so on. Have a break, then check it again. There is nothing worse than soldering away to realise you are one strip too far over or something. My hand-eye coordination is not the best, therefore my soldering isn’t pretty, but it works:

One would say that there is a good argument for making your own PCBs… and I would start to agree with that. The LED is soldered to some short leads to give it a bit of play, and some heatshrink over the legs to keep them isolated:

And finally, to add a DC socket to feed blinky some power…

The last thing was to check the soldering once more under natural light, to check for bridges or shorts, then have a cup of tea. Upon my return I drilled out a hole in the enclosure lid for the LED, and one one the side for the DC socket, and fitted the lot together… and success! It worked 🙂

So there you have it. The journey from a daydream to a finished product… well a prototype anyway. But it works, and that is the best feeling of all. You can download the schematic from here. And here is the Arduino sketch:

```/*
Version beta 2.1
John Boxall 04 August 2010
Creative Commons Attribution-Share Alike 2.5 Australia
DS1307/i2c timekeeping based on code by Maurice Ribble
17-4-2008 - http://www.glacialwanderer.com/hobbyrobotics
*/

#include "Wire.h"
int red = 9; // LEDs connected to these pins as you might want to PWM them to alter brightness
int green = 10;
int blue = 11;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
void setDateDs1307(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-28/29/30/31
byte month,         // 1-12
byte year)          // 0-99
{
Wire.write(0);
Wire.write(decToBcd(second));    // 0 to bit 7 starts the clock
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.write(0);
Wire.endTransmission();
*hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
}

// blinks LED on pin 'colour' for 'blinks' times with on and off delay of 'ondelay', 'offdelay'
// colour: 9 is red, 10 is green, 11 is blue
{

{
digitalWrite(colour, HIGH);
delay(ondelay);
digitalWrite(colour, LOW);
delay(offdelay);
}
}

{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
float aa;
int bb;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

// convert hours from 24 to 12 hour time
if (hour==0)
{
hour=12;
}
if (hour>12)
{
hour=hour-12;
}
blueGlow(1,10);
aa=minute;
aa=aa/10;
bb=int(aa); // find the value of tens of minutes (0~5)
if (bb>0)
{
}
if (bb==0) // but if the time is something like 03:02?
{
}
aa=minute % 10; // find modulo of minutes to get single minutes
bb=aa;
if (bb>0)
{
}
if (bb==0)
{
}
}

void whiteGlow(int n, int d)
{
for (int nn=0; nn<n; nn++)
{
for (int a=0; a<=255; a++)
{
analogWrite(red, a);
analogWrite(green, a);
analogWrite(blue, a);
delay(d);
}
for (int a=255; a>=0; --a)
{
analogWrite(red, a);
analogWrite(green, a);
analogWrite(blue, a);
delay(d);
}
}
}

void blueGlow(int n, int d)
{
for (int nn=0; nn<n; nn++)
{
for (int a=0; a<=255; a++)
{
analogWrite(blue, a);
delay(d);
}
for (int a=255; a>=0; --a)
{
analogWrite(blue, a);
delay(d);
}
}
}

void setup()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
second = 0;
minute = 17;
hour = 4;
dayOfWeek = 6; // these values are moot, but need to store something
dayOfMonth = 28;
month = 5;
year = 10;
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); // every time blinky has new batteries, it will start from midnight/midday
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
}

void loop()
{
whiteGlow(1, 10); // glow white - announces that the time will now be shown
delay(1000); // give people a second to focus on blinky
delay(50000); // wait 50 seconds
}```

I hope you enjoyed reading this post and hopefully felt inspired enough to make your own.

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.

1. Using a ping-pong ball as a diffuser is a great idea! (one that I shall liberate for a project I’m working on)

2. DJPhil says:

Interesting! It’s spinning off all sorts of ideas in my head. I bet a four sphere version using a color to number conversion would look neat. Add temperature, weather data, hmm.

I’m going to go make some coffee and think on this.

• Sounds great… if you do please let me know

• DJPhil says:

I’ve got a long way to go myself before I can craft such a thing, as I’m currently completely unschooled in programming and micros. I’m working on that though, as soon as I finish a half dozen or so analog projects I have backed up . .

The coffee got me as far as wondering if RGB LEDs could reproduce resistor color codes. I’d imagine brown would be difficult. It could give you another display method to play with.

P.S. I stopped to write the fellow who developed your wordpress theme. I knew I’d seen that name before, and then it hit me. He was a musician in the late 90s tracking community (mod, fasttracker, screamtracker, etc.), and very good at it. Small world!

• Crikey, small world isn’t it?
Were you considering a resistance meter that shows the colour codes? That would be awesome. You could always use a small colour LCD instead, could be easier to make brown.
have fun
john

• DJPhil says:

Oh, also, did the ping pong ball actually say ‘For External Use Only’ on it?!?

D: Yikes!

• Yesssss… yes it did. Souveneir from “Priscilla” show at Star City a few years ago.
Cheers
John

3. Joshua says:

Normally a fan of 24-Hour time….. But that could make reading the time a much longer process….

• Hello!
Yes, I think in 24 hour time as well… but this was more of an exercise in simplicity more than anything. However you have just inspired the next version…
Cheers
John

• There’s a thought… thanks for the idea!

4. […] you are looking for a less is more solution to showing the time then you need to have a look at the Blinky Clock that John Boxall created. It is being run from a ATmega328 Microcontroller and a DS1307 Real Time […]

5. […] when prototyping my clock and timer Arduino-based projects on a breadboard. For example, blinky, or the various clock projects in the Arduino […]

6. Carlo says:

Hi John,
when you make a clock, you always use a timer ic…
Isn’t possible to use the arduino time library or the millis() function for keep track of time?
Thanks,
c.

• Hi Carlo
Good question. I use the DS1307 (and soon the NXP PCF8563) for accuracy, it is an actual real time clock IC, plus with an optional 3V cell it can remember the time when the circuit loses power. millis() depends on the board being on constantly, otherwise it resets to zero, and also resets after 50(?) days or so. The dateTime library is good, but depends on the Arduino having a crystal for accuracy, some do not. So if I am making a clock, in my opinion a dedicated timing chip with back up is the way to go. But at the end of the day it is up to you! 🙂
cheers
john

7. That is REALLY cool! You are going to cost me lots of money you know!

8. Paul says:

Hey John,

Thanks for the fantastic clock idea. I think it is just great. I played around some with your program and put the finished project up on Instructables:

I gave you full credit in the Instructable and the video included in it for the idea behind the project. Just giving you a heads up. Thanks again.

As you say over there, Cheers mate!

• John Boxall says:

Well done, thanks for sharing it with us.