Réaliser un beau cube de 512 Leds

8x8x8 LED Cube

blue LED
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. 


Control Circuit

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

Control Circuit Schematic

circuit schematic

Parts List

I have been receiving a lot of questions about parts so the parts I used are listed below. I get all my components from http://au.element14.com who offer next day delivery in Australia or from http://www.jaycar.com.au/, 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]
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/.

PCB

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

controller board top

Control Board Bottom

COntroller board bottom

CUBE

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.

First Complete Layer

first complete layer

LED Cube

finished LED cube

Finished Product

final product

Control

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.

STP16CP Timing Diagram

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 BYTE CODE

void CUBE::send_data(char byte_to_send){
for(int i = 0; i < 8; i++){
if(byte_to_send & 0x01<<i){
digitalWrite(SDI, HIGH);
}
digitalWrite(CLK, HIGH);
digitalWrite(SDI,LOW);
digitalWrite(CLK,LOW);
}
}

LATCH CODE

void CUBE::latch(void){
digitalWrite(LE,HIGH);
digitalWrite(LE,LOW);
}

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 Code

char CUBE::flip(char input){
char output = 0x00;
for(int i = 7; i >= 0; i--){
if(input & 0x01 << i){
output |= 0x01 << (7 - i);
}
}
return output;
}

Animations

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[5][3][0] = 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.

Wave Animation Simulated in Matlab


Animations Using Functions

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 and Surface

equation for a 3d sine wave
mesh grid of 3D sine 

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 Code

double cube::map(double in, double inMin, double inMax, double outMin, double outMax){
double out;
out = (in-inMin)/(inMax-inMin)*(outMax-outMin) + outMin;
return out;
}
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.

Sine Code

for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
Z = sin(phase + sqrt(pow(map(x,0,size-1,-PI,PI),2) + pow(map(y,0,size-1,-PI,PI),2)));
Z = round(map(Z,-1,1,0,size-1));
cubeArray[x][y][(int)Z] = 1;
}
}
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.

Equation of a Spiral/Helix

equation of a apiral

3D waves Equation

3D wave equation 

Generate 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 breakdown

Generate Chars Code

void cube::genChars(void){
int i = 0;
memset(cubeChars, 0x00, sizeof(cubeChars));
for(int z = 0; z < size; z++){
for(int y = 0; y < size; y++){
for(int x = 0; x << size; x++){
if(cubeArray[x][y][z] == 1){
cubeChars[i] |= 0x01<<((size-1)-x);
}
}
i++;
}
}
}

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..

The End Results


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/.

Interactive Cube


Aucun commentaire:

Enregistrer un commentaire