8x8x8 multiplexed LED cube with an Arduino Mega 2560

Thank you again for your help, guys!

I'm thinking and thinking an thinking about which approach to take, but it seems that the more I know, the more confused I get :)

I must admit, the solution that appeals to me most at this time is to have 8 separate, unconnected layers, each driven by a MAX7219. It seems that the current consumption is not so bad after all and I'm hoping that the ones I can find on ebay (10 pcs for 5$) will do the job. I would not divide the LEDs into 8 layers the conventional way though. Instead of having the usual 8 horizontal layers, I'd have 8 vertical layers. This has several advantages: 1. Having 8 layers driven each by a MAX7219 requires 8x16 wires. Half of these would be connected to the layers directly from the bottom of the cube (because the layers would be placed such way that half of the required wires would face the bottom). This means that only 64 wires would be visible. These could enter the cube from the back of it (the side which is away from the viewer). Could still be messy... 2. By having these vertical plane layers, the weight of each layer would stand on the bottom 8 LEDs, so I would have to add just a few non-conducting sticks to strengthen the cube, maybe just at the top and around the middle, not everywhere. I'm not sure if this would look nice because the cube would be more transparent or it would look weird...

I guess the main reason why I'm trying to convince myself that the MAX7219-based solution is best is because it's the simplest from more than one perspective: A. Less components to solder in the circuit. B. Takes care of LED currents and even can be used to set brightness from software easily. C. The software does not need to be aware of the multiplexing, the Max chips do it themselves.

Searching the Internet I have found that somebody has actually pulled it off with this Max7219-based solution applied to a 8x8x8 LED cube (http://hackedgadgets.com/2011/09/02/8x8x8-led-cube-powered-by-an-arduino/). Unfortunately, I must say that the result is not nice at all. I mean, I do respect his work, but let's face it, the usual LED cubes that we see are much more better looking. Those wooden sticks at the corners of the cube block the vision a lot and those wires at the back are just plain ugly. I'd hate to turn up with a result like that after who knows how many hours of work.

I've never thought it would be so hard to build a LED cube. There are solutions for every problem related to it, but none of the solutions is "perfect". You can only get some benefits by sacrificing others... I'll try to think of solutions to go for the MAX7219-based solution and to get rid of the ugly wires and to solve the problem of non-conducting sticks between the layers. As much as I realize that most of the cube out there don't use this solution because of the disadvantages I have just enumerated, I don't dare to try the other solution. It just has too much room for error both in building the circuit and in the software part which gets more complicated by having to implement multiplexing. Also it's less foolproof. If the software messes up the multiplexing and lights up all the 512 LEDs, I don't know what's going to happen...

Like I said, the more I think of it, the scarier it gets... :)

Back to the TPIC6B595… CrossRoads, you laid it out so nicely for me, I just hate to waste that information, so I’m back to it again :slight_smile: Looking at the diagram, the following additional questions have come up:

  1. Should all GNDs be connected together (The GND of the Arduino, the GDN of the TPIC6B595s, etc.)?
  2. What kind of resistors should be used?
  3. What kind of capacitors should be used?
  4. You recommended NDP6020P MOSFETS for the transistors. In their datasheet the leggs of the NDP6020P are marked G,D,S. Which of these leggs go where in the diagram?
  5. You wrote that if the software multiplexing turned each layer on for 4ms, it would lead to a refresh rate of 30 fps. Do you think that’s good enough for the human eye?
  6. You wrote that dimming could be achieved by connecting to PWM pins on the Arduino. But connecting what to the PWM pins?

Sorry if I’m asking the obvious again…

"If the software messes up the multiplexing and lights up all the 512 LEDs, I don't know what's going to happen..." Nothing. Any COTS switching power supply will just shutdown as it sees an overcurrent situation occurring, same as if you shorted the output.

