3x3 Cube light wont light :/

I'm doing this for a robot project as the finish line for a drag race. The cube will light as a celebration for the winner of the race. I don't understand why my other lights won't turn on on the cube! I did wire all the levels of my 3x3 LED cube, and they seem to not light up. I guess schematics or advice is what I'm asking for...

Im using:
-orange LEDs (x27)
-Adruino Uno (x1)

  • 270 ohm resisters (x3)
  • 1k ohm resistors (x9)
    -ULN2003A transistors (x2)
    -solderless breadboard
    -transistors (x9)

1k ohm resistor seems a bit much, the 270 ohm on your planes with no resistors on your columns sounds closer to what you probably want. I dont really see the need for the ULN 2003a Darlington arrays in your setup there, You should be able to run 27 LEDs without all those parts, heck I have a 64 LED cube that ran on an uno and 4 resistors (it works better with 16 resistors on the columns.)

Just a guess, you could probably put 150 ohm resistors on the columns( 9 ), and do away with the rest of the parts, and have a fine working cube.

The exact resistor value depends on how much current you need to fully illuminate but not damage the LED. Typically with 5mm LEDs they are often 20ma, and the forward voltage is about 2volts, You are sending it 5v, which could damage the LED, so you should resist it down to about 2v (or whatever the datasheet for that specific LED says).

You may want to do a little testing with different resistors, or a small pot to find the brightness level/voltage/resistance you like, and keep it within safe levels.

Once you get your cube working, adding complications like transistors, darington arrays and such will be a lot easier (although, with a small cube like that, using all those parts are not really necessary, but is NOT a bad way to learn how to use them, on a smaller scale.)

OK, I did get all the columns to light now and the programs I have written are actually working...

I have run into another problem though... Controlling the levels 1-3

The cannot control the levels to specifically light one light at a single time, usually when I light a column I get the entire row or a light directly above it. I have the levels in pins 11,12, and 13 the last digit of each corresponding to the level. 1 being the bottom, 2 the middle, and 3 being the top. The columns are separated by 0-8 for all 9 pins and 9 columns.

Am I not grounding something or does the problem lie in my coding? It is extremely simple and basic since I am new to this but I really would love to learn if there are simpler routes I should be taking or looking into!

void setup(){
    pinMode(0, OUTPUT );
        pinMode(1, OUTPUT);
        pinMode(2, OUTPUT);
        pinMode(3, OUTPUT);
        pinMode(4, OUTPUT);
        pinMode(5, OUTPUT);
        pinMode(6, OUTPUT);
        pinMode(7, OUTPUT);
        pinMode(8, OUTPUT);
        pinMode(11, OUTPUT);
        pinMode(12, OUTPUT);
        pinMode(13, OUTPUT);


}

