Introduction: LED Cube Display
In this project, you will build an 8x8x8 LED cube as a display. After building the cube and learning the code basics, you will be able to write your own display animations. It is a great visual for scientific purposes and it will be a nice decorative addition to your room! During the process of the cube-building, you will acquire a whole slew of basic electronics skills, which paves the way for more complex projects in the future.
This is my individual project for the Electronics course, and it took about five weeks. I spent 12 hours on this project per week, and I had access to the parts and tools typically found in a college electronics lab. It might also be good to know that, even though the workload is not a piece of cake, no hands-on expertise is required. Instead, you'll gain much experience and learn from your own mistakes along the way.
Disclaimer: I borrowed the design and the code from Kevin Darrah (http://www.kevindarrah.com/?cat=99) who built an 8x8x8 RGB cube (thus tripling the work!). The waveform display is my own work. I strongly recommend watching all his LED videos before you start the project! They are extremely helpful in understanding how everything works, which is crucial for this complicated project! I gave brief explanations about the circuitry and the general architecture when I discuss the circuit connections and the code, so feel free to jump to that part first to gain a theoretical understanding:)
Step 1: Part List
- single-color DIFFUSED LEDs x512 with ~30 spares (You might notice that I used three colors myself. This is originally designed to help reflect the waveform amplitude (e.g. red means higher amplitude), but I didn't solder the slices correctly, so eventually I just treated them as the same. If you are still interested in making color variations in the vertical direction, please read notes on the vertical slices step:))
- PC boards, medium x7 and small x2 (These are the ones available in my lab, but please feel free to adjust the size depending on what's readily available to you! Please read the circuitry section for your reference. I found that for beginners, PCBs without any connected strips are more accommodating, mainly because you can add and cut connections at will. De-soldering can be tricky!)
- NPN 2N3904 transistors x72
- 1k resistors x 150
- 100 Ohm resistors x 72
- P-channel MOSFETs IRF9Z34 x8 plus 8 clip-on heat sinks
- 100 micro Farads capacitors x8
- 74HC595 shift registers x9
- Arduino Uno + screw shield (I used a proto-screwshield R3 kit)
- Wire with insulation of 8 colors (I highly recommend using different colors! You will have a lot of wires right next to each other, and the colors really help when we check the circuit.)
- 5V 2.8A power supply (as long as your power supply current limit is higher than 64*(current through 1 LED), it should work fine:))
- wire terminals
- Molex headers with 8 pins and 6 pins.
- Molex wire housing with 8-pins and 6-pins (the quantity of these will be different depending on your PCB size and your circuit design, so please read the whole Instructable (particularly the circuitry part) before deciding on the number you need:))
- Bare copper wire (to be on the safe side, prepare 50m of this)
- Large wood board (roughly 9 inch on each side)
- 12 inch wooden skewers (optional; if you find a way to make straight wires, you don't need this)
- scotch tape
- long nails x16
- Soldering iron
- wire cutter
- glue gun (optional; if you find a way to make straight wires, you don't need this)
- heat sink clamps x2 (alligator clips work as well)
- wire stripper
Step 2: Making LED Rows
First and foremost, test all the LEDs! I breadboarded up a circuit with an LED and an 100 Ohm resistor. I then tested one LED at a time and added that in parallel with the other LED. We want to discard 1) broken LEDs, 2) LEDs with the anode and the cathode backwards (you don't want to just "remember" which one has got it flipped!) 3) dimmer LEDs.
Next, we made the wooden jig, which is also my final mount for the cube. Drill a 8x8 grid with 1 inch between the center of the holes. Select drill bits with a diameter just above the diameter of your LEDs, such that they can fit into the holes and still stay straight. We nailed extra wooden strips to the perimeter, which kept the board surface flat (we used plywood for the board, so it's got a fair bit of flex to it). In addition, this elevated the areas with the holes such that the LEDs can poke through the holes. Select one side and put two long nails on the same line as the centers of the holes. We'll tie the wires on these nails.
We can now start to make LED rows! I didn't find an effective way to make straight wires, so I only un-kinked the wires using a wooden block. Place the wire across the edge of the block; hold the wire down with your thumb on one side of the block and pull the wire through; the edge of the block will un-kink the wire. I recommend putting on a glove to protect your thumb:(
Place 8 LEDs into this row with the long "leg", the anode, facing one direction. We are going to solder them onto the wire. Note that the plane formed by the anode leg and the cathode leg should be perpendicular to the line of the wire, and the cathode leg should be away from the wire. Tie the wire on a nail and pull it to go across the LEDs until it's straight and taut. Tie it on the other nail. Adjust the wire height (I noticed a small flat area on the LED leg, and I adjusted the wire such that it's touching this area for all LEDs). This height is arbitrary, but please be consistent. Keep in mind: 1) the level height difference in your cube is going to be roughly 1 inch (so the wires can't be too high); 2) the LEDs might break under the heat of the soldering iron (so the wires can't be too low) (though I haven't personally experienced any issue from this). Now your wire should be touching the long leg of the all LEDs, forming a cross. Solder the wire and the anode leads and trim the leads afterwards.
In this project, I experimented with two different solder joint contact configuration. One is the cross contact described above, and the other is bending the LED leg such that the contacting wires are parallel. Theoretically, the parallel contact joints are more stress-resistant, but considering how light the LEDs are, the cross joints probably aren't that detrimental. You will gain a lot of practice soldering the wire and LED legs, so feel free to experiment with different techniques! I used a flat tip soldering iron, and I personally think it offers better control over the solder blobs and a larger heat contact surface area.
After you do the soldering, use the breadboard for the LED-checking to check the connections(important). Clamp the positive lead to the wire and sweep the negative lead through the short LED legs. They should all light up! After we check that they are all fine, gently push the LEDs from below the board to dislocate them and slide the wire up the nails. You can trim away the looped ends, but definitely save some length!
What if my LED doesn't light up?
First things you might check is whether you got the cathode and the anode flipped. Then try clipping the positive lead to the LED leg instead of the whole wire. If your LED lights up that way, you can re-solder the LED. If your LED still doesn't light up, replace it with another.
We need to make 64 such LED rows:)
Step 3: Soldering Vertical Slices
As a preview, all the anodes in each layer are connected, and all cathodes in each vertical column are connected. Now we need to make the vertical slices. Remember the two nails we put into the board to tie wires? Now put in 14 more of those in a similar way:) (Caution: file the nail tips well! You will be pressing your fingers around those tips a lot.)
Now place 8 LED rows onto the board and make sure that their legs are facing the same direction. Note that the wires should be parallel to the rows of nails! Push down on the LEDs such that they are all at the same height. If some of the LEDs keep popping out (perhaps due to the curvature in your wire), scotch-tape down the ends to the board. Now, run wires across the nails as before. I could only eyeball the wires to be approximately on the same height, but that's ok because what you really care about is that the LEDs are at the same height.
Solder the cathode leads onto the wires. You'll notice that here I used the parallel-contact soldering configuration, and I did find that more solid and better looking than the cross joints, but it was more time consuming, because you need to 1) bend the wires with pliers; 2) make sure that the bent section touches the main wire; 3) bend that section to be at the right height, because your soldering iron will come in at an angle and you need the iron to touch both wires at the same time.
If you want to use different colors at different layers....
Make sure that each of your slices reflects the color scheme. For example, if I wanted the top three layers to be yellow LEDs, the middle two to be orange LEDs and the bottom three to be red LEDs, I'll place three yellow LED columns, two orange ones and three red ones in that order. Make sure that your color order and the LED orientation is consistent for all eight slices!
Use the breadboard setup to test all the LEDs in each slice. It is definitely easier to re-solder here when your LEDs are secured rather than in the middle of the air.
If your wires aren't straight on themselves, DON'T pull the slice from the nails just yet! Read the next step.
If you already have straight wires, push the LEDs gently from below and slide the slice from the nails. Don't trim the ends just yet:)
Step 4: Supporting the Vertical Slices
If your wires have some curvature to them, as mine did, we can fix them to be on a flat plane by adding rigid support along the perimeter. I chose 12 inch wooden skewers because they are readily available on Amazon. I glued the skewers on the perimeter and added small pieces in the corners to strengthen the frame. See photos for details. Note that only two skewers are completely attached to the wires, and the other two skewers are above the whole grid. I recommend testing the frame without the corners pieces first. I found that the extra short sticks got in the way of the LEDs when I was stacking the slices up, and the glue joints are probably strong enough to hold the LED grid anyway. If the grid still bulges a little bit, press down on the two un-glued sides and glue the wires to the skewers at several points. Don't trim away the loose ends just yet! In particular, keep a fair bit of length of skewers on the side that's going to be at the bottom of the cube, so that we can keep the LEDs off the floor.
Step 5: Assembling the Cube
Now that we have the slices, we can make the cube! I found it easier to stack them up rather than sticking vertical slices together, but if you have a collaborator, feel free to improvise! To avoid mistakes, first glue the slices to another set of skewers and add connection wires later. As you see in the photo, I glued four skewers at the corners to help align and support the layers. Keep in mind that, ideally, the layers are 1 inch apart. I found that my LEDs rested on the wooden frame from the previous layer, so I don't have to hold them up while gluing them, but if your slices rest at a lower height, a collaborator or some wood strips (see photo) would help. Before you glue the slices, make sure that their orientation is correct! You want the cathode and anode ends to point in consistent directions. Also check the orientation of the LEDs.
It's VERY important to make sure the LEDs light up when you stack each layer! It would be virtually impossible to get to the center of the cube once you have it all assembled.
You might notice that my wood frames don't necessarily align with each other, but if you look at the LEDs, they align better! Since we'll be seeing this cube in a dark environment, misalignment of the frame is acceptable.
Next, use additional wires to solder the anode leads on the same level together. If you find it difficult to keep the wires there, try "weaving" the wire through the leads (alternate the way the wire crosses the leads, between from above to from below). It's ok if these wires aren't perfectly straight, because the main LED structure is already set, and the side wires aren't very visible once we turn the LEDs on.
Just to be safe (we'd rather err on the cautious side, yes?), test all the LEDs again. At this point, if one of the lights in the center of the cube doesn't light up, I'm not sure if there's a simple way to address that:( However, if you were meticulous about checking the LEDs when you stack up the layers, the LEDs should still be fine.
Now we can trim away the wire excess on all except the bottom side. Now we can temporarily put the cube away! Congratulations! Now we are more than half way there:)
Step 6: Circuit Connections
Please read the pdf schematics before arranging circuit elements on the PC boards. This schematic is for the RGB cube by Kevin Darrah, and since our cube has single colored LEDs, our workload is actually only a third of that (we have a third of the cathode controls, specifically). I strongly recommend putting all the circuit elements onto the PCBs to test out the spacing first. Give yourself more room to work with, especially for the shift register boards and the anode control boards. Then dump the circuit components out and only solder a few at a time, since it's less difficult to solder without so many circuit component legs getting in the way.
anode and cathode circuits
Our circuit design is such that when the inputs to the anode circuitry and the cathode circuitry are both 5V (or HIGH), the LED is turned on. Let's first go through the anode circuitry. When the input is HIGH, the transistor quickly becomes saturated, and the collector voltage drops to near 0, which means the Gate of the MOSFET is pulled to LOW. Since the MOSFET Source is connected to 5V, a LOW in the Gate means that Drain voltage is set to HIGH. The capacitor across the Source helps keeping the system stable.
When the cathode control input is HIGH, the transistor is again saturated and the collector voltage goes to 0V. The collector terminal connects to the LED through a current limiting resistor. You can choose the current limiting resistor based on your LED properties. Since I'm using red, orange and yellow LEDs, I used 100 Ohms. We see that now the positive side of the LED is raised high and the negative side pulled low, and the LED lights up.
Since we have 64 cathodes leads (each column) and 8 anode leads (each layer), we need 64 sets of the cathode control and 8 sets of the anode control. I recommend that complete sets of 8 controls are on the same board, since each shift register connects to 8 controls, and it seems more organized if the 8 connection wires go to the same place. Be careful not to overcrowd the boards! We are going to run lots of wires so make sure to give yourself enough space! Solder all the components to the board. One trick to increase your work surface stability is to solder on components with the same height (e.g. solder the transistors after soldering all the resistors to avoid the resistors falling out). For each set of 8 cathode control circuit, make sure to solder one 8-pin header which outputs data to the LED cube.
It's not apparent from the schematics, but wherever there's a transistor, we need to connect it to GND and 5V.
shift register circuits
The shift registers are connected to each other via 6 wires. They are connected in parallel for 5V, GND, CLOCK, LATCH and BLANK, and in series for DATA. When you connect the wires, make sure that the cathode shift registers are at the end of the sequence, because the DATA always goes to the very end of the serial line. Basically, the Arduino sends out a string of binary code that flows down the DATA line connection. The binary code then gets parceled into 8 bits per shift register. The 8 shift register terminals are then connected to a set of 8 cathode/anode controls. The 5V powers the entire cube, and since we have a maximum of 64 LEDs lit up at the same time, make sure that the total current doesn't exceed your power source limit. The other pins basically control when the data gets into the shift registers and when the data are released to the circuit controls from the shift registers. Make sure that each shift register has its own 8-pin header and each shift register board (except for the last one) has a 6-pin header through which the 5V, GND, CLOCK, LATCH, BLANK and DATA wire can go to the next shift register board.
The circuitry at the Arduino is very simple. Basically, we have 6 wires coming out of the Arduino (5V, GND, CLOCK, LATCH, BLANK and DATA). Make sure that your GND lead is connected to the GND of the Arduino (In fact, all the GND in this project should be connected), but that your 5V lead is not! Note that the Arduino in Darrah's schematic actually shows the terminals of the ATMEGA chip. See one of the images attached for the corresponding terminals between the chip and the Arduino.
We used a screwshield to avoid directly running wires into the Arduino. The parts that you need to solder onto the screwshield are the stacking header pins for the digital ports, 1 6-pin header and 1 2-port terminal block. You can add another row of stacking header pins on the other side for balance. (Note that the blue terminal blocks shown in the pictures don't actually do anything). Solder according to schematics. Important note: just to be safe, connect the 5V terminal on the 6-pin header to the 5V of the power source (which is the green terminal block), NOT the 5V of the Arduino. This way, your Arduino is powered by your computer, and all the 5V in your circuit is supplied by the power source. However, do connect all the GNDs together. You might tell from the picture that I solder the GND pin of the 6-pin header and the GND pin of the terminal block onto the GND strip on the screwshield.
While I don't know ways to check the shift register circuits, we can and should check the anode and cathode control circuit using a breadboard. See the photos for the details. Basically, we connect the board inputs to all be 5V. Then we can use a multimeter to check the output voltages. We found that the output voltage from the anode controls is only about 4V, but that is an expected consequence from the MOSFET.
- Don't skimp on the length of your connection wires between the boards! You will have many boards and lots of wires, and it would be clearer and easier for trouble shooting if the boards are well-separated.
- Use different colors to differentiate which wire is which. This is very important especially given how many wires you would need. We then put these wires in the wire housing in a fixed sequence. Use a good crimper to make secure wire terminals.
- Be consistent with the use of headers and the wire housing! In my project, for a certain board, all the inputs come from wire housings and the outputs go out through the headers.
- Because the header terminals are quite close together, be cautious that you don't solder the wires together, especially if you are relatively inexperienced in soldering like me! A trick that I found helpful was to push down on the wire with the soldering iron to melt the solder, then use pliers to clamp the strands in the wire together and push the wire closer to the header terminal. Move away the soldering iron and the solder joint should cool down and retain its shape very soon.
Step 7: Mounting the Cube
Instead of threading the rigid cathode leads through the 64 holes, which is quite difficult in practice, we can solder the wires to the leads first and then pull the wires through the holes. To allow the wires to come out from underneath the mounting platform, drill 9 holes on the side of the mount (8 for the cathode and 1 for the anode).
Firstly, trim the skewers to be at approximately the same length. Cut the cathode leads such that they are almost at the same height as the skewers. Now bend the lead to form a little hook using pliers. Strip about half an inch of your wire and bend the wire too. Hook the lead and the wire together and close the hooks with pliers. This offers good contact between the wire and the lead, and it frees up your hands for the soldering. Make sure to put a heat sink clamp before the nearest LED solder joint such that that solder joint doesn't come off from the new heat. If you don't have heat sink clamps, alligator clamps work too.
It's good practice to check the connections (I measured the resistance of the solder joint) after you finish soldering each layer, though I have found that the "hook" method gives really strong solder joints.
Now thread the wires through the holes. Gently tug on the wires and push the mounting platform to be in contact with the skewers. Thread each set of 8 wires through one hole on the side of the mounting platform and secure the bundle with a piece of electric tape. Since the four sides of the cube are equivalent, it doesn't matter along which side your group the wires. I suggest pre-making the wire terminals on these, such that you can quickly assemble the wire housing.
For the anode connections, solder one wire onto each level and pass that wire out from one of the holes. You will need two heat sink clamps to prevent neighbor solder joint from melting.
After you mount the cube, test each LED again to make sure that they are ok.
Don't skimp on the wire length! I think my wires are easily 12 inches long, but they still prove to be a bit shorter.
Now you are ready to connect everything and run the cube!
Step 8: The Code and Multiplexing
Due to the short project time, I borrowed Darrah's code and only made minor changes to it. I'm attaching the version that I used. He made excellent comments to his code, and I recommend reading through them to get a better understanding of how it actually works. Here I'll describe two key features of his code, the multiplexing and the bit angle modulation.
All the LED cube projects that I read about make use of multiplexing, and this is the technique that allows us to control individual light. With multiplexing, only one layer of the LEDs are lit up at one time. However, since the layers are cycled through with a very high frequency, the image "stays" in our vision for a while, and we think that the light is still there. In the software, we pull one layer to HIGH at one time and all the other layers to LOW, so only the LEDs in this layer can light up. To determine just which ones do light up, we used the shift registers to control which of the 64 cathodes are pulled HIGH. Before lighting up the next layer, we set the anode of this layer to LOW such that no lights in this layer can light up. Then we pull the anode on the next layer to HIGH.
Bit Angle Modulation
The BAM technique allows us to control the brightness of each LED on a scale between 0 and 15. If you don't need the brightness change, you don't need to implement this. Basically, we have a four bit control, and this control corresponds to 15 cycles of going from the bottom layer to the top layer (remember that for multiplexing, we are lighting up each layer at a time?). If we write 1 to the first bit, this one LED turns on when we cycle through the layers for the first time. If we write 1 to the second bit, this one LED turns on for the next two cycles. The 3rd bit corresponds to the next 4 cycles, and the fourth corresponds to the next 8 cycles (so we have 15 cycles in a complete set). Say, we want to set the LED to 1/3 of its full brightness, which is 5/15. To accomplish this, we write 1 to the first and the third bit and 0 to the other two so that the LED turns on for the 1st cycle, off for the next two, on for the next four and off for the next 8. Since we are cycling through this so fast, our vision "averages" the brightness, and we get 1/3 of the full brightness.
LED cube as a display for wavefunctions?
One possibility that we thought about at the start of this project was to use this display to show wavefunctions of particles in a square box. I did write a method in the Arduino code that plots the ground state and the first excited state, but it turns out that the resolution isn't quite adequate. The ground state seems fine, but the first excited state requires some interpretation. However, if you squint, you can tell that the function looks like one bump when when you look at it from one direction, and it looks like a full sine wave cycle if you look from the other direction. This is what the wavefunction amplitude should look like! Since even the first excited state requires some hindsight interpretation, I didn't code for other more complicated ones.
Step 9: Test Runs!
Congratulations for completing the cube! Now try writing your own display function and share your work with families and friends:)
After your cube is functioning correctly, tape the backside of the PCBs with non-conducting tape, since the connections are all exposed now and they might short each other.