Introduction: Ping Pong Ball Full Colour Binary Clock

About: I love making things. I have for as long as I can remember liked to make stuff. Now days I have two kids (Thomas and Emma) and most of the things I do are safe for them! I love electronics and Microchips, I ha…

Colour changing 24Hr Binary clock using ping pong balls and full colour LED’s and a Funduino 8*8 matrix board.

I have already built a small 12Hr binary clock and fitted it into a computer, this worked very well but was only really half a binary clock (no seconds). So I decided to build a full 24hour with second’s binary clock. As I was designing the clock I decided to try and make it very colourful and pleasant to look at, so I choose full colour LED’s and used ping pong balls to make a nice diffuser! At this stage I hadn’t really thought about how I was going to drive the LED’s I initially thought about using logic gates linked to the PWM pins of the Arduino, but the more I thought about it the more difficult it was. Basically I have 20 5mm full colour LED’s, meaning I have 60 LED’s in total. so at this point I had another think about how I was going to drive all the LED’s and then realised I had the solution in a 8*8 full colour matrix, I had already used a Funduino/colorduino when I made my Plasma box, so this was a logical solution.

Step 1: The Build

I wanted this clock to look pleasing! so the ping pong balls were the main feature and the ¼” bit of ply that they are mounted onto was cut carefully to be hidden behind the balls. You can see in the pictures that I used my favourite build method (design on a Raspberry pi using QCAD, then printed and glued to the wood)

I choose to drill all the holes using a holesaw so the balls sit nicely on the plywood. I then got my little girl to “paint” the ply wood using black ink.

Then the balls were glued to the wood using a glue gun.

Then working from the back and with the ping pong balls resting on a cloth (so they don’t get scratched) I pierced each ping pong ball with the tip of a soldering iron, then cleaned up the hole with a file.

The LED legs were then bent over at different heights and directions so I could wire up each red blue green up in columns (6) and the common positive in rows(4). You should be able to see the detail in the photos, I added a small piece of insulation to the wire where it goes over another wire. The top three LED’s were wired up using black wire for the positive leg.

At this stage I quickly tested all the LEDS using a Multimeter on Diode test. This will light the led with a small voltage.

Once I was happy that all the LED’s were ok, I added different coloured wires to each row and column. 22 in total (3 for each column and 4 positive wires)

I then added a small platform above the connecting wires and fitted the funduino.

Next each wire needed to be soldered to pins on the funduino, and more importantly they needed to be out in the correct place,

Seconds Units pin 8

Seconds Tens pin 7

Minutes Units pin 6

Minutes Tens pin 5

Hours Units pin 4

Hours Tens pin 3

In all cases you will have 3 wires (red, blue and green)

Then the 4 positive wires go to

Bottom row pin 8

Second row pin 7

Third row pin 6

Top row pin 5

Step 2: The Program Explained

Firstly I should point out that I am not very good at programming, however I have improved! My first attempt at a binary clock was very long winded, and I have managed to improve the code considerably.

So the first thing we do is read the time, which is very easy.

(RTC.read(tm))

Then the next bit is to take each value and split it into units and tens AND if the value is less than 10 then make the tens value zero. This routine is run 3 times for the hours minutes and seconds.

void binaryOutput(int number)

{

if (number >= 10)

{

int tens = number/10;

int units = number - (tens*10);

setBinary(units,ROW);

ROW = ROW + 1;

setBinary(tens,ROW);

}

else

{

int tens = 0;

int units = number;

setBinary(ROW,units);

ROW = ROW + 1;

setBinary(ROW,tens);

}

}

You should be able to see that once you have split the number into tens and units you then run another routine to display the value in a Column. This routine take the 0-9 number and converts it to a binary number and turns on (and OFF) the required LED’s

This part of the program was the bit that improved so much from the last attempt! basically each row is treated the same independent of the number of LED’s in the row. which means the units rows have 4 LED’s and the hour Tens only has two LED’s but runs though the same routine, the Funduino doesn’t know that there isnt an LED in the position and any way the unused LED’s would be set to off.

void setBinary(int value, int whichRow)

{

ROW = whichRow;

int XYZ = 8;

int COL = 3;

for (int i = 0; i < 4; i ++)

{

getColor(g);

if (value >= XYZ)

{

Colorduino.SetPixel(ROW,COL,A,B,C);

value = value - XYZ;

}

else

{

Colorduino.SetPixel(ROW,COL,0,0,0);

}

XYZ = XYZ / 2;

COL = COL - 1;

}

}

So how does this bit of code work?? The routine is supplied with two pieces of data, which ROW and the number. XYZ is initially set to 8 and COL set to 3. So you then get the colour code and do 4 loops, on each loop you compare your number with XYZ and determine if it is more, if its more then the top LED should be turned on (the number 8 led!) Then 8 should be subtracted from your number. If its not greater than 8 then the Top LED should be turned off. In both cases you then divide XYZ by 2 and decrement the COL. then you loop again this time checking if your number is greater than 4, and so on. See below for an example.

