Blue LED Cube: January 2011
This is exactly what it sounds like, an awesome flashing cube of LED's. After seeing a 512 LED cube on hackaday I decided that I needed one for myself and went right to ebay to find some cheap LED's. Although 512 LED's seems like a daunting number it only took one weekend to make the control circuit and construct the cube, the code and animations though took a few weeks, maybe coding isn't my thing. I will go through some of the steps and theory here and you can see the results in the video at the end.
The Finished Product
Before I started this project I had never heard of multiplexing, its basically a nice way of breaking up the control of a
large number of LED's and tricking the eyes into seeing it all happening simultaneously. In this case all you have to do is
load an image onto the bottom layer hold it there for say 5-10 milliseconds, turn it off and load an image onto the next layer
for 5-10 milliseconds etc etc, at this speed you will not be able to tell that each layer is being controlled separately.
Multiplexing reduced the number of LED's that need controlling at a single time from 512 to 64 LED's + 8 layers, this is
still more I/O's than most micro controllers so I found a nice chip that allows me to control as many LED's as a want with
only 3 I/O's.
The STP16CP LED sink driver receives a serial signal and can sink the cathode of 16 separate LED's to ground, the really nice thing about this chip is that you can run as many as you want in cascade to control say up to 64 LED's + 8 layers. I have included my schematic below, I used the suggested layout from the data sheet except I added a 10uF decoupling capacitor on the power inputs to keep them nice and quiet, the resistors are the current setting resistors I used some high wattage 1k resistors I had laying around. I have 4 chips to control the 64 LED's in each layer and another chip and 8 transistors to control the layers. These chips are designed to sink currents, not to supply them so you have to ensure that all the cathodes (negative leg) of the LED's in a column are connected and the anodes (positive legs) of all the LED's in each layer are joined together and supplied via the transistors.
I am currently using an old PC power supply to power my cube, I will probably never get around to making a more compact power supply but if you decide to make your own remember that this many LED's will draw a decent current, I measured the maximum current drawn from my cube and it was about 700mA that includes the power for the control circuit (this was with multiplexing so if you actually turned all the layers on at once it would be a lot more).
I have been receiving a lot of questions about parts so the parts I used are listed below. I get all my components from
Farnell who offer next day delivery in Australia or from Jaycar, not delivered but
usually keep a decent selection of passive and active components in stock. Now I'm not saying you need exactly these
components, the capacitors for one are rather expensive and an electrolytic capacitor would do a similar job, but this
is what I used and they obviously work.
- 5 x 1k 2W resistors (2W is overkill but I already had them at home) [element14 part# 1417017]
- 5 x 10uF 35V Tantalum Capacitors (35 V is overkill but I already had a few) [element14 part# 1457591]
- 8 x BD136 pnp transistors (the BD438 in the schematic should work just fine) [element14 part# 9956263]
- 5 x STP16CPS05MTR LED sink Driver [element14 part# 1551227]
- 9 x 8 pin header [jaycar part# HM3418]
- 512 LEDs of which ever colour tickles your fancy
As for the board and schematic those who are wondering how you get them, well you make them. I'm not an electrical engineer so my electronics knowledge is limited by what datasheets can tell me, if you read through the STP16CPS05 datasheethttp://www.farnell.com/datasheets/28788.pdf you will see that it gives all the information you need to make the schematic above even a suggested circuit application. I use eagleCad http://www.cadsoftusa.com/ to draw my schematics and layout the boards. Its easy and they offer a free version which is nice, there are tutorials on YouTube but really the only way to get the hang of it is try it out. To make the boards I use the toner transfer method google will throw about a thousand tutorials at you if you type it in, here is a simple one http://www.instructables.com/id/Cheap-and-Easy-Toner-Transfer-for-PCB-Making/.
Printed Circuit Board
I layed out the board using eagle, turns out I had to make it double sided to fit all the traces in, double sided boards are a bit tricky with the toner transfer method and I hate soldering vias but it didn't look too bad in the end, a few smudges on the top ground plane where the toner didn't stick and you can see a few wires on the bottom to fix a broken trace and a somehow floating block of my ground plane. If you want the eaglecad files I have uploaded them to my downloads section which you can access via the top menu, but remember these chips are tiny, although you may be able to get ones already soldered to breakout boards if you search hard enough.
Control Board Top
Control Board Bottom
I found the simplest part of the project constructing the cube, once I had a jig to hold each layer in position and got
into a routine it all came together relatively quickly. The first picture is of the first complete later of 64 LED's,
the second shows the anode layer in red and the 64 cathode legs in black which will be soldered to the next layer to
form the cathode columns. Each layer is held together along one axis using the LED's positive leg and on along the
other axis with 8 pieces of wire, the layers are then soldered to each other using each LED's negative legs, the final
cube is surprisingly rigid.
Once I finished the cube I wired it all up to do some testing before I made a timber box to hide all the wires and circuits, with a few coats of paint the final product came up looking pretty good I think, the most annoying part so far was getting all 64 of the slightly bent legs through the holes in the wooden box
I seem to get a lot of questions from people who don't seem to understand how the cube works as a system, I thought all the information was here, but knowing me I probably just write too much and people skip bits. So I have painted a picture which describes the layout of the cube and its system, hopefully it clears some things up.
The fist step in control is to figure out how to load data into the STP16CP chips, they have 3 inputs, clock (CLK), data (SDI) and latch (LE). Its pretty simple really you load the data on the data pin, keep the time with the clock pin and set the data which activates the outputs with the latch pin. I didnt find the timing diagrams provided in the data sheet completely obvious initially so ill try and explain it hopefully a bit clearer here. For example if you want to load the byte B11001110 = 0xCE into the first byte register in the first STP16 chip in the cascade the timing diagram below shows the required output for all 3 pins.
STP16 Timing Diagram
These chips can receive data at up to 50Mhz or something crazy (a little less in cascade) so for my outputs I just used 3 digital I/O's on my arduino board which runs at 16Mhz well below the theoretical maximum so no delays are required for the timing. Currently all the animations are calculated by c++ code I have written on my PC, my arduino converts the serial data sent from my PC to the 3 timed outputs required by the LED drivers. The arduino code below shows how easy it is to convert a byte. To send the instructions from my PC to my ardunio board I use a C++ serial library I wrote, you can see the code here.
Send a Byte to The Driver Board
The cascade works by pushing the data to the next byte register each time data is loaded into the first register, this means that the first byte you load will end up in the last byte register. Normally because I have 5 chips, each that have 2 byte registers I would load 10 bytes into the cascade before sending the latch command. The first byte corresponds to the layer command so will only ever have one bit set, the second byte is just zeros because nothing is connected to those pins and the next eight correspond to the image desired on that layer. What I didn't think of when laying out the board was that every second 8-pin header actually needed to be flipped around. You could fix this by soldering the wires on in opposite directions but I still hadn't thought of it by that time so i fixed it by flipping every second byte with the following code. You can see that some basic understanding of binary can be useful for this project, there are plenty of tutes on the Internet for this sort of thing.
Flip a Byte
To animate the cube I first write all the animations onto a 8x8x8 array in C++ on my PC, then I split up the array into
64 bytes (8 bytes per layer) and send the 64 bytes to my arduino which converts them and loads them onto the cube layer
by layer. This might mean more computationally demanding code but it makes it a lot easier to visualise the animations
as I write them, if I want to turn on the LED at (x,y,z) = (5,3,0) I just set cubeArray = 1.
As I was waiting for my LED's in the mail I started writing and plotting animations in matlab to try and get an idea of how I was going to animate this thing. Matlab is very handy for this sort of thing if a bit slow when it comes to plotting this way, you can see in the short video below that it can help visualise things when you don't have a physical platform.
Animation Using Maths
Probably the easiest to implement and maybe even the nicest look animations are those based on surface functions such as the wave function in the matlab simulation above. Here I will go through the animation of a 3D sine wave which looks pretty cool on the cube. I start with the function below which plots the surface shown in the figure, to get this onto my cube I need to map the function onto my cube and discretise the continuous function.
3D Sine Function
Because my array representing my cube has a range from 0-7 in each axis you need to map the values of X and Y to a range centered at zero to get a symmetrical result which you can the map back onto the range 0-7 to get the Z position, the simple c++ function below will map a value in a range onto the desired range.
Map Number to New Range
So to plot the function onto the 8x8x8 array I loop through all 64 X and Y positions, map these values to a range between -PI and PI, then calculate the Z position which will be somewhere in the range -1 to 1. Then I map the Z result back to the range 0-7 and round it off to get a discrete position and set the LED at [X,Y,Z] to on. I have included my code below where size = 8, there are probably other ways of getting the same result but this made sense to me. Of course this only plots one instance of the sine animation, to actually make it move I repeat this code clearing the array at each instance and continuously incrementing the phase between 0 and 2PI.
Here is a video of the 3D sine animation on the cube unfortunately I still haven't found a decent camera to film this with, so the quality is not excellent.
3D Sine Animation
There are plenty of cool looking 3D equations out there, a few more I have used that turned out fairly well are a spiral/helix, and the waves function like the one I showed in the matlab simulation above, their equations below can be implemented in the same way as the 3D sine wave.
3D Wave Function
Generating the Bytes
So now that I have a 3D array filled with an instance of an animation it needs to be broken up into something to send to my arduino. 8 is such a nice number for this sort of thing because there are 8 bits in a byte, so I can separate the array into 64 bytes which makes 512 bits each representing an LED. The image below shows how I split up one layer of the cube, each byte is stored in an array cubeChars. The code I have written for this is also included below.
A Layer of Bytes
Byte Generation Code
The Finished Cube
Here is a video of some of the animations I have written, I tried to make them all flow together nicely which probably wouldn't have taken so long if I didn't sit here staring into it all the time.. I'm still using my dodgy camera but until I find something better.. Enjoy..
Interactive LED Cube
Once I finished my cube I decided that the next step was to make some interactive animations, to do this I chose to learn how to write win32 applications in C. Seemed like it could be a useful skill to have. I am still working on the software but I have uploaded V1.0 which has playable snake, interactive mouse tracking, keyboard input and a digital clock animation along with several standard non-interactive animations. Remember this is my first win32 application which I wrote completely from scratch using the visualc++ IDE, if it is dodgy its because I made a lot of it up as I went along. You can download the application or the source code from the downloads section in the top menu. If you want to learn how to write windows applications this is the tutorial I used, it has some really good explanations and examples http://www.winprog.org/tutorial/.
My PC software and animations are great and all, but it seemed like a good chalange to get this thing running completely off the Arduino.
So here it is, no PC required, just upload my MK2 code and give it some power. The Arduino is a bit limited of course so not all of my animations have been ported, but it was worth the work.
Oh and one last thing if you get yourself a DS1307 real time clock module for your Arduino you can use the cube as your bed side clock! I will upload a video soon.
If you are getting load of errors when you try and compile the code just change every instance of WProgram.h to Arduino.h.
I have been working on a new and improved RGB LED cube over the last few months, I probably will not get it up on my site before March 2012 so here is a little teaser. All multiplexing, Bit Angle Modulation for colour effects and all of the animations are handled by my chipKIT UNO, all animations are calculated on the fly not stored on an SD card, no PC required. I have also written some linux software to extract video data from pretty much any movie file which makes for some pretty cool animations (ok this part requires a computer). Check out how I made it here!