LED cube control

I have made a 4x4x4 LED cube which I am controlling by using the 20 digital and analog pins of an Uno. The cube has 4 levels of LED’s with all the cathodes connected together in their respective levels. The 16 anodes of each level are all connected to the respective anodes of the other three levels, thus having a total of 16 separate anodes for the columns and 4 separate cathode connections for the 4 levels. Rather than using 4 separate NPN transistors I want to use a ULN2803. i just want to hopefully confirm that my understanding of how to connect it is correct.
Thanks Pedro

With a 4 x 4 rgb cube it is possible to multlex it in such a way that you dont need any transistors or shift registers to control it. You end up with 16 wires that you can plug into the arduino pins directly.

Are you using rgbs or normal leds?

ULN2803 sinks current, you would use that if the layers had common cathodes. Good so far.
16 LEDs could have up to 320mA - single output on ULN2803 can take 500mA. Good so far.

'328P can only source 200mA, and only if the current is spread across the ports appropriately. Check the current limit resistors you have Per Anode and make sure you will not fry the '328.

So just to clarify, seeing as the I/O pins are sourcing current, presumably to check the current draw I would place an ammeter in series with each of the 16 pins and make sure that each was only drawing a maximum of 40 mA per pin and also that each port group was not drawing more than 100 mA per group. If either of these two figures are too high I would need to lower the current draw by fitting a higher value resistor

Yes - calculate to start tho.
(Vs - Vled - Vuln2803)/.02 = Resistor

So say Vs = 5V, Vled = 2.2V, Vuln2803 = 0.7V:
(5-2.2-.7)/.02=105 ohm

If you are making sure a port cannot exceed 100mA, then 100/8 = 12.5mA
(5-2.2-.7)/.0125 = 168 ohm

Most LEDs have 20mA max continuous on current.
Adjust the calculations as needed.
Vs for arduino is only guaranteed to be no lower than 4.2 or 4.3V at 20mA, so don't be surprised if you are not measuring 5V when you are driving LEDs on.

Thanks Crossroads I will check that out

boylesg - I am just using normal LED's as per my partial schematic 8)

I have constructed my 4x4x4 LED cube where all the cathodes on each of the four levels are connected together (within each individual level) and the sixteen anodes of each level are connected in series with the anodes of the other three levels. The anodes are connected to digital pins 0 to 15 via current limiting resistors and the cathode levels are switched to ground by a ULN2803 controlled by digital pins 16 to 19. I have attached a partial circuit schematic to illustrate this. I am having a problem where if I try to light only one LED using this code by calling onLed in loop as –

void loop()
 { 
  onLED(ledRow[0],ledCol[0]); 
 }

I get level 1,2 and 4 fully lighting and level 3 faintly lighting. As you can see the main functions that do the switching on and off of the LED’s are

  1. onLED
  2. offLed
  3. allOff
    Here is my full code
byte ledRow[] ={16, 17, 18, 19 };
byte ledCol[]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
byte timer= 10;
byte timer1= 40;


void setup() 
{  
  for( int i =  0; i < 4; i++)

  {
    pinMode( ledRow[i],OUTPUT);
  }

  {  
    for(int j =  0; j < 16; j++)

    {
      pinMode( ledCol[j],OUTPUT);
    }
  }
}


void onLED(int ledRow, int ledCol)
{

  digitalWrite(ledRow, HIGH); 
  digitalWrite(ledCol, HIGH); 

}


void offLED(int ledRow, int ledCol)
{
  digitalWrite(ledRow, LOW); 
  digitalWrite(ledCol, LOW); 
}


void allOff()
{
  for(int i = 4; i--;)
  {
    for(int j = 16; j--;)
    {
      offLED(ledRow[i],ledCol[j]);
    }
  }
}


void oneToNine_ColsOn()
{
  for(int j = 16; j--;)

  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}


void everySecond_ColsOn1()
{

  for(int j = 0; j< 16; j+=2)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}


void everySecond_ColsOn_2()
{

  for(int j = 1; j< 16; j+=2)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
} 
void lhWall_fToR()

{

  for(int j = 0; j< 16; j+=4)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}

void rhWall_fToR()

{

  for(int j = 2; j< 16; j+=4)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}


void frontWall_LtoR()
{
  for(int j = 0; j< 4; j++)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}

void rearWall_LtoR()
{
  for(int j = 6; j<16; j++)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(10);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}
void topRowPaneFigure8()
{
  for(int y = 0; y < 4; y++)   // light LED's 1 - 3 on/off on top level

  {
    onLED(ledRow[0],ledCol[y]);         // 7 8 9
    delay(timer1);                       // 4 5 6
    offLED(ledRow[0],ledCol[y]);        // 1 2 3
  }
  for(int y = 5; y > 2; y--)  // light LED's 6 - 4 on/off on top level
  {
    onLED(ledRow[0],ledCol[y]);
    delay(timer1);
    offLED(ledRow[0],ledCol[y]);
  }
  for(int y = 6; y < 16; y++)  // light LED's 7 - 9 on/off on top level
  {
    onLED(ledRow[0],ledCol[y]);
    delay(timer1);
    offLED(ledRow[0],ledCol[y]);
  }
  for(int y = 5; y > 2; y--)   // light LED's 6 - 4 on/off on top level
  {
    onLED(ledRow[0],ledCol[y]);
    delay(timer1);
    offLED(ledRow[0],ledCol[y]);
  }

}