Number is 6.

Loop1 (input number = 6, XYZ = 8, Col = 3) is it equal to or more than 8? NO turn off top light, Half the XYZ, decrement the Col.

Loop2 (input number = 6, XYZ = 4, Col = 2) is it equal to or more than 4? YES turn on the 3rd light, subtract 4 from the number, half the XYZ and decrement the Col.

Loop3 (input number = 2, XYZ = 2, Col = 1) is it equal to or more than 2? YES turn on the 2nd light, subtract 2 from the number, half the XYZ and decrement the Col.

Loop4 (input number = 0, XYZ = 1, Col = 0) is it equal to or more than 1? NO turn off the bottom light, half the XYZ and decrement the Col

At this point you then increment the ROW reset the XYZ and Col, and do the same routine for the TENS. Then repeat for the minutes and hours.

Lastly for the code you then have to “Flip” the Colorduino page to display the new time, or if the time hasn’t changed then change the colour.

void loop()

{

tmElements_t tm;

if (RTC.read(tm))

{

binaryOutput(tm.Second);

ROW = ROW + 1;

binaryOutput(tm.Minute);

ROW = ROW + 1;

binaryOutput(tm.Hour);

ROW = 0;

}

Colorduino.FlipPage();

}

So that handles the reading and displaying the time, now let’s have a look at the colours. Each Column is set to a colour and the next Column is changed by a value determine by “increment” the larger the number the better the colour variation over the 6 columns. I found that around 8 - 12 is a good number. The colour are decided by a routine which takes the value of “g” (then called rainbow) one colour is incremented, another is decremented and the 3rd is set to zero, this then cycles up and down through all the colours and gives a nice rainbow effect (see the graph for a better explanation) . One problem I had which took a very long time to work out the very simple soloution was how to make the rainbow move slowly across the columns. because I have stepped the colour between each row, if I now want to increment each column by only 1 then I have to take into consideration what the original colour number was and reset "g" to that number then add one. I think that makes sense.

So the last thing is how do you adjust the time???

I wasn’t really sure how I was going to adjust this clock when I started to build this clock, but because there are no inputs available on the colorduino board, I made a GPS clock which you can connect the RTC unit to and correct the time. I will add another instructable on how I made this!!

Step 3: The Full Program

#include <Colorduino.h>

#include <Wire.h>

#include <Time.h>
#include <DS1307RTC.h>
int R = 30;
int B = 40;
int G = 50;
int ROW = 0;
int g = 0;
int GKB = 0;
int increment = 12;
int initalG = 0;
void setup()
{
Colorduino.Init();
unsigned char whiteBalVal[3] = {28,60,44};//RGB
Colorduino.SetWhiteBal(whiteBalVal);
}
void binaryOutput(int number)
{
if (number >= 10)
{
int tens = number / 10;
int units = number - (tens * 10);
setBinary(units,ROW);
ROW = ROW + 1;
setBinary(tens,ROW);
}
else
{
int tens = 0;
int units = number;
setBinary(units,ROW);
ROW = ROW + 1;
setBinary(tens,ROW);
}
}
void setBinary(int value, int whichRow)
{
ROW = whichRow;
int XYZ = 8;
int COL = 3;
for (int i = 0; i < 4; i ++)
{
getColor(g);
if (value >= XYZ)
{
Colorduino.SetPixel(ROW,COL,R,G,B);
value = value - XYZ;
}
else
{
Colorduino.SetPixel(ROW,COL,0,0,0);
}
XYZ = XYZ / 2;
COL = COL - 1;
}
}
void getColor(int rainbow)
{
if (rainbow < 255 )
{
R = rainbow;
B = 255 - rainbow;
G = 0;
}
else if (rainbow < 511)
{
rainbow = rainbow - 255;
R = 255 - rainbow;
B = 0;
G = rainbow;
}
else
{
rainbow = rainbow - 510;
R = 0;
B = rainbow;
G = 255 - rainbow;
}
g = g + increment;
if (g > (765 - increment))
{
g = 0;
}
}
void loop()
{
tmElements_t tm;
if (RTC.read(tm))
{
initalG = g;
binaryOutput(tm.Second);
ROW = ROW + 1;
binaryOutput(tm.Minute);
ROW = ROW + 1;
binaryOutput(tm.Hour);
ROW = 0;
delay(6);
g = initalG + 1;
if (g > (765 - increment))
{
g=0;
}
}
Colorduino.FlipPage();
}

Time Contest

Second Prize in the
Time Contest

Make It Glow! Contest

Participated in the
Make It Glow! Contest