LED Clock
It functions as a very pretty piece of functional art. However, it is missing a home since I do not have space where I live for it :( so it is staying con mis padres at the moment.
It is approximately 30" tall and about 30 lbs? (hard to tell since it is awkward to hold). This makes it difficult to mount to wall (I havn't tried yet). It actually stands on its own surprisingly well by balancing between two of the seconds rods.
Anyways! enjoy this fantastic piece of art and technology!
Here is video. You can see some ghosting and glitching. The ghosting can probably be solved with just using a slightly higher resistor? the glitches are just because some of the wires are loose. I took this video after a few months of this sitting in the cellar and didn't bother to go through the long debugging process of ensuring all proper connections...
Materials
Materials:
- 120 tubes 3" long (60 sec + 60 min) = 360" of tubing = 30 feet of 1" steel tubing (this is the hardest part to get just because you need so much)
- 24 tubes 2" long (24 hours) = 48" = 4 ft 3" diameter tubing (I used a broken table support for this)
- 100-200 ft of as thin of wire as you can find (magnet wire is a good option). Also, try to get black wire to blend in better.
-
144 LEDs
- 60 for the seconds (choose color A)
- 60 for the minutes (choose color B)
- 24 for the hours (choose color C)
- 24 resistors (100 ohms or close)
- Arduino MEGA (you could work to put it onto regular arduino but we need 24 I/O pins in this build)
- DS 1307 (found here)
Metalwork
Here are the metal-work steps:
Step 1: Cut the tubes.
you need to cut 144 three-inch tubes (1" diameter). I used a horizontal bandsaw with a block clamped down at the 3" mark to cut as quickly as possibly. While this step takes the most time, it isn't that challenging. I would not attempt this without a bandsaw or other power tool as there are a lot of cuts to make...
Step 2: Bend a Circle
To create a guide for when it comes to welding the tubes together, we want to make a circle out of a bent piece of steel rod (1/8" or 1/4" thick) (1" wide). The diameter of this circle is set to be 30" so we need to first cut a length of 30" x Pi = 94.25". Then you need to bend or roll the flat length into the curved circle. This is most easily accomplished in a roller (as I did) or you can take the hard, long, and less precise way of just bending it slowly by hand. It isn't too tough to bend, but it sure wont be as nicely bent as with a roller.
Step 3: Welding
I prefer MIG welding always because it is fast and easy. You can choose whatever welding method / technique you like though. Basically we are just going to make a ton of spot welds. Nothing heavy duty is needed (although you can heavily weld a couple if you want to hang it by them).
With that said, remember your safety!
I found it easiest to start with the minute's tubes. I welded all 60 tubes to the inside of the guide circle bar. Then you can choose to either do the seconds or the hours. I did seconds next, and lastly the hour tubes. For aesthetics, I spot welded (although I think I used an oxy-acetylene torch) a few small rods to the inside. They are completely not needed. The original idea was to mount the arduino to the center but I realized this would look ugly so I stuffed it at the bottom.
(it wouldn't be a bad idea to clean the metal off and de-burr it)
Circuit
The third picture basically is just me calculating how much space (as in the angle) each 1" tube takes up and thus what radius circle do I need to hold all the tubes. I also accounted for a little bit of spacing as well. This is how I came up with the 30" diameter.
The hour circuit is shown in the second picture. As you can see, the LEDs marked 1-24 are in use and the additional 6 LEDs (25-30) are not in use (there isn't physically anything in their position). The 6 pins shown on the right of picture 2 are the 6 pins needed from the arduino. These 6 pins control all 24 LEDs for the hour hand.
The chart at the top (in green) on the first picture shows the number of pins needed to control X LEDs using simple charlieplexing. As you can see, n pins can control (n2 - n) LEDs. So to control 24 LEDs we need 6 pins (as claimed earlier) and to control 60 LEDs we need 9 pins.
ignore some of the unnecessary info in green... and ignore the purple and blue... basically, we need 24 pins from the arduino (or whatever). This means we can't use an UNO or Due, rather, we need to use the larger Arduino MEGA which comes with 54 pins. It is a shame to waste all those extra pins, but so be it. You could also use an atmega or anything else, the code is fairly simple.
You will also need a DS1307 Real-time clock (as shown at adafruit) if you want the clock to remember the time after turning it off each time. Otherwise you have to manually set the time every time you start it running. This would mean going into the code each time.
The same circuit can be extended from to 6-pin version to the 9-pin version. The hard part comes with the physical wiring... I would recommend starting with the hour's wiring to get the rhythm before continuing to the more complicated rings.
Wiring I
I can point you in the right direction and I am glad to offer any advice and answer any questions posted in the comments. However, I firmly believe the best way to do this (resulting in the least errors) is to just try wiring it and that way see the patterns that dictate where each wire goes. This will end up being a lot more helpful than an instruction manual.
The pictures below may come in handy though, at least when starting out. The pictures on this page correspond to how to create each bank of LEDs for the minutes and seconds hands. I started with each LED by bending the shorter lead (-) into a sort of bracket and then ran a slightly curved piece of stiff metal (conductive) wire to connect all of these electrodes. The + leads (longer leads) of the LED were left pointing straight up (down in the picture).
Wiring II
these pictures show the hour wiring. It is confusing, I know. Post questions if you have them.
My best advise is to just wire it up and figure out which one is LED 1, 2, .... , 24 in the programming... it isn't too hard to figure out.
Wiring III
I separated the LEDs into chunks of 8 (marked in the picture by the duct tape on every 8th tube). This is needed for the charlieplexing circuit mentioned before. The first chunk of 8 is pin 1, the second is pin 2, etc... The first LED on the first chunk of 8 has a common chunk on pin 1 and a selecting wire leading to pin 2. The next one is also on chunk 1, but has selector pin 3... And once we get to chunk 2 (LED number 9 total), the first LED of this chunk has its selector pin equal to pin 1. THE NEXT LED HAS SELECTOR PIN 3, not 2, because we skip 2 since it is in chunk 2.... this continues on this way all the way around the circle.
The part to keep in mind is that every chunk skips over the selector number that is equal to the chunk number.
This can be very confusing as you get tired and prone to mistakes... it is a very long process. Solder along the way but be prepared to make corrections when debugging...
Code
A quick explanation of which pins go where... arduino pins 22-27 are the 6 pins for the hours, arduino pins 28-36 are the 9 for minutes, and 37-45 are the 9 for seconds.
The int arrays a[30] and b[30] together are the 2 dimensional array for the cathode and anode of each LED.
The int arrays c[72] and d[72] together are the arrays for minutes (and seconds since they use the same array). As you can see both arrays are shifted to align the time = 0 position to be at the top of the clock since I didn't put the first LEDs in the right spot when putting it together. You can keep shifting values left or right (just make sure to always to the same to both arrays c & d) until the minute / second hand at time = 0 is at the top.
You do not need to manually set the time since the RTC library does that upon initialization when you load up the sketch.
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
// 6 (hour) + 9 (min) + 9 (sec) = 26 pins needed using charlieplexing to control 144 LEDs on 3 seperate rings.
// 6 pins = used for hours
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
int a[30] = {22,23,24,25,26,27,22,23,24,25,26,27,22,23,24,25,26,27,22,23,24,25,26,27,22,23,24,25,26,27};
int b[30] = {27,27,27,27,27,26,26,26,26,26,25,25,25,25,25,24,24,24,24,24,23,23,23,23,23,22,22,22,22,22};
//can use up to 30 pins. so there are 6 extra positions open for use.
// 9 pins (x2) = used for both minutes and seconds(+9)
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
int c[72] = {32,31,30,29,28,36,35,34,33,32,31,30,29,28,36,35,34,33,32,31,30,29,28,36,35,34,33,32,31,30,29,28,33,32,31,30,29,28,36,35,34,33,32,31,30,29,28,36,35,34,33,32,31,30,29,28,36,35,34,33};
int d[72] = {33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,29,29,29,29,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32};
// can control up to 72 pins. so there are 12 extra positions open for use.
void setup()
{
Serial.begin(57600);
Wire.begin();
RTC.begin();
//giving the DS1307 board power (for Arduino MEGA)
//the other bins are wired to SCL and SDA lines on the arduino (for the MEGA they are pins 20 and 21) (for the Duemilanove they are on the analog pins, check the arduino website to read more).
pinMode(18, OUTPUT);
digitalWrite(18, LOW);
pinMode(19, OUTPUT);
digitalWrite(19, HIGH);
}
void loop()
{
DateTime now = RTC.now();
//hour
int timeHr = now.hour();
int modHr = timeHr % 24; // modulo 24
//resets each pin so that the pin is neither HIGH nor LOW (so LEDs dont stay on)
pinMode(22, INPUT);
pinMode(23, INPUT);
pinMode(24, INPUT);
pinMode(25, INPUT);
pinMode(26, INPUT);
pinMode(27, INPUT);
//the next several lines grab the position of the LED from the arrays a[] and b[] (cathode and anode) and set them to HIGH and LOW outputs for this loop.
pinMode(a[modHr], OUTPUT);
pinMode(b[modHr], OUTPUT);
digitalWrite(a[modHr],HIGH);
digitalWrite(b[modHr],LOW);
//minute
int timeMin = now.minute();
int modMin = timeMin % 60;
pinMode(28, INPUT);
pinMode(29, INPUT);
pinMode(30, INPUT);
pinMode(31, INPUT);
pinMode(32, INPUT);
pinMode(33, INPUT);
pinMode(34, INPUT);
pinMode(35, INPUT);
pinMode(36, INPUT);
pinMode(c[modMin], OUTPUT);
pinMode(d[modMin], OUTPUT);
digitalWrite(c[modMin],HIGH);
digitalWrite(d[modMin],LOW);
//second
int timeSec = now.second();
int modSec = timeSec % 60;
pinMode(37, INPUT);
pinMode(38, INPUT);
pinMode(39, INPUT);
pinMode(40, INPUT);
pinMode(41, INPUT);
pinMode(42, INPUT);
pinMode(43, INPUT);
pinMode(44, INPUT);
pinMode(45, INPUT);
pinMode((c[modSec] + 9), OUTPUT);
pinMode((d[modSec] + 9), OUTPUT);
digitalWrite((c[modSec] + 9),HIGH);
digitalWrite((d[modSec] + 9),LOW);
/*
pinMode(37, OUTPUT);
pinMode(38, OUTPUT);
pinMode(39, OUTPUT);
pinMode(40, OUTPUT);
pinMode(41, OUTPUT);
pinMode(42, OUTPUT);
pinMode(43, OUTPUT);
pinMode(44, OUTPUT);
pinMode(45, OUTPUT);
digitalWrite(37,LOW); //1
digitalWrite(38,LOW); //2
digitalWrite(39,LOW); //3
digitalWrite(40,LOW); //4
digitalWrite(41,LOW); //5
digitalWrite(42,LOW);
digitalWrite(43,LOW);
digitalWrite(44,LOW); //8@5 off
digitalWrite(45,HIGH);*/
}
Downloads
Plug and Play
I also attached a switch so that you could permanently keep it plugged in and just use the switch if you ever wanted to turn it off. (shown in the last picture on this step).
It is very visible at night and surprisingly visible in daylight (less so the green hour LED). I also frequently hear complaints about how you can't read the absolute time due to not having numbers, to which I will respond right now with why do you need to know the time down to the second? or within a couple minutes? If you are that obsessed with knowing precise time, you are probably well-trained by now to not trust a wall clock anyways! I have no trouble glancing at this clock and reading the time to the nearest 5 minutes easily. So I say it is very practical. Just don't let the 24-hour time confuse you :)
One last remark: I cannot stop thinking about gatling guns when I look at this...