Your latest questions: Resistors = inexpensive resistors, 1/8W, carbon composition. Value will depend on the LED color & the current you want to put thru them. If have a 5V source, and the anode transistor has 0.45V across it, and the cathode shif register has 0.25V across it, that leaves the remaining voltage across the LED and the resistor. For and LED with Vf of 3.2V way, and using 20mA as the current, then: (5V - .45 - .2v - 3.2)/.02 = 55 ohm. 56 ohm is a standard value.

For the transistors, the base/gate resistor from the shift register is probably not needed (no need to limit current into the shift register, that will be set by the pullup resistor), and the pullup resistor can be smallish, say 220 ohm.

Caps are just 16/25/50V 0.1uF caps. I use these a lot http://www.dipmicro.com/store/C5K10-50

P-channel MOSFET - Gate connects to the shift register Source connects to +5 Drain connects to the LEDs (odd naming, I know).

30Hz - Movies were only 24 Hz for the longest time, and TV was 30 Hz. Good enough?

PWM connected to OE/ on the shift registers could be used for dimming. I would connect to the cathode shift registers where there is less current flow.

You are making too much of the "multiplexing complexity" I think.

// some stuff you need anyway
# include
unsigned long currentmillis();  // millis() and micros() are type unsigned long, 0x00000000 to 0xFFFFFFFF
unsigned long previousmillis();
unsigned long duration = 4;  // time in mS to display each digit
// declare other variables, and 2 arrays, one to hold the anode bit selection, one to hold the 64 bytes of the array

void setup(){
// do all the setup stuff, pinModes & stuff.

void loop(){
// start the multiplexing:
currentmillis = millis();  // capture the "time"
if ( (currentmillis - previousmillis)>=duration){  // 4 mS gone by yet?
previousmillis = previousmillis  + duration;  // set for next time check

x=x+1;  // break down anode for:next loop so it can run within the time check
if (x==8){
x=0;  // reset  after passing 7
// turn off existing anode (see note below)
digitalWrite(anodeSS, LOW);
SPI.transfer(0xFF);  // all 1s so no MOSFET is on
digitalWrite(anodeSS, HIGH);

// set up cathodes
digitalWrite (cathodeSS, LOW);
for (y=0; y<8; y=y+1){
SPI.transfer(dataArray[(x*8)+y]); // so 0-7, then 8-15, 16-23, etc., up to 55-63
// (perhaps ditch earlier anode write & pull later one back to here, so all shift registers are updated together with one SS pin?)

digitalWrite (cathodeSS, HIGH);

// now turn on one anode (see note above)
digitalWrite(anodeSS, LOW);
SPI.transfer(anodeArray[x]);  // Array holds B00000001,  B00000010,  B00000100, B00001000, B00010000, B00100000, B0100000, B10000000
digitalWrite(anodeSS, HIGH);  // with high = output pulled low

} // end time check

// do other stuff if desired while waiting for next time check, like receive serial data, update dataArray contents, etc
} // end void loop

This may need a little tweaking, but that's basically it. I used seperate SS for the Anode vs the Cathodes, it may be that you can string them all together with one SS, have to play some and see which looks better.

Yes, all GNDs get connected.

CrossRoads, doesn't your circuit require 16 wires per 64 LEDs? So the number of wires in the cube is the same as using the MAX7219? Or have I misread it?

The only way I can think of reducing the required number of wires to less than 16 is to use Charliplexing:


However that is quite complex. Also you still need 9 wires to control 64 LEDs (only a small saving).

For n pins, you can have up to n(n-1) LEDs in the matrix. Any LED can be lit by applying 5 V and 0 V to its corresponding pins and setting all of the other pins connected to the matrix to input mode.

I think you are misreading the partial schematic. Each common anode layer needs 1 wire. The common cathodes need 64 wires, 1 per column, usually soldered to the PCB that makes the base of the cube. 72 wires total. Vs 8 x 16 wires = 128, and connectivity not built into the array either. See the video that was posted in Reply #21.

Wish I had way more hours in a day to build one of these up. I'd go for 9x9, have read having the center LED to pivot things around makes it look neater. My 12-shift register board could drive it, be a bit of a software PITA spreading 81 bits + 9 anode control bits across 12 8-bit registers (96 bits).

CrossRoads, thanks again! :) Yeah, I guess I was making too big of a fuss about the software multiplexing, it's not the end of the world after all :)

One last "dumb" question: You mentioned some pull-up resistors which should be 220 Ohm. Which one are those in the diagram and what is their role?

I think I'm going to create my cube based on this diagram and based on your explanations. But I'll start with a 5x5x5 one. It's just too complex to aim for the big rabbit from start...

I looked for TPIC6B595 on eBay and found TPIC6B595N only. I guess it's the same...

The pullups go on the Gate of the MOSFET (or, the Base of the PNP, as currently drawn).

Start with 5x5, leave room to expand it to 8x8, need to use whole bytes anyway…

TPIC6B595N, N is the package type.

tpic6b595 open drain shift register.pdf (150 KB)

CrossRoads: The common cathodes need 64 wires, 1 per column, usually soldered to the PCB that makes the base of the cube. 72 wires total. Vs 8 x 16 wires = 128

Ach, you hardware guys always come up with cool ways of doing things! :)

Yes, indeed - but its always the software that actually makes it look cool when running! For instance, I have no idea how to write the code that makes it do the vertical paddle wheel kind of rotation, or the bubble rise up thru the middle kind of thing.

Well then, the theory is clear :) All that remains to do is to order the components, wait 5 weeks until they arrive from China, solder them together and write the software :) Should be ready by spring :) Too bad I can't buy the components here in Romania in some local store. Well, I could, but they'd cost 10 times more as sellers and stores are really greedy here.