void centreRowPaneFigure8()
{
  for(int y = 0; y < 4; y++)    // light LED's 1 - 3 on/off on centre level

  {
    onLED(ledRow[1],ledCol[y]);           // 7 8 9
    delay(timer1);                         // 4 5 6
    offLED(ledRow[1],ledCol[y]);          // 1 2 3
  }
  for(int y = 5; y > 2; y--)   // light LED's 6 - 4 on/off on centre level
  {
    onLED(ledRow[1],ledCol[y]);
    delay(timer1);
    offLED(ledRow[1],ledCol[y]);
  }
  for(int y = 6; y < 16; y++)   // light LED's 7 - 9 on/off on centre level
  {
    onLED(ledRow[1],ledCol[y]);
    delay(timer1);
    offLED(ledRow[1],ledCol[y]);
  }
  for(int y = 5; y > 2; y--)   // light LED's 6 - 4 on/off on centre level
  {
    onLED(ledRow[1],ledCol[y]);
    delay(timer1);
    offLED(ledRow[1],ledCol[y]);
  }

}

void bottomRowPaneFigure8()
{
  for(int y = 0; y < 4; y++)   // light LED's 1 - 3 on/off on bottom level

  {
    onLED(ledRow[2],ledCol[y]);          // 7 8 9
    delay(timer1);                        // 4 5 6
    offLED(ledRow[2],ledCol[y]);         // 1 2 3
  }
  for(int y = 5; y > 2; y--)   // light LED's 6 - 4 on/off on bottom level
  {
    onLED(ledRow[2],ledCol[y]);
    delay(timer1);
    offLED(ledRow[2],ledCol[y]);
  }
  for(int y = 6; y < 16; y++)   // light LED's 7 - 9 on/off on bottom level
  {
    onLED(ledRow[2],ledCol[y]);
    delay(timer1);
    offLED(ledRow[2],ledCol[y]);
  }
  for(int y = 5; y > 2; y--)    // light LED's 6 - 4 on/off on bottom level 
  { 
    onLED(ledRow[2],ledCol[y]);  
    delay(timer1);
    offLED(ledRow[2],ledCol[y]);
  }

}

void centreWall_LtoR()
{
  for(int j = 4; j<6; j++)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(timer);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}

void centreWall_fToR()

{

  for(int j = 1; j< 16; j+=4)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(timer);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}

void diagWall_LtoR()
{
  for(int j = 0; j < 16; j+=4)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(timer);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}

void diagWall_RtoL()
{
  for(int j = 2; j < 8; j+=2)
  {
    for(int i = 4; i--;)
    {
      digitalWrite(ledRow[i], HIGH);
      delay(timer);
      digitalWrite(ledCol[j], HIGH);
    }
  }
}


void loop()
{ 
  oneToNine_ColsOn();
  delay(10);
  allOff();
  delay(10);
  everySecond_ColsOn1();
  delay(10);
  allOff();
  delay(10);
  everySecond_ColsOn_2();
  delay(10);

  oneToNine_ColsOn();
  delay(10);
  allOff();
  delay(10);
  everySecond_ColsOn1();
  delay(10);
  allOff();
  delay(10);
  everySecond_ColsOn_2();
  delay(10);


  lhWall_fToR();
  delay(100);
  allOff();
  centreWall_fToR();
  delay(100);
  allOff();
  rhWall_fToR();
  delay(100); 
  allOff();

  frontWall_LtoR();
  delay(100);
  allOff();
  centreWall_LtoR();
  delay(100);
  allOff();
  rearWall_LtoR();
  delay(100);
  allOff();

  topRowPaneFigure8();
  centreRowPaneFigure8();
  bottomRowPaneFigure8();

  centreWall_LtoR();
  allOff();
  diagWall_LtoR();
  allOff();
  centreWall_fToR();
  allOff();
  diagWall_RtoL();
  allOff();
  
}

Even if I simplify things and just use this in loop, I still get the same situation.

void loop()
   { 
     digitalWrite(ledRow[0], HIGH);
     digitalWrite(ledCol[0], HIGH);
   }

I then connected the cube straight to the Arduino without the transistor array and set the pin with this

void loop()
   { 
     digitalWrite(ledCol[0], HIGH);
     digitalWrite(ledRow[0], LOW);
   }

The single LED now lights perfectly with none of the others in it’s column lighting fully or partially. What am I missing here. Thanks Pedro.