void loop(){
     digitalWrite(0, HIGH);
   digitalWrite(13, HIGH);
       delay(10);
   digitalWrite(0, LOW);
   digitalWrite(13, LOW);
       delay(10);
   digitalWrite(1, HIGH);
   digitalWrite(13, HIGH);
       delay(50);
   digitalWrite(1, LOW);
   digitalWrite(13, LOW);
       delay(50);
   digitalWrite(1, HIGH);
   digitalWrite(12, HIGH);
       delay(50);
   digitalWrite(1, LOW);
   digitalWrite(12, LOW);
       delay(50);
   digitalWrite(2, HIGH);
   digitalWrite(13, HIGH);
       delay(50);
   digitalWrite(2, LOW);
   digitalWrite(13, LOW);
       delay(50);
   digitalWrite(3, HIGH);
   digitalWrite(13, HIGH);
       delay(50);
   digitalWrite(3, LOW);
   digitalWrite(13, LOW);
       delay(50);
   digitalWrite(4, HIGH);
   digitalWrite(13, HIGH);
       delay(50);
   digitalWrite(4, LOW);
   digitalWrite(13, LOW);
       delay(50);
   digitalWrite(5, HIGH);
   digitalWrite(13, HIGH);
       delay(50);
   digitalWrite(5, LOW);
   digitalWrite(13, LOW);
       delay(50);
   digitalWrite(6, HIGH);
   digitalWrite(13, HIGH);
       delay(10);
   digitalWrite(6, LOW);
   digitalWrite(13, LOW);
       delay(10);
   digitalWrite(7, HIGH);
   digitalWrite(13, HIGH);
       delay(50);
   digitalWrite(7, LOW);
   digitalWrite(13, LOW);
       delay(50);
   digitalWrite(8, HIGH);
   digitalWrite(13, HIGH);
       delay(10);
   digitalWrite(8, LOW);
   digitalWrite(13, LOW);
       delay(10);
  digitalWrite(8, LOW);
  digitalWrite(13, LOW);
       delay(10); 
  digitalWrite(8, HIGH);
  digitalWrite(11, HIGH);
      delay(10);
  digitalWrite(8, LOW);
  digitalWrite(11, LOW);
      delay(10);
  
  
  
  
  
  digitalWrite(0, HIGH);
  digitalWrite(11, HIGH);
      delay(10);
  digitalWrite(0, LOW);
  digitalWrite(11, LOW);
      delay(10);
  digitalWrite(0, HIGH);
  digitalWrite(12, HIGH);
      delay(50);
  digitalWrite(0, LOW);
  digitalWrite(12, LOW);
      delay(10);
  digitalWrite(0, HIGH);
  digitalWrite(13, HIGH);
      delay(100);
  digitalWrite(0, LOW);
  digitalWrite(13, LOW);
      delay(10);
  digitalWrite(8, HIGH);
  digitalWrite(11, HIGH);
      delay(10);
  digitalWrite(8, LOW);
  digitalWrite(11, LOW);
      delay(10);
  digitalWrite(8, HIGH);
  digitalWrite(12, HIGH);
      delay(50);
  digitalWrite(8, LOW);
  digitalWrite(12, LOW);
      delay(10);
  digitalWrite(8, HIGH);
  digitalWrite(13, HIGH);
      delay(100);
  digitalWrite(8, LOW);
  digitalWrite(13, LOW);
      delay(10);
  digitalWrite(6, HIGH);
  digitalWrite(11, HIGH);
      delay(10);
  digitalWrite(6, LOW);
  digitalWrite(11, LOW);
      delay(10);
  digitalWrite(6, HIGH);
  digitalWrite(12, HIGH);
      delay(50);
  digitalWrite(6, LOW);
  digitalWrite(12, LOW);
      delay(10);
   digitalWrite(6, HIGH);
  digitalWrite(13, HIGH);
      delay(100);
  digitalWrite(6, LOW);
  digitalWrite(13, LOW);
      delay(10);
  digitalWrite(2, HIGH);
  digitalWrite(11, HIGH);
      delay(10);
  digitalWrite(2, LOW);
  digitalWrite(11, LOW);
      delay(10);
  digitalWrite(2, HIGH);
  digitalWrite(12, HIGH);
      delay(50);
  digitalWrite(2, LOW);
  digitalWrite(12, LOW);
      delay(10);
  digitalWrite(2, HIGH);
  digitalWrite(13, HIGH);
      delay(100);
  digitalWrite(2, LOW);
  digitalWrite(13, LOW);
      delay(10);
      
      
  digitalWrite(0, HIGH);
  digitalWrite(11, HIGH);
  delay(500);
  digitalWrite(0, LOW);
  digitalWrite(11, LOW);
  delay(100);
  digitalWrite(1, HIGH);
  digitalWrite(11, HIGH);
  delay(500);
  digitalWrite(1, LOW);
  digitalWrite(11, LOW);
  delay(100);
  
  
  
}

There are some pictures in the attachments, sorry the wiring is semi messy, I cant really have them looking neat till I solve this solution out :confused:

The pins in row W/X are likely connected together due to being plugged into what is normally a 'power' strip.
Try moving them to Row A, section 14, 24, 34

Are you wired up like this?
Be sure to only drive 1 anode high and 1 cathode low at a time.

If you have the ULN2003 to drive the cathodes, then you can drive all the anodes while still just driving 1 cathode.

Thanks for responding to my forum post Robert, I did re-wire and set up the cube with the schematics you uploaded on my post. I did move the middle row to A, 14, 24, and 34... were they supposed to be offset from the other two that are one 15, 25, and 35?

With the ULN2003A should I be connecting the 3 levels, or the 9 columns vs both? I was also playing around with the example of 'BlinkWithoutDelay' and it seemed to do the trick of turning on one single light at a time, except I do not understand how to add more less into the example code, any tips/ recommendations?

I added a attachment of the rewire and I'm using the same code from my post earlier, thanks again! You're fine to reply back to my email here or on my post in the Arduino forums.

my goal here is to multiplex these lights, how should I be starting my program?

