Go Down

Topic: 8x8x8 multiplexed LED cube with an Arduino Mega 2560 (Read 41 times) previous topic - next topic


That bobduino thing looks pretty cool. I've also seen a similar thing that was just shift registers, I think it was 8 of them, I cant remember for sure.

I have been working on documentation for 3 different RGB LED cubes, they all controll 64 RGB LEDs, but they do it 3 different ways.

I still have a lot of work to go, I have one cube up, and details about how what wires to use, how to prep them, and why.

I really think the split is a bad idea, It will require some kind of non-conductive structure in between. I dont see any good way to do this, it will only make things harder, and I think the results will be less than desirable.

I have seen carbon fiber tubes and plastic stuff at the hobby store, if you really must try some kind of non-conductive alternative, you might find something there. What you will find there is something called music wire, its hardened steel wire, and is very very stiff. Its harder than hell to solder too, but it provides a really sturdy structure, that will flex a bit, instead of bending and kinking. You can get very thin wire, that is stronger than bailing wire, and much much thinner, and harder to see.

You should really learn about Serial communication, like I mentioned in my other post. Transmitting the data (64 bits per plane most likely) Since you do not have 64 pins available, there is no way to do that with parallel, so you will need serial, there is no doubt (unless you were willing to entertain charlieplexing...) Since you are forced into serial, you really wont need a mega, but it has more memory, so that will be useful, but you really only need a few pins to do serial data transfer. Since you have so many pins available, you may elect to use one pin per plane, and 3 pins to serialize your data through. Since you will be doing some form of serial, you have lots of options, shift registers, LED drivers, you could even do a ton of resistors and transistors. Drivers come with a lot of different features, I've tried get my head around what things are important, and its confusing.

If you go with a constant current driver, like the TLC 5940, you can do it with 4 chips (each chip is 16 bit, and does PWM), You will need to source current to each plane, as the TLC chips are sink only, no sourcing.

If you use shift registers, the nice thing about them is that they can sink or source, so you could source using a shift register, and sink with something else. The downside is that they dont control the current, so the will need resistors.

Multiplexing chips probably wont work for you.

I havnt finished my higher power cubes, but you will need to sink or source current to your planes, I've done a little reading and it seems there are 2 common ways to do that, darlingtons or mosfets. Mosfets are preferred as they seem to be more efficient, especially when not being used (and your mosfets would only be used 1/8 of the time).

The current website im working on is about RGB charlieplexing cube, but you will find some useful info about building cubes in there. I would strongly suggest building a couple small structures with just a few parts, and actually complete something so you understand all the steps before you try to design your own process.

The most realistic way I can see building this cube is 8x64 setup, and common anode(planes) is the most versatile way, since you could use shift registers or constant current drivers.



Dec 28, 2012, 11:11 pm Last Edit: Dec 28, 2012, 11:13 pm by Un4Seen Reason: 1
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 :) 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

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.
Code: [Select]

// some stuff you need anyway
# include<SPI.h>
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.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.


Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Go Up