Anyway, I know I've said this quite a few times already, but I'll say it one more time: thank you very much for taking the time and patience to explain this to me in detail. I've learned a lot from this discussion. I'll be back with pictures and videos when I'll have something usable or perhaps with a few more questions even before that if things don't go well :)

Thanks! Andras

I have built a 5x5x5 cube which is not powered yet but, getting close.

For the wires that go to the layers, I used bare 24Ga. craft wire that I found in Walmart. The wire has a similar shine as the LED leads so, it is not as obvious that the wires are in the cube. Care has to be taken running the wires but, they work nicely.

Let me know if you can see this image. At this point, I have only soldered the cube to the board. No wires have been ran yet in this picture.

I can see it :) Nice! Aren't those 5mm LEDs?

Looks nice!

Andras, you can start writing software while you wait.

Un4Seen: I can see it :) Nice! Aren't those 5mm LEDs?

Yes they are 5mm diffused LEDs. I started with a 3x3x3 cube and made it work basically but, had one bad LED. I then bought 100 more LEDs and made the cube bigger to 5x5x5.

Here is where I got the LEDs. They did take around 3 weeks to arrive using the standard mailing option. http://stores.ebay.com/LED-Wholesale-World/Blue-LED-/_i.html?_fsub=2777255010&_sid=1016205190&_trksid=p4634.c0.m322

Funny thing, I was looking at the same seller, only at his 3mm LEDs. I guess he has good prices. I'd like to use 3mm ones because it makes the cube more empty, more transparent, more visible (up to 5x5x5 it probably does not matter but when you get to 8x8x8 it does).

CrossRoads, I have made a few modifications to your wiring diagram, to make it more understandable for amateurs like myself and to be sure that I have understood things well. I hope you don’t mind.

The information I have added:

  1. The polarity of the LEDs
  2. The value of the resistors
  3. The value of the capacitors
  4. The type of the MOSFETs and which of their legs goes where
  5. The connections between the Arduino and the shift registers

I have removed all the additional circuitry that was around the Arduino or other micro controller on the other pins because I thought that it’s not needed. In other words the only pins of the Arduino that need to be connected to anything are D10/SS, D11/MOSI, D13/SCK and GND. I hope I was not wrong…

Could you please suggest some other MOSFET instead of NDP6020P-ND? These are barely found and expensive on eBay and cannot be found at all in my town's local shops...

Thanks, Andras