The ULN2003 has 7 arrays, so you would need 2 chip to run the columns.
Have you tested your cube to make sure each LED lights, and only one LED lights at a time?

You may want to write a simple test program that lights 1 LED, then pauses, then turns off the LED, then lights the next LED, until it sequences all the LEDs. 2 loops (1 to 3, and 1 to 9) would be nice, but you can do it any way you like.

Once you have the wiring setup right, everything seems to light properly, you can go back and add your other components if you want, then make sure it still works.

From :
http://arduino.cc/playground/Main/LEDCube3x3
I found this 3x3x3 cube code, Ive modified it to work with your cubes pinout.
It uses pins 0-8 and 11,12,13 (i didnt know there was a pin0, but I did put it in the code, to match the pins used in your code.

/*
Based on ledcube.c from Make: September 7, 2007 weekend podcast  
http://blog.makezine.com/archive/2007/09/make_a_pocket_led_cube_we.html

Custom animation programmed by Mark Boszko, http://stationinthemetro.com
*/

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

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

// LED Pattern Table in PROGMEM - last column is display time in 100ms units
// TODO this could be a lot more compact but not with binary pattern representation
prog_uchar PROGMEM PatternTable[] = {
  // blink on and off
    B111, B111, B111, B111, B111, B111, B111, B111, B111, 5,
    B000, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B111, B111, B111, B111, B111, B111, B111, B111, B111, 5,
    B000, B000, B000, B000, B000, B000, B000, B000, B000, 1,
  // flash each LED in sequence: 
  // Left->Right column, then Top->Bottom row, then Upper->Lower plane
    B100, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B010, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B001, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B100, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B010, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B001, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B100, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B010, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B001, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B100, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B010, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B001, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B100, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B010, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B001, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B100, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B010, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B001, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B100, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B010, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B001, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B100, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B010, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B001, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B000, B100, 1,
    B000, B000, B000, B000, B000, B000, B000, B000, B010, 1,
    B000, B000, B000, B000, B000, B000, B000, B000, B001, 10,

  // this is a dummy element for end of table (duration=0)
    B000, B000, B000, B000, B000, B000, B000, B000, B000, 0  
};

/*
** Defining pins in array makes it easier to rearrange how cube is wired
** Adjust numbers here until LEDs flash in order - L to R, T to B
** Note that analog inputs 0-5 are also digital outputs 14-19!
** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps
*/

//TheColdest's cube uses pins 0-9, 11-13, I would suggest using 

//int LEDPin[] = {16, 3, 1, 15, 4, 6, 14, 5, 7};
// Using pins 0-8 for columns
int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};

//int PlanePin[] = {19, 18, 17};
//using pins 11,12,13 for planes
int PlanePin[] = {11, 12, 13};

// initialization
void setup()
{
  int pin;      // loop counter
  // set up LED pins as output (active HIGH)
  for (pin=0; pin<PLANESIZE; pin++) {
    pinMode( LEDPin[pin], OUTPUT );
  }
  // set up plane pins as outputs (active LOW) 
  for (pin=0; pin<CUBESIZE; pin++) {
    pinMode( PlanePin[pin], OUTPUT );
  }
}

// display pattern in table until DisplayTime is zero (then repeat)
void loop()
{
  // declare variables
  byte PatternBuf[ PLANESIZE ];      // saves current pattern from PatternTable
  int PatternIdx;
  byte DisplayTime;        // time*100ms to display pattern
  unsigned long EndTime;
  int plane;      // loop counter for cube refresh
  int patbufidx;   // indexes which byte from pattern buffer
  int ledrow;    // counts LEDs in refresh loop
  int ledcol;    // counts LEDs in refresh loop
  int ledpin;    // counts LEDs in refresh loop

  // Initialize PatternIdx to beginning of pattern table
  PatternIdx = 0;
  // loop over entries in pattern table - while DisplayTime>0
  do {
    // read pattern from PROGMEM and save in array
    memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
    PatternIdx += PLANESIZE;
    // read DisplayTime from PROGMEM and increment index
    DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );    
    // compute EndTime from current time (ms) and DisplayTime
    EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;

    // loop while DisplayTime>0 and current time < EndTime
    while ( millis() < EndTime ) {
      patbufidx = 0;    // reset index counter to beginning of buffer
      // loop over planes
      for (plane=0; plane<CUBESIZE; plane++) {
        // turn previous plane off
        if (plane==0) {
          digitalWrite( PlanePin[CUBESIZE-1], HIGH );
        } else {
          digitalWrite( PlanePin[plane-1], HIGH );
        }

        // load current plane pattern data into ports
        ledpin = 0;
        for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
          for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
            digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
          }
          patbufidx++;
        } 

        // turn current plane on
        digitalWrite( PlanePin[plane], LOW );
        // delay PLANETIME us
        delayMicroseconds( PLANETIME );
      }    // for plane
    }    // while <EndTime
  } while (DisplayTime > 0);        // read patterns until time=0 which signals end
}

The ULN2003A connects to the 3 cathode layers.
Write the 9 anodes for a layer, turn on its cathode, after 4-5mA turn it off.
Write the 9 anodes for the next layer, turn on its cathode, after 4-5mA turn it off.
Write the 9 anodes for the next layer, turn on its cathode, after 4-5mA turn it off.
Repeat.

During the 4-5mS, be doing something else, like checking for button inputs, incrementing pointers into the array you are pulling data from to create the anode patterns, receiving serial data to update the array with, etc. Which describes the code above if you had fied patterns stored on progmem.

You could use 3 int variable, 1 for each layer, and do two direct port writes for each layer to write the anodes, one more for the cathodes, and just manipulate the data at the bit level in the 9 bits that make up the anode variables.

CrossRoads, I have the cube made in the exact opposite way, I'm driving the layers with anodes, and the columns/rows with cathodes. SO can I still just reverse what you're saying and have it work? Or do I have to remake a cube?

as with writing the array, like a said before I've never done this before could you give me an example as to how you digitalWrite a specific amount of milliAmps?

So you have this then.

"how you digitalWrite a specific amount of milliAmps"

You don't - that was a typo on my part, should have been mS, not mA. The current will be limited by the resistors.

Write the 9 cathodes for a layer, turn on its anode, after 4-5mS turn it off.
Write the 9 cathodes for the next layer, turn on its anode, after 4-5mS turn it off.
Write the 9 cathodes for the next layer, turn on its anode, after 4-5mS turn it off.
Repeat.

code snippet - define all the variables, etc. All time elements are unsigned long.

void loop()

{

  currentmicros = micros(); // read the time. can be millis also, interval is then 5, vs 5000

  if ((currentmicros - nextmicros) >= interval) // 5 milliseconds have gone by, display the next layer

  {
nextmicros = nextmicros + interval;
// do the cathode/anode driving
// keep track of which layer is being driven
anodelayer = anodelayer +1;
if (anodelayer == 3){ anodelayer = 0;}  // layers 0,1,2
    }

OK. so I found another way to light them individually with this code.

int timer = 0;
int leveltimer = 5;

byte piggy   [9] = {1,0,1,0,0,0,1,0,1}; //lighting the four corners
byte cowey [9] = {1,0,1,0,0,0,1,0,1};
byte horse  [9] = {1,0,1,0,0,0,1,0,1};

void setup(){
  for(int i= 0; i<9; i++){
    pinMode(i, OUTPUT);
  }
  pinMode(11,OUTPUT); //level 1, base
  pinMode(12,OUTPUT); //level 2, middle
  pinMode(13,OUTPUT); //level 3, top
}
void loop(){
  for(int j = 11; j<14; j++){ //j = pin 11, level 1
  
  //digitalWrite(j, HIGH);
  if(j==11){
    for(int i = 0; i<9; i++){
      delay(timer);
     if(horse[i]){
       digitalWrite(i, HIGH);
       
       
   }
   else{
   digitalWrite(i, LOW);
   }
  }
 }
 if(j==12){ //j = pin 12, level 2
    for(int i = 0; i<9; i++){
      delay(timer);
     if(cowey[i]){
       digitalWrite(i, HIGH);
       
   }
   else{
   digitalWrite(i, LOW);
   }
 }
 }if(j==13){ //j = pin 13, level 3
    for(int i = 0; i<9; i++){
      delay(timer);
     if(horse[i]){
       digitalWrite(i, HIGH);
       
       
   }
   else{
   digitalWrite(i, LOW);
   }
  }
 }
   digitalWrite(j, HIGH);
     delay(leveltimer);
    digitalWrite(j, LOW);
  }
  
}

I tried repeating this and controlling the levels and columns, but when I copy and pasted the code I got a loop of the original program never escaping the loop. level 1,2,3...

CrossRoads I tried using your snippet and I honestly don't understand it one bit since like I said before I'm new to this.

Is there a way I can stay in the same format I'm in now just increase the volume of the program?