RGB SMT LED Cube, resistors, drivers, and shift registers.

Yet another crazy cube idea. one of the nice things about this setup is that you dont use too much current, and you dont have to worry about mosfets, It does require more parts than the charliecube, but its only 16 transistors. Because it only lights up 12 LEDs at a time it only uses 240 mA, but it has a duty cycle of 4%, so it wont be very bright.

Here my modification of a 5x5x5 transistor cube (thanks crossroads), that I changed to 4x4x4 RGB. I didnt quite draw all the lines in, but hopefully enough is there to get the right idea.

At this rate, I may never get the original cube SMT constant current cube finished, or the shift register-resistor cube built.

I've been reading up on the transistors...
For the cascaded transistor cube, it looks like i could use 20 2n2222 transistors. Since my needs are 240ma, 3904s wont be suitable. It seems like I could also do it with ULN chips and 4 transistors. Is there any reason an n-channel mosfet wouldnt work well?

I still havnt figured out what mosfets to use for the other cubes, but maybe I will find one to use with the transistor cube.

I have been trying to figure out what decoupling cap I need for the TLC 5940, Ive read that I should put a 47uf electrolytic cap on them. I've looked over the datasheet, and not found anything that suggest what cap to use, the tutorial doesnt have any decoupling cap, and calculating what cap seems to be some kind of magic that nobody really understands.

I've dug through all my spare/scrap parts, and cant find any 47uf caps, i have many caps in various sizes, but that that size. What about voltage rating, what caps do i need? how do I know what size is right?

Im also curious about ordering parts from the big houses like digikey mouser, ... How long does it take to get parts within the US? does it take weeks, or within a week? I've never ordered anything from any of those places, so any tips would be helpful.

Ive found lots of fets that will probalby be suitable, trying to pick one is hard.

Ive found this one DMN2112SN
its 100mOhm, 1/2watt 1.2a
My needs are:
16x3x20=960ma=.96a
THis is my dissipation calculations.
.96x.96 =0.9216 x .1= .09216, or 96mw, or about 1/10th watt, so well within 1/2 watt.

this is from the digikey website:

FET Type MOSFET N-Channel, Metal Oxide
FET Feature Logic Level Gate
Drain to Source Voltage (Vdss) 20V
Current - Continuous Drain (Id) @ 25° C 1.2A
Rds On (Max) @ Id, Vgs 100 mOhm @ 500mA, 4.5V
Vgs(th) (Max) @ Id 1.2V @ 1mA
Gate Charge (Qg) @ Vgs -
Input Capacitance (Ciss) @ Vds 220pF @ 10V
Power - Max 500mW
Full datasheet.
http://www.diodes.com/datasheets/ds30830.pdf

Does that seem like a good part for what im doing? I dont want to buy any more parts that are not what i need.

I love to see these things in action, Can you maybe think about making a video for us so we can see :smiley:

For decoupling you usually need one larger cap, for example 47uH, and smaller caps for each chip involved with usual values ranging from 0.1uF to 0.01uF. The latter ones are for the high frequelncy noise and should be located as close as practically possible to the ICs.

Here's an excellent tutorial on it:
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

I order most of my components from places like Mouser, Digikey and Newark and they ship rapidly. Of course it depends on ones particular location but my things usually arrive within 3-4 days.

CybrE3_Mad_Coder, heres a link to my youtube videos, the last several videos are examples of LEDs and circuits that ive been working on. I have some TLC5940 stuff, 74hc595/shiftout stuff, and some charlieplexed stuff.

Headroom, Thanks for the tips, It sounds like those place dont take any longer than ebay or any other place, thats good to know.

I looked over mikes decoupling page, and things are still rather complicated and hard to understand everything, but its good to have that as a reference. As I understand it, if the caps arent quite right, there can be a lot of RF noise, and I guess its common for folks to just throw some caps at it, and be unaware of the noise issue. I dont like solving problems by making other problems, which is what im trying to avoid, while learning...

I have 104 ceramic caps on my shift registrers, and my tlc chip, but I think my tlc chips may also need 47uH because mike had posted that on another thread about that chip.

There are no capacitors in the TLC tutorial, and the 595 tutorial has them in the wrong place, it would really be nice if things were consistent around here. its kinda confusing.

I ordered some parts from digikey yesterday, and in just over an hour, I was notified that my order was ready for shipping, it appears to be on its way, and should be here by the end of the week, and shipping cost was minimal.

1 25 DMN2112SNDICT-ND MOSFET N-CH 20V 1.2A SC59-3 25
2 25 785-1085-1-ND MOSFET P-CH -30V -1.2A SC70-3 25
3 100 CF18JT51R0CT-ND RES 51 OHM 1/8W 5% CF AXIAL 100
4 100 MMBT2222AFSCT-ND TRANSISTOR GP NPN AMP SOT-23 100
5 10 399-6098-ND CAP ALUM 47UF 35V 20% RADIAL 10
6 100 CF18JT75R0CT-ND RES 75 OHM 1/8W 5% CF AXIAL 100

Hopefully, the fets are the best fets for my purposes. I think I have some parts that will be very efficient, but Im hoping they are fast enough.
The other parts are for other cubes, including the new transistor shifter cube.

I hope to have some inexpensive charliecube kits soon if anyone wants to build one.

I ordered parts monday around noon, and the parts arrived by thursday. It seems they can ship stuff just as quickly, and inexpensively as any ebay provider within the US.

They did kind of use a lot of packaging, but they did use about 1/2 recyclable packing material.

I forgot to calculate the resistors for the 2n2222 transistors. I need 240mA for the transistor cube, The transistors I got seem to be limited to 350ma, that should be enough for my needs. I have been trying to figure out HFE, and what resistors to use with them, to limit the current to safe levels. Nearest i can tell, about 330 seems to be about right, to keep me under 350ma, but enough to drive the transistor well into saturation.

It seems that while reading about mosfets, one of the nice things is that I wont be needing a current limiting resistor, like I would on a BJT, but that I could use a resistor to help reduce the chance of the fet self destructing or going into a feedback loop or something. can anyone explain that ?

The transistor cube is coming along nicely. I have 16 spires built, and I have 20 transistors soldered and circuit wired up for them. im still trying to figure out the best way to assemble the spires onto the PCB. Im thinking that making 4 spires into 1 plane, then fit each plane onto the PCB. I'll get some pics up today.

Heres one image of the spires being assembled. I havnt soldered them together yet, but I think this is how I will do it.

This is an ugly picture of the transistors. I grouped them badly. It was to make it fit in a small space. After soldering them in like this, I realized I could use a little more space, put 4 transistors inline, and the wiring would have been a lot neater and tidier.

man, you're doing a great job!! I'm anxiously awaiting your next posts! thank you for sharing this with us!

rick

You are welcome rick, thanks for the support. :smiley:

If things go well today, I think I will solder the LEDs to the board, and finish the circuitry. Then the scary part, testing.

I havnt posted anything in a while, I have been testing transistors for the new cube, and for the other unfinished cubes.
The above picture was after finishing the new cube design. I chose to build this one using just the LEDs leads, instead of using wire. I wanted this cube to fit on a smallish PCB, the LEDs are just under 1" apart, and that meant that the LED leads were just long enough to work without additional wire.
I did have to add 2 support wires, to help make the cube sturdy, but I may take them off, as they are kinda ugly.

Ive finally gotten the transistor cube working. Heres a quick video

This circuit uses:
64 Common Cathode RGB LEDS
20 NPN transistors (2n2222, I used tiny sot23 package parts, but any 2222 should work)
20 Resistors (eight 270 ohm 2n2222 base resistors, 12 anode resistors (eight 100 ohm, four 150 ohm)
The cube layout uses lines instead of planes. Typical 4x4x4 cube construction uses 4 planes of 16 LEDs, this uses 16 lines of 4 LEDs, which brings the duty cycle down to 6.67% (from 25%), but it requires few parts, and doesnt require off-board power, since it only lights up a maximum of 12 LEDs(4 RGB LEDs) at a given time.

This specific cube was made using the LED leads and no additional stiff wire, It is also sized to fit a slightly smaller circuit board (this board is only 3" wide, so the LEDs are about 7/8" in apart, unlike the other cubes that are 1" spacing.

I think it looks horrible in the daylight, compared to the cubes with nice stiff wires, but when its dark, you dont notice so much.

This cube use 20 pins on the microcontroller, and on most arduinos, that doesnt leave any pins left for additional features, and assuming you are using 20ma LEDs you could draw upto 240ma at one time, which may be too much for 28 pin dip arduinos.

Edit: removed old ugly program, see next post for better program.

This is a better test program, I've cleaned things up, and added some more programs.

// TransistorCube  -- Test Program
#include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash

#define CUBESIZE 4
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 3333 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 5 // multiplies DisplayTime to get ms - why not =100?

/*
** Defining pins in array makes it easier to rearrange how cube is wired
** This cube uses 2 plane pins and one led pin to light up any single LED.
** Pins 2-13 are used to control the 12 RG and B anodes (the rear to forward 4 LED)
** 5 banks of 4 transistors that are controlled by 8 arduino pins sink the cathodes.
** Pins (14,15,16,17) control 4 transistors that select the row(wide), and on each row.
** Pins (18,19,0,1)4 control 1 of 4 sets of 4 transistors that select the level(height). 
** First you have to turn on a row, then turn on a level to sink the LED.
** 
** This cube uses NPN transistors. We send HIGH to sink a row or level,
** and we send HIGH to turn on a anode color/forward/back LED. send LOW turns LEDs off.
*/

int RGBColumnPin[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int RowPin[] = {14, 15, 16, 17};
int LevelPin[] = {18, 19, 0, 1};
int RowLevelCount  = 4;
int RGBColumnPinCount = 12;
// initialization
void setup()
{
  int pin; // loop counter
  // set up LED pins as output (active HIGH)
  for (pin=0; pin<(RGBColumnPinCount); pin++) {
    pinMode( RGBColumnPin[pin], OUTPUT );
  }
  // set up plane pin1 as outputs (active HIGH)
  for (pin=0; pin<CUBESIZE; pin++) {
    pinMode( RowPin[pin], OUTPUT );
  }
  // set up plane pin2 as outputs (active HIGH)
  for (pin=0; pin<CUBESIZE; pin++) {
    pinMode( LevelPin[pin], OUTPUT );
  }
}

void loop(){
// comment out lines below to run just the specific test you want
// to run. comment all but one routine at a time for best results.
// You can also change values inside the programs for different testing.

  loopFor();
  loopRand();
  loopRedWall();
  loopFullOn();

}

// This bit of programming uses 3 loops to sequence all 192 LEDs 
// one loop controls 1 LEDs anode pin, the 2 other loops control the cathode pin.
// You turn a pin HIGH, to light the LED (turn the anode HIGH, and turn 2 
// transistors HIGH to sink one cathode line (4 RGB LEDs)
// Turning all pins LOW, turns all LEDs off.
void loopFor()
{

   for(int thisRowPin = 0; thisRowPin < RowLevelCount; thisRowPin++){
     for(int thisLevelPin = 0; thisLevelPin < RowLevelCount; thisLevelPin++){
        for(int thisPin = 0; thisPin < RGBColumnPinCount; thisPin++){
        
        planesOff();
        digitalWrite(RGBColumnPin[thisPin],HIGH);
        digitalWrite(RowPin[thisRowPin],HIGH);
        digitalWrite(LevelPin[thisLevelPin],HIGH);
       
        
        delay(100); // increase value to slow down
        
        digitalWrite(RGBColumnPin[thisPin],LOW);
        digitalWrite(RowPin[thisRowPin],LOW);
        digitalWrite(LevelPin[thisLevelPin],LOW);
     //   delay(100); // if you want an off delay       
      }
    }
  } 
}

void loopRand()
{
    int randPin = random(12);
    int randPlane1 = random(4);
    int randPlane2 = random(4);
    
    planesOff();
    
    digitalWrite(RGBColumnPin[randPin],HIGH);
    digitalWrite(RowPin[randPlane1],HIGH);
    digitalWrite(LevelPin[randPlane2],HIGH);
        
    delay(50);
           
      
    digitalWrite(RGBColumnPin[randPin],LOW);
    digitalWrite(RowPin[randPlane1],LOW);
    digitalWrite(LevelPin[randPlane2],LOW);
     
     
}

void planesOff(){
    for(int thisRowPin = 0; thisRowPin < RowLevelCount; thisRowPin++){
        digitalWrite(RowPin[thisRowPin],LOW);
    }
    for(int thisLevelPin = 0; thisLevelPin < RowLevelCount; thisLevelPin++){
        digitalWrite(LevelPin[thisLevelPin],LOW);
    }
}


void loopRedWall()
{

   for(int thisRowPin = 0; thisRowPin < RowLevelCount; thisRowPin++){
        for(int thisPin = 0; thisPin < 4; thisPin++){
  
     for(int thisLevelPin = 0; thisLevelPin < RowLevelCount; thisLevelPin++){
         
        planesOff();
        digitalWrite(RGBColumnPin[0],LOW);
        digitalWrite(RGBColumnPin[1],HIGH);
        digitalWrite(RGBColumnPin[2],LOW);
        digitalWrite(RGBColumnPin[3],LOW);
        digitalWrite(RGBColumnPin[4],HIGH);
        digitalWrite(RGBColumnPin[5],LOW);
        digitalWrite(RGBColumnPin[6],LOW);
        digitalWrite(RGBColumnPin[7],HIGH);
        digitalWrite(RGBColumnPin[8],LOW);
        digitalWrite(RGBColumnPin[9],LOW);
        digitalWrite(RGBColumnPin[10],HIGH);
        digitalWrite(RGBColumnPin[11],LOW);
        digitalWrite(RowPin[thisRowPin],HIGH);
        digitalWrite(LevelPin[thisLevelPin],HIGH);
       
        
        delay(5); // increase to slow down
        
        digitalWrite(RGBColumnPin[0],LOW);
        digitalWrite(RGBColumnPin[1],LOW);
        digitalWrite(RGBColumnPin[2],LOW);
        digitalWrite(RGBColumnPin[3],LOW);
        digitalWrite(RGBColumnPin[4],LOW);
        digitalWrite(RGBColumnPin[5],LOW);
        digitalWrite(RGBColumnPin[6],LOW);
        digitalWrite(RGBColumnPin[7],LOW);
        digitalWrite(RGBColumnPin[8],LOW);
        digitalWrite(RGBColumnPin[9],LOW);
        digitalWrite(RGBColumnPin[10],LOW);
        digitalWrite(RGBColumnPin[11],LOW);
        digitalWrite(RowPin[thisRowPin],LOW);
        digitalWrite(LevelPin[thisLevelPin],LOW);
     //   delay(100);        
      }
    }
  } 
}
void loopFullOn()
// This program lights 12 LEDs ina line, and cycles through the row/levels
{
   for(int thisRowPin = 0; thisRowPin < RowLevelCount; thisRowPin++){
 //       for(int thisPin = 0; thisPin < 4; thisPin++){
  
     for(int thisLevelPin = 0; thisLevelPin < RowLevelCount; thisLevelPin++){
         
        planesOff();
        digitalWrite(RGBColumnPin[0],HIGH);
        digitalWrite(RGBColumnPin[1],HIGH);
        digitalWrite(RGBColumnPin[2],HIGH);
        digitalWrite(RGBColumnPin[3],HIGH);
        digitalWrite(RGBColumnPin[4],HIGH);
        digitalWrite(RGBColumnPin[5],HIGH);
        digitalWrite(RGBColumnPin[6],HIGH);
        digitalWrite(RGBColumnPin[7],HIGH);
        digitalWrite(RGBColumnPin[8],HIGH);
        digitalWrite(RGBColumnPin[9],HIGH);
        digitalWrite(RGBColumnPin[10],HIGH);
        digitalWrite(RGBColumnPin[11],HIGH);
        digitalWrite(RowPin[thisRowPin],HIGH);
        digitalWrite(LevelPin[thisLevelPin],HIGH);
       
        
        delay(100); //This controls speed, bigger is slower.
        
/*        digitalWrite(RGBColumnPin[0],LOW);
        digitalWrite(RGBColumnPin[1],LOW);
        digitalWrite(RGBColumnPin[2],LOW);
        digitalWrite(RGBColumnPin[3],LOW);
        digitalWrite(RGBColumnPin[4],LOW);
        digitalWrite(RGBColumnPin[5],LOW);
        digitalWrite(RGBColumnPin[6],LOW);
        digitalWrite(RGBColumnPin[7],LOW);
        digitalWrite(RGBColumnPin[8],LOW);
        digitalWrite(RGBColumnPin[9],LOW);
        digitalWrite(RGBColumnPin[10],LOW);
        digitalWrite(RGBColumnPin[11],LOW);
*/        
        digitalWrite(RowPin[thisRowPin],LOW);
        digitalWrite(LevelPin[thisLevelPin],LOW);
     //   delay(100);        
   //   }
    }
  } 
}

I like your progress! I hope you continue to post more videos as you get better at using the cube.

I need to build a RGB cube bad!

Thanks :smiley:
Thats how I felt when I stared this thread many months ago. I had a working single color cube, it wasnt too hard to build...
Then I made all the wrong assumptions, and figured RGB wouldnt be to much harder. Boy was I wrong.
So far, the original cube has lit up LEDs, but is still not working, the next attempt is 1/2 way finished (less than the first attempt), the third attempt has been working great, I've done a lot of work documenting the building and testing modifying, and the last one seems to work, but is in the early stages of software development.

At this point my expectations are that the unfinished cubes will be the best quality (speed/brightness), but they have also been the most problematic.

The quickest easiest to get up and working is the charliecube, If you use 75 ohm resistors, that should keep the LEDs under 20ma (although I'd recommend 50 ohm resistors as that should keep them at about 20ma, and 25ma on the red)

I've been working on changing the 4x4x4 single color cube to work with the transistor cascade cube, and it requires radical change to the program.

This part should read in 16 bits (one plane of data)

memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
PatternIdx += PLANESIZE;

The way the new cube works, it seemed best to deal with a whole cube data at one time, since I am lighting 1 line(4 LEDs), instead of 4 planes (16 LEDs).

I have changed it to:

memcpy_P( PatternBuf, PatternTable+PatternIdx, (PLANESIZE * CUBESIZE) );
PatternIdx += (PLANESIZE * CUBESIZE));

Hopefully, I've done that right, but there is another part where we use the data, this part:

digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );

Im pretty sure that what that line does is light up a specific LED (LEDPin is one of 16 column pins), and PatternBuf is the 16 bits of data, and patbufidx points to the specific bit for the specific pin. this gets looped 16 times to complete one plane.

Now what I want to do is light up 4 LEDs in a line, not a plane, each of the LEDs are RGB LEDs, so each bit will actually light all three LEDs so its white when on. Instead of lighting just one LED, I need to do all 4 (which is really 12 LEDs). Both ways do cycle of 16 to complete the cube, the old way did 4 cycles of 16, the new way does one cycle of 16, but lights 4 LEDs per cycle.

digitalWrite( RGBColumnPin[1], PatternBuf[patbufidx] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[2], PatternBuf[patbufidx] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[3], PatternBuf[patbufidx] & (1 << ledlevel) );
// LED 2
digitalWrite( RGBColumnPin[1+16], PatternBuf[patbufidx+16] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[2+16], PatternBuf[patbufidx+16] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[3+16], PatternBuf[patbufidx+16] & (1 << ledlevel) );
// LED 3
digitalWrite( RGBColumnPin[1+32], PatternBuf[patbufidx+32] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[2+32], PatternBuf[patbufidx+32] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[3+32], PatternBuf[patbufidx+32] & (1 << ledlevel) );
// LED 4
digitalWrite( RGBColumnPin[1+48], PatternBuf[patbufidx+48] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[2+48], PatternBuf[patbufidx+48] & (1 << ledlevel) );
digitalWrite( RGBColumnPin[3+48], PatternBuf[patbufidx+48] & (1 << ledlevel) );
}
patbufidx==patbufidx+CUBESIZE;

I dont really understand the "& (1 << ledlevel) )" part in this case ledlevel is one of the 2 transistors that are controlling which line is active. It seems to me that I dont want that in there, but its doing something like shifting a bit, and I dont know if I need it or not, or how to treat it in this modification. The variables ledrow, and ledlevel are what make this loop 16 times (4 sets for 4)
Since its lighting up 4 LEDs at a time, instead of looping through 4 planes, I changed the patbufidx++ to the above +CUBESIZE, is that a good way to do it?

I could use some help fixing up this code to work right. The hardware tests fine with my other program, but I have been having no luck getting this one working right, and could use some help.

I've spent a bunch of time going over this code, and changing things many different ways.
I still havnt figured out how to make this program work with the transistor cube.

Most cubes are planar, but this cube is different. Its similar to the charliecube in that it treats the cube as 16 LEDs in a spires of 4 LEDs. Changing the program that runs 4 cycles of 16 cycles of LEDs, seems simple enough to convert to 4 cycles of 4 cycles of 4 RGB LEDs,

On my previous post I was trying to make the program load the 64 bits at a time, and it was making things crazy and complicated, so a couple days ago, I tried changing it back to 16 bits at a time, while lighting 16 spires/line of 4 LEDs, one spire/line at a time.

The way I was expecting the program to work is basically like this:

1 row pin and 1 level pin turn on a individual cathode for 4 RGB LEDs in a line (spire).

12 anode pins control the 4 RGB LEDs. To keep things simple, we are treating each RGB LED as a single color LED, and using 1 bit per LED

This code includes 3 versions of the anode pins that use a "1 << variableName" thing,

The program starts with the usual declaring variables, and setting up the pins, then starts a couple loops and has some while statements. The loops used to be 16 and 4, but I needed to change it to 4 and 4 with 12 anode writes instead of 1 anode write.

The original version has a pattern buffer index that points to one of 16 bits of data, and it increments until it completes its cycle, then advances a plane, and reads in and processes that 16 bits. It does this 4 times to complete 1 line of data (64 bits).

Im trying to make this program cycle 4 lines of 4 LEDs at a time, then increment the pattern buffer index 4 times, which should be the same a sequencing 16 LEDs on a plane (4 lines of 4 LED is the same as 16 LEDs in a 4x4 matrix)

I have found that if I comment out the pattern buffer index, I can get things to start to work, but never quite right. Sometimes it lights up many LEDs instead of one, It only seems to read the first 4 bits in a 16 bit segment though.

If I enable the pattern buffer indexing lines, the cube lights many leds on many levels, its really weird.

Heres the current not working quite right version. It only has a couple lines of data I just change the data with 1s and 0s to test that I can control each LED one or more at a time.

Hippynerd:
It says the code too many characters for one post :frowning: Splitting it seems the best option.

Click on Additional Options (lower left of text window) and Upload it as an Attachment.