4x4 LED "MiniCube"

I had about 70 or so pin-source LEDS leftover from a big bag I got a while back. Also found a few old shift registers laying about. So...I decided to attempt my first LED cube. Instead of going BIG, I decided to try for the smallest I could make. Managed to fit 64 LEDs into a perfect 1 inch cube!
XD

Just cr*ppy little test code running, and still some "buttoning up" to do. But, wanted to share.

Thanks!

Nice work, I have yet to make a cube and I've been using Arduino for ever.. I have like 5 Arduinos and countless custom Arduinos. I think I will put a SMD LED version on the drawing board..

codlink:
Nice work, I have yet to make a cube and I've been using Arduino for ever.. I have like 5 Arduinos and countless custom Arduinos. I think I will put a SMD LED version on the drawing board..

Thanks!

That would be sweet! Make it small enough to fit on a keychain... Or repurpose a thumb drive to house an Arduino (ATTiny) & mount cube on top.

Great job there 1ChicagoDave.
I have previously made this

this

3 x 3 x 3 cube controlled by nine IO's and was looking at how to progress to a 4 x 4 x 4 with 595 shift registers. Next I built a 4 x 4 matrix with two 595's just to try and work out how I might control that and hopefully later expand it to four levels. I started this thread but did no get very far despite the best intentions of a couple of other members who shared their code with me. Might you be able to give me any advice on how to proceed with this.
Thanks Pedro

Thanks!

I took a look at your other thread, schematics, etc...
Do you just have all cathodes tied to ground?

I just finished a crude schematic of my entire cube (to try to explain it to my brother). I can hopefully get that uploaded later today — it's on my laptop, I'm currently on my iPad.

But the gist of it is....
Each horizontal layer of 16 LEDs have all of their cathodes connected. Then, each vertical column has their anodes connected. So, all in all, I am controlling 16 anodes & 4 cathodes with my code. (I also attached each cathode lead to an NPN, and control the NPN with my Arduino.)
I have two shift registers (not daisy chained - I used old 74164's I found in an old box - only clock & data pins, no serial out or latch pins). Each shift register is controlling 8 anodes (two rows of columns) and I'm driving the NPN, cathode transistors, straight from Arduino (yes, with series resistor to base....for some of you out there. You know who you are. XD ).

My code is a bit sloppy. Depending on what I needed to do, I switched back and forth between simple "turn on this row of Anodes & this Cathode" and a form of multiplexing where I quickly cycled through each of four cathode layers "on, then off" turning on whichever LEDs I needed in a given layer while it's cathode was "ON". I did it all using "ShiftOut" and some binary byte which correlated to the position of LEDs I wanted to control.

I'm pretty sure that almost all of this will make zero sense until I post schematic & code, so I'll head over to my laptop in a few and get that posted.

Again, I KNOW my code is messy....and could be done A LOT more efficiently. I'm just posting it to try and help others. So, please be nice. XD

I'll get that posted in just a bit.

Ok, here's my (very crude, and quickly made) schematic. (Attached)
I started the schematic to design a "shield" to hold the shift registers and to connect the Arduino to the LED MiniCube board. I then, just added the LEDs and such to try and illustrate how it all works together. (And kinda crunched the current limit resistors into schematic at last minute... to avoid the inevitable comment about it.) There are a lot of overlapping nets. But, if you trace them back, it should be relatively easy to decipher.

And here's ALL of my code. (posted in parts because, "The message exceeds the maximum allowed length (9500 characters)."
I wasn't planning on sharing this just yet....so it's pretty messy. It's still very much a work in progress. There is a lot of code commented-out right now for testing purposes. And, I haven't commented/documented/explained as much as I intend to before "officially sharing" it with others. But, I would think (hope), most people should be able to make sense of (most of) it.

*** I'm also in the process of renaming some of my "patterns" so that they make more sense. They made sense to me at the time....but just a few days later I had no idea what I was thinking! :blush:
I had gone through a few different "methods" of controlling the lights. And, unfortunately, still have all of them being used right now.
I am, however, very open to some constructive criticism. I would very much like to streamline/optimize the code... as well as make it easier to add new patterns, randomness, etc... without having to manually devise the binary byte ("B11001101", etc...) for each sequence.

Thank you, and... I hope this doesn't just confuse you even more, Pedro! XD

/*
*
 * MiniCube LED Cube with 74164 shift registers
 * Original (and likely, inefficient) code, comments, and documentation
 * somehow pieced together by:
 * David Ratliff 
 * July, 2013
 * 
 * designed for use with my Pin-Source, 4x4, LED cube with 74164 shift registers attached to 16 anode leads
 * and 4 NPN (2N4401) transistors connected to each of 4 cathode leads (one for each horizontal layer of 16 LEDs).
 * 
 * ***Naming convention***
 * 
 * Cartesian Coordinate System used. With axis, (x, y) = (0, 0).
 *    X-Axis (y=0) is line of LEDs parallel, and closest, to the transistors on board
 *    Y-Axis (x=0) is line of LEDs parallel, and closest, to the Cathode leads coming from cube
 *    Z-Axis extends upwards from the board beginning with "1"(bottom layer) and ending with "4" (top layer)
 *
 * FUNCTIONS & THEIR NAMES 
 *------------------------
 *    After morphing through many permutations and made-sense-at-the-time naming schemes...
 *   I finally settled on one which, I beleive, makes the code easiest to understand.
 *   Here is a brief introduction (and REMINDER to myself!) - 
 *  "planes" contain 16 active LEDs. May be horizontal or vertical. function contains x, y, or z (and it's value) to indicate position
 *  "hinges" transition between planes. Usually "hinging" upon row of LEDs shared by both planes (starting & ending plane).
 *  "slashe" are angled planes which run through center of cube 
 *   "slants"  are angled planes which contain one corner-edge of cube - typically only use two rows/columns along one of axis
 *
 *
 */

#define data1 6     // PWM Pin
#define data2 4      // PWM pin

#define clock1 5   //PWM Pin
#define clock2 3    // PWM Pin

#define cathode3 11
#define cathode4 10
#define cathode2 9
#define cathode1 8

int Flow = 80;    // "delay" to hold patterns before shifting next pattern    ***Update this eventually to use 'millis' or some timer to avoid so much wasted time on 'delays'

long randNumber;      // holder for Random number from generator function

unsigned long previousMillis = 0;        // will store last time LED was updated    --  **Leftover from prev version? ** Don't think this is currently used in any functions. 

/*
// Intervals used in previous version of functions -- Not currently used
unsigned long intervalConstant = 3000;
unsigned long interval1 = (intervalConstant/4);  // interval at which to blink milliseconds)
unsigned long interval2 = (intervalConstant/2);
unsigned long interval3 = (3* intervalConstant/4);
unsigned long interval4 = intervalConstant;

*/

void setup()
{
  Serial.begin(9600);
  pinMode(A0, INPUT);    // to read "noise" as random number
  randomSeed(analogRead(A0));    // Seed Pseudo-RNG with noise from open/floating pin A0
  
  //  Set pins to shift registers as OUTPUT
  pinMode(clock1, OUTPUT);      // Clock for Shift Register 1
  pinMode(clock2, OUTPUT);      // Clock for Shift Register 2
  pinMode(data1, OUTPUT);      // Data for Shift Register 1
  pinMode(data2, OUTPUT);      // Data for Shift Register 1

  // Set shift register pins to a LOW "idle" state  --- *74164 Shift Register "clocks" on rising edge of digital signal
  digitalWrite(clock1, LOW);  
  digitalWrite(clock2, LOW);
  digitalWrite(data1, LOW);
  digitalWrite(data2, LOW);

  // set cathode pins to output
  pinMode(cathode1, OUTPUT);
  pinMode(cathode2, OUTPUT);
  pinMode(cathode3, OUTPUT);
  pinMode(cathode4, OUTPUT);
}

void loop()
{

   hingeX3Y0(Flow);    // from planeX3 to planeY0
   
   slantY1Y2(5, 5);
   slashY0Y3(5, 5);
   pinWheelL(5, 5);
   pinWheelL(5, 5);
   pinWheelL(5, 5);
   pinWheelL(5, 5);
   pinWheelL(5, 5);
   slantY0Y3(5, 5);
   
  /* planeZ(1, Flow);      // Bottom Layer
   planeZ(2, Flow);
   planeZ(3, Flow);
   planeZ(4, Flow);
   planeZ(3, Flow);
   planeZ(2, Flow);
   planeZ(1, Flow);
   
   */
  planeZ(1, Flow);

  hingeZ1Y3(5, 5);

  planeY3(Flow);

  hingeY3X3(Flow);
  hingeX3Y0(Flow);
  hingeY0X0(Flow);    // Hinges CCW from planeY0 to planeX0

  // Begin Small Sq up, Large Sq down

  hSquareSmall(1, Flow);
  hSquareSmall(2, Flow);
  hSquareSmall(3, Flow);
  hSquareSmall(4, Flow);

  hSquareLarge(4, Flow);
  hSquareLarge(3, Flow);
  hSquareLarge(2, Flow);
  hSquareLarge(1, Flow);


  hSquareSmall(1, Flow);
  hSquareSmall(2, Flow);
  hSquareSmall(3, Flow);
  hSquareSmall(4, Flow);

  hSquareLarge(4, Flow);
  hSquareLarge(3, Flow);
  hSquareLarge(2, Flow);
  hSquareLarge(1, Flow);

  hSquareSmall(1, Flow);
  hSquareSmall(2, Flow);
  hSquareSmall(3, Flow);
  hSquareSmall(4, Flow);

  hSquareLarge(4, Flow);
  hSquareLarge(3, Flow);
  hSquareLarge(2, Flow);
  hSquareLarge(1, Flow);
  // End Small Sq up, Large Sq down

  growSquareLarge(4, 40);
  sqPillarLg(5, 20);
  sinkSquareLarge(4, 40);
  growSquareSmall(4, 40);
  sqPillarSm(5, 20);
  sinkSquareSmall(4, 40);
  growSquareLarge(4, 40);
  sqPillarLg(5, 20);
  sinkSquareLarge(4, 40);
  growSquareSmall(4, 40);
  sqPillarSm(5, 20);
  sinkSquareSmall(4, 40);


  bitwiseRandomFall(100, 20);


  planeZ(1, Flow);      // Bottom Layer
  planeZ(2, Flow);
  planeZ(3, Flow);
  planeZ(4, Flow);
  planeZ(3, Flow);
  planeZ(2, Flow);
  planeZ(1, Flow);

  hingeY0X0(Flow);    // Hinges CCW from planeY0 
  hingeX0Y3(Flow);
  hingeY3X3(Flow);
  hingeX3Y0(Flow);    // back to planeY0

  slantY3Y0(5, 5);
  slashY3Y0(5, 5);
  slantY3Y2(5, 5);

  planeY3(Flow);

  hingeY3Z4(5,5);

  planeZ(4, Flow);      // "Plane" = 16 LEDs horizontally. "4" = Top Layer
  planeZ(3, Flow);      // Layer just above center
  planeZ(2, Flow);      // Layer just below center
  planeZ(1, Flow);      // Bottom Layer
  planeZ(2, Flow);
  planeZ(3, Flow);
  planeZ(4, Flow);

  hingeZ4Y3(5, 5);

  planeY3(Flow);
  planeY2(Flow);
  planeY1(Flow);
  planeY0(Flow);
  planeY1(Flow);
  planeY2(Flow);
  planeY3(Flow);

  hingeY3Z1(5, 5);



}   // End void loop()

MiniCubeShield_2_FULL.pdf (57.2 KB)

And now....some more of the code.

// Pattern Sequences//
void semiShift(int lightTime)    // GOAL: To shiftOut (less than a byte) new binary BETWEEN cathode changes!  --- NOT SUCCESSFUL....
{

  for(int j=0; j<255; j++)      // set to any range within 0-255 ( 8 bits )
  {
    cathodeOff(0);
    for(int cat = 4; cat > 0; cat--)             // turn on Cathodes 1 thru 4, one at time
    {
      // Send data to Cube
      for (int i = 0; i < 3; i++)              // Customized "shiftOut" function code
      {

        digitalWrite(data2, !!(B010 & (1 << i)));
        digitalWrite(clock2, HIGH);
        digitalWrite(clock2, LOW);		

      }

      for (int i = 0; i < 3; i++)              // Customized "shiftOut" function code
      {

        digitalWrite(data1, !!(B01 & (1 << (2 - i))));
        digitalWrite(clock1, HIGH);
        digitalWrite(clock1, LOW);		

      }      

      // Turn on ONE cathode
      cathodeOn(cat);        //  turn on/off cathodes from top to bottom  - ("Rain")
      if(cat < 4)
      {
        cathodeOff(cat+1);
      }  // end if cat
      // increase i
      j++;     
      // delay to see effect
      delay(2*lightTime);
    }    //end for cat
  }        // end for int i
}    // end semiShift


void bitwiseRandomLone(int lightTime)    
{
  for(int i=0; i<255; i++)      // set to any range within 0-255 ( 8 bits )
  {
    randNumber = random(255);                // generate "random" number from 0 -255
    cathodeOff(0);                                // turn ALL cathodes off prior to shift
    for(int cat = 4; cat > 0; cat--)             // turn on Cathodes 1 thru 4, one at time
    {
      int randNumber = random(255);              // generate "random" number from 0 -255

        // Send data to Cube
      shiftOut(data2, clock2, LSBFIRST, (randNumber & (randNumber-1)));        // keep it "random looking" on ShiftReg2
      shiftOut(data1, clock1, MSBFIRST, (i & randNumber));                // again, for ShiftReg1
      // Turn on ONE cathode
      cathodeOn(cat);                  //  turn on/off cathodes from top to bottom  - ("Rain")
      if(cat < 4)
      {
        cathodeOff(cat+1);
      }  // end if cat
      // increase i
      i++;     
      // delay to see effect
      delay(2*lightTime);
    }    //end for cat
  }        // end for int i
}    // end bitwiseRandomLone



void bitwiseRandomFall(int range, int lightTime)    
{
  for(int i=0; i<range; i++)      // set to any range within 0-255 ( 8 bits )
  {
    cathodeOff(0);
    for(int cat = 4; cat > 0; cat--)             // turn on Cathodes 1 thru 4, one at time
    {
      // Send data to Cube
      shiftOut(data2, clock2, LSBFIRST, (i & (5*i/3)));        // keep it "random looking" on ShiftReg2
      shiftOut(data1, clock1, MSBFIRST, (i & (7*i/2)));        // again, for ShiftReg1
      // Turn on ONE cathode
      cathodeOn(cat);        //  turn on/off cathodes from top to bottom  - ("Rain")
      if(cat < 4)
      {
        cathodeOff(cat+1);
      }  // end if cat
      // increase i
      i++;     
      // delay to see effect
      delay(2*lightTime);
    }    //end for cat
  }        // end for int i
}    // end bitwiseRandomFall


void bitwiseRain(int lightTime)      // Use bitwise & to create custom light pattern
{
  for(int i=140; i<255; i++)      // set to any range within 0-255 ( 8 bits )
  {
    cathodeOff(0);
    shiftOut(data2, clock2, LSBFIRST, (i & (i+111)));        // keep it "random looking" on ShiftReg2
    shiftOut(data1, clock1, MSBFIRST, (i & (i-213)));        // again, for ShiftReg1
    for(int cat = 4; cat > 0; cat--)             // turn on Cathodes 1 thru 4, one at time
    {
      cathodeOn(cat);        //  turn on/off cathodes from top to bottom  - ("Rain")
      if(cat < 4)
      {
        cathodeOff(cat+1);
      }  // end if cat
      delay(lightTime);
    }    //end for cat
  }        // end for int i
}    // end bitwiseRain


void bitwiseTwins(int lightTime)
{
  for(int i=130; i<200; i++)    // set to any range within 0-255 ( 8 bits )
  {
    cathodeOff(0);
    shiftOut(data2, clock2, LSBFIRST, (i & (i+1)));        // count (backwards?) 1- 255 on ShiftReg2
    shiftOut(data1, clock1, MSBFIRST, (i & (i-1)));        // count 1 - 255 on ShiftReg1
    for(int cat = 1; cat < 5; cat++)             // turn on Cathodes 1 thru 4, one at time
    {
      cathodeOn(cat);        // turn on/off cathodes from bottome to top
      if(cat>1)
      {
        cathodeOff(cat-1);
      }  // end if cat
      delay(lightTime);
    }    //end for cat
  }        // end for int i
}    // end bitwiseTwins


void binaryTwins(int lightTime)
{
  for(int i=100; i<155; i++)    // set to any range within 0-255 ( 8 bits )
  {
    cathodeOff(0);
    shiftOut(data2, clock2, LSBFIRST, i);        // count (backwards?) 1- 255 on ShiftReg2
    shiftOut(data1, clock1, MSBFIRST, i);        // count 1 - 255 on ShiftReg1
    for(int cat = 1; cat < 5; cat++)             // turn on Cathodes 1 thru 4, one at time
    {
      cathodeOn(cat);        // turn on/off cathodes from bottom to top - ("growth")
      if(cat>1)
      {
        cathodeOff(cat-1);
      }  // end if cat
      delay(lightTime);
    }    //end for cat
  }        // end for int i
}    // end Binary Twins


void binaryGrowth(int lightTime)      // WARNING! - USES LOTS OF CURRENT!!
// TOO MUCH for Arduino to handle.
// be sure to connect LEDs to own power source
//  ....AND CONNECT GROUNDS TOGETHER
{
  for(int i=0; i<510; i++)
  {
    if( i>=0 && i < 256)
    {
      cathodeOff(0);
      shiftOut(data2, clock2, MSBFIRST, B00000000);    // send all 0 to ShiftReg2
      shiftOut(data1, clock1, MSBFIRST, i);            // count 1 - 255 on ShiftReg1
      for(int cat = 1; cat < 5; cat++)                 // turn on Cathodes 1 thru 4, one at time
      {
        cathodeOn(cat);
        if(cat>1)
        {
          cathodeOff(cat-1);
        }  // end if cat
        delay(lightTime);
      }    //end for cat
    }      //end if

    if( i>=256 && i < 510)
    {
      cathodeOff(0);
      shiftOut(data1, clock1, MSBFIRST, B11111111);    // send all 1 to ShiftReg1
      shiftOut(data2, clock2, MSBFIRST, i-255);            // count 1- 255 on ShiftReg12
      for(int cat = 1; cat < 5; cat++)              // turn on Cathodes 1 thru 4, one at time
      {
        cathodeOn(cat);
        if(cat>1)
        {
          cathodeOff(cat-1);
        }  // end if cat
        delay(lightTime);
      }    // end for cat
    }      // end  for
  }        // end  for
}          // end void binaryGrowth


// CONTROL CATHODES ON/OFF

void cathodeOff(int cathNum)
{
  if (cathNum == 1)
  {
    digitalWrite(cathode1, LOW);
  }     // end if 1
  if (cathNum == 2)
  {
    digitalWrite(cathode2, LOW);
  }    // end if 2
  if (cathNum == 3)
  {
    digitalWrite(cathode3, LOW);
  }    // end if 3
  if (cathNum == 4)
  {
    digitalWrite(cathode4, LOW);
  }    // end if 4
  if (cathNum == 0)
  {
    digitalWrite(cathode1, LOW);
    digitalWrite(cathode2, LOW);
    digitalWrite(cathode3, LOW);
    digitalWrite(cathode4, LOW);
  }  // end if ALL
}    // end void CathodeOFF


void cathodeOn(int cathNum)      // Turn one or all cathodes on
{
  if (cathNum == 1)              // Bottom layer
  {
    digitalWrite(cathode1, HIGH);
  }     // end if 1
  if (cathNum == 2)          
  {
    digitalWrite(cathode2, HIGH);
  }    // end if 2
  if (cathNum == 3)
  {
    digitalWrite(cathode3, HIGH);
  }    // end if 3
  if (cathNum == 4)              // Top layer
  {
    digitalWrite(cathode4, HIGH);
  }    // end if 4
  if (cathNum == 0)              // Turn ALL cathodes/Layers on
  {
    digitalWrite(cathode1, HIGH);
    digitalWrite(cathode2, HIGH);
    digitalWrite(cathode3, HIGH);
    digitalWrite(cathode4, HIGH);
  }  // end if 0 / ALL
}    // end void CathodeOn

// *******  END CONTROL CATHODES *************

// ********  3D SHAPES - Begin  ***********

void sqPillarSm(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    hSquareSmall(1, lightTime);
    hSquareSmall(2, lightTime);
    hSquareSmall(3, lightTime);
    hSquareSmall(4, lightTime);
  }      // End for i frameNum
}    // End sqPillarSm

void sqPillarLg(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    hSquareLarge(1, lightTime);
    hSquareLarge(2, lightTime);
    hSquareLarge(3, lightTime);
    hSquareLarge(4, lightTime);
  }      // End for i frameNum
}    // End sqPillarLg

// *********  END  --- 3D SHAPES   ************

A bit more....

// *********   HORIZONTAL SEQUENCES ************** 

//********* Static Horizontal Shapes  ************
void planeZ(int level, int lightTime)
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B11111111);
  shiftOut(data1, clock1, LSBFIRST, B11111111);
  cathodeOn(level);
  delay(lightTime);
}  // end void planeZplaneZ()

void hSquareLarge(int level, int lightTime)
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B10011111);
  shiftOut(data1, clock1, LSBFIRST, B11111001);
  cathodeOn(level);
  delay(lightTime);
}  // end void hSquareLarge

void hSquareSmall(int level, int lightTime)
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B01100000);
  shiftOut(data1, clock1, LSBFIRST, B00000110);
  cathodeOn(level);
  delay(lightTime);
}  // end void hSquareSmall


//********* END  ** Static Horizontal Shapes  ************

//******** BEGIN  ** Vertical Grow & Sink  ************

void growSquareLarge(int level, int lightTime)
{

  cathodeOff(0);
  // build square level by level from bottom to top

  for (int i = 1; i <= level; i++)
  {
    shiftOut(data2, clock2, LSBFIRST, B10011111);
    shiftOut(data1, clock1, LSBFIRST, B11111001);
    cathodeOn(i);
    delay(lightTime);
  }  //end for
}  // end void growSquareLarge

void growSquareSmall(int level, int lightTime)
{
  cathodeOff(0);
  // build square level by level from bottom to top
  for (int i = 1; i <= level; i++)
  {
    shiftOut(data2, clock2, LSBFIRST, B01100000);
    shiftOut(data1, clock1, LSBFIRST, B00000110);
    cathodeOn(i);
    delay(lightTime);
  }  // end for
}  // end void growSquareSmall

void sinkSquareLarge(int level, int lightTime)
{
  cathodeOff(0);
  // turn whole square on
  shiftOut(data2, clock2, LSBFIRST, B10011111);
  shiftOut(data1, clock1, LSBFIRST, B11111001);
  cathodeOn(0);
  delay(lightTime);

  // turn off level one by one from top to bottom
  for (int i = level; i > 0; i--)
  {
    shiftOut(data2, clock2, LSBFIRST, B10011111);
    shiftOut(data1, clock1, LSBFIRST, B11111001);
    cathodeOff(i);
    delay(lightTime);
  }  //end for
}  // end void sinkSquareLarge

void sinkSquareSmall(int level, int lightTime)
{
  cathodeOff(0);
  // turn whole square on
  shiftOut(data2, clock2, LSBFIRST, B01100000);
  shiftOut(data1, clock1, LSBFIRST, B00000110);
  cathodeOn(0);
  delay(lightTime);
  // turn off level one by one from top to bottom
  for (int i = level; i > 0; i--)
  {
    cathodeOff(i);
    delay(lightTime);
  }  // end for
}  // end void sinkSquareSmall

//  ********END  **  Vertical Growth  ****************

void hFLipUp1(int lightTime)    // flips up from planeX0 to planeZ4
{
  cathodeOff(0);

  shiftOut(data2, clock2, LSBFIRST, B00010001);
  shiftOut(data1, clock1, LSBFIRST, B00010001);
  cathodeOn(0);
  delay(lightTime);

  //first "step"

  //**PseudoCode ***loop this for "lightTime" milliseconds????
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00010001);
  shiftOut(data1, clock1, LSBFIRST, B00010001);
  cathodeOn(4);
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00100010);
  shiftOut(data1, clock1, LSBFIRST, B00100010);
  cathodeOn(3);
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B01000100);
  shiftOut(data1, clock1, LSBFIRST, B01000100);
  cathodeOn(2);
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B10001000);
  shiftOut(data1, clock1, LSBFIRST, B10001000);
  cathodeOn(1);

  // end first "step"

}  // end hFlipUp1


// END HORIZONTAL SEQUENCES  

// VERTICAL SEQUENCES

//  ************  Verical WIDES - Y-axis "planes of Light"  ******************


void planeX3(int lightTime)          // "Wall of light" entire row, all layers.   Header side of board
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B10001000);
  shiftOut(data1, clock1, LSBFIRST, B10001000);
  cathodeOn(0);
  delay(lightTime);

}

void planeX2(int lightTime)
{
  cathodeOff(0);
  digitalWrite(cathode4, LOW);
  shiftOut(data2, clock2, LSBFIRST, B01000100);
  shiftOut(data1, clock1, LSBFIRST, B01000100);
  cathodeOn(0);
  delay(lightTime);
}


void planeX1(int lightTime)
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00100010);
  shiftOut(data1, clock1, LSBFIRST, B00100010);
  cathodeOn(0);
  delay(lightTime);
}

void planeX0(int lightTime)                    // "Wall of light" entire row, all layers.   Cathode side of board
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00010001);
  shiftOut(data1, clock1, LSBFIRST, B00010001);
  cathodeOn(0);
  delay(lightTime);
}

//  ************END Verical Wides - Y-axis "Walls of light"  ******************


//  ************  Verical Slices - X-axis "Walls of light"  ******************


void planeY0(int lightTime)                // "Wall of light" entire row, all layers.   Transistor side of board
{  
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00001111);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
  cathodeOn(0);
  delay(lightTime);
}  // End void vSlice 1

void planeY1(int lightTime)
{  
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B11110000);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
  cathodeOn(0);
  delay(lightTime);
}  // End void vSlice 2

void planeY2(int lightTime)
{  
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00001111);
  cathodeOn(0);
  delay(lightTime);
}  // End void vSlice 3

void planeY3(int lightTime)                          // "Wall of light" entire row, all layers.   Empty end of board
{  
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B11110000);
  cathodeOn(0);
  delay(lightTime);
}  // End void vSlice 4

//  ************END Verical Slices - X-axis "Walls of light"  ******************

// ************ Flat turns, hinges, transitions - *****************
void hingeY0X0(int lightTime)  // Turns from planeY0 to planeX0
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00001111);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B11000011);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00100001);
  shiftOut(data1, clock1, LSBFIRST, B10000100);  
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00010001);
  shiftOut(data1, clock1, LSBFIRST, B01000010);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00010001);
  shiftOut(data1, clock1, LSBFIRST, B00010001);
  cathodeOn(0);
  delay(lightTime);
}  // end hingeY0X0

void hingeX0Y3(int lightTime)    // turns from planeX0 to planeY3 - Cathode side
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00010001);
  shiftOut(data1, clock1, LSBFIRST, B00010001);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00100010);
  shiftOut(data1, clock1, LSBFIRST, B00010001);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B01001000);
  shiftOut(data1, clock1, LSBFIRST, B00010010);  
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00111100);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B11110000);
  cathodeOn(0);
  delay(lightTime);
}    // end hingeX0Y3


void hingeY3X3(int lightTime)    // turns from planeY3 to planeX3 - Cathode side
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B11110000);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B11000011);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00100001);
  shiftOut(data1, clock1, LSBFIRST, B10000100);  
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B01000100);
  shiftOut(data1, clock1, LSBFIRST, B10001000);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B10001000);
  shiftOut(data1, clock1, LSBFIRST, B10001000);
  cathodeOn(0);
  delay(lightTime);
}      // End hingeY3X3


// *****HINGE UP & DOWN FUNCTIONS ***********
void hingeY3Z4(int lightTime, int frameNum)      // Hinges plane UP from Y3 to Z4
{
  slantY2Y3(lightTime, frameNum);
  slashY0Y3(lightTime, frameNum);
  slantZ3Y0Y3(lightTime, frameNum);
}    // End hingeY3Z4

void hingeZ4Y3(int lightTime, int frameNum)      // Hinges plane DOWN from Y3 to Z4
{
  slantZ3Y0Y3(lightTime, frameNum);
  slashY0Y3(lightTime, frameNum);
  slantY2Y3(lightTime, frameNum);

}    // End hingeZ4Y3


void hingeZ1Y3(int lightTime, int frameNum)      // Hinges plane UP from Z1 to Y3
{
  slantY3Y0(lightTime, frameNum);
  slashY3Y0(lightTime, frameNum);
  slantY3Y2(lightTime, frameNum);

}    // End hingeZ1Y3

void hingeY3Z1(int lightTime, int frameNum)      // Hinges plane DOWN from Y3 to Z1
{
  slantY3Y2(lightTime, frameNum);
  slashY3Y0(lightTime, frameNum);
  slantY3Y0(lightTime, frameNum);


}    // End hingeY3Z1

// *****  END --- HINGE UP & DOWN FUNCTIONS ***********
void hingeX3Y0(int lightTime)    // turns from planeX3 to planeY0 - Cathode side
{
  cathodeOff(0);
  shiftOut(data2, clock2, LSBFIRST, B10001000);
  shiftOut(data1, clock1, LSBFIRST, B10001000);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B10001000);
  shiftOut(data1, clock1, LSBFIRST, B01000100);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B01001000);
  shiftOut(data1, clock1, LSBFIRST, B00010010);  
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00111100);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
  cathodeOn(0);
  delay(lightTime);
  shiftOut(data2, clock2, LSBFIRST, B00001111);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
  cathodeOn(0);
  delay(lightTime);
}    // end hingeX3Y0


void slashY1Y2(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}

void slashY0Y3(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B00001111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11110000);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slantY1Y2(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B00001111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00001111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slantY0Y3(int lightTime, int frameNum)
{

  for (int i = 0; i <= (2*frameNum); i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11111111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11111111);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slashZ2Y0Z3Y3(int lightTime, int frameNum)
{

  for (int i = 0; i <= (2*frameNum); i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11111111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11111111);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slashY2Y1(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}

void slashY3Y0(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B00001111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B11110000);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11110000);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slantY3Y2(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11110000);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11110000);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slantY2Y3(int lightTime, int frameNum)
{

  for (int i = 0; i <= frameNum; i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11110000);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11110000);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);

    // planeY2
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);

    // planeY3    
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B00001111);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}    // End slantY2Y3

The last bit that is being used...

void slantZ3Y0Y3(int lightTime, int frameNum)
{

  for (int i = 0; i <= (2*frameNum); i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11111111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11111111);
    cathodeOn(4);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}    // End slantZ3Y0Y3

void slashZ2Y3Z3Y0(int lightTime, int frameNum)
{

  for (int i = 0; i <= (2*frameNum); i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11111111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(3);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11111111);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}


void slantY3Y0(int lightTime, int frameNum)
{

  for (int i = 0; i <= (2*frameNum); i++)
  {
    cathodeOff(0);
    //  planeY0
    shiftOut(data2, clock2, LSBFIRST, B11111111);
    shiftOut(data1, clock1, LSBFIRST, B00000000);
    cathodeOn(2);
    delay(lightTime);
    cathodeOff(0);
    // planeY1 
    shiftOut(data2, clock2, LSBFIRST, B00000000);
    shiftOut(data1, clock1, LSBFIRST, B11111111);
    cathodeOn(1);
    delay(lightTime);
    cathodeOff(0);
  }    //end for

}

void pinWheelL(int lightTime, int frameNum)      // spins in middle from slashY0Y3 to (just before) slashY0Y3
{
  //    Each "set" goes halfway
  slashY0Y3(lightTime, frameNum);
  slashZ2Y0Z3Y3(lightTime, frameNum);
  slashZ2Y3Z3Y0(lightTime, frameNum);
  //  Second "set" completes the '360'

  slashY3Y0(lightTime, frameNum);
  slashY2Y1(lightTime, frameNum); 
  slashY1Y2(lightTime, frameNum);
}

void halfPinLBot(int lightTime, int frameNum)    // Bottom "half" of pinwheel  -- useful for transistion to slashY3Y0 / from slashY0Y3
{
  slashY0Y3(lightTime, frameNum);
  slashZ2Y0Z3Y3(lightTime, frameNum);
  slashZ2Y3Z3Y0(lightTime, frameNum);
}

void halfPinLTop(int lightTime, int frameNum)   // Top "half" of pinwheel  -- useful for transistion to slashY0Y3 / from slashY3Y0
{
  slashY3Y0(lightTime, frameNum);
  slashY2Y1(lightTime, frameNum); 
  slashY1Y2(lightTime, frameNum);
}

And this.... is just some "reference code" and individual LED code to help me from getting all turned around. Also, I was thinking of possibly incorporating later.
....If I need to.

//    Individual LED Coordinates - (x,y) - axis = corner of transistors (x) & cathodes (y)


void oneOne()
{
  shiftOut(data2, clock2, LSBFIRST, B00000001);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void oneTwo()
{
  shiftOut(data2, clock2, LSBFIRST, B00000010);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void oneThree()
{
  shiftOut(data2, clock2, LSBFIRST, B00000100);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void oneFour()
{
  shiftOut(data2, clock2, LSBFIRST, B00001000);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void twoOne()
{
  shiftOut(data2, clock2, LSBFIRST, B00010000);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void twoTwo()
{
  shiftOut(data2, clock2, LSBFIRST, B00100000);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void twoThree()
{
  shiftOut(data2, clock2, LSBFIRST, B01000000);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void twoFour()
{
  shiftOut(data2, clock2, LSBFIRST, B10000000);
  shiftOut(data1, clock1, LSBFIRST, B00000000);
}

void threeOne()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00000001);
}

void threeTwo()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00000010);
}

void threeThree()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00000100);
}

void threeFour()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00001000);
}

void fourOne()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00010000);
}

void fourTwo()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B00100000);
}

void fourThree()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B01000000);
}

void fourFour()
{
  shiftOut(data2, clock2, LSBFIRST, B00000000);
  shiftOut(data1, clock1, LSBFIRST, B10000000);
}


/*
Single lines  --- REFERENCE BINARY --------
 
 planeY0   --  Transistor Side of Board
 shiftOut(data2, clock2, LSBFIRST, B00001111);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 planeY1
 shiftOut(data2, clock2, LSBFIRST, B11110000);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 planeY2
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00001111);
 
 planeY3    
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B11110000);
 
 
 planeX0    --    Cathode Side of Board
 shiftOut(data2, clock2, LSBFIRST, B00010001);
 shiftOut(data1, clock1, LSBFIRST, B00010001);
 
 planeX1
 shiftOut(data2, clock2, LSBFIRST, B00100010);
 shiftOut(data1, clock1, LSBFIRST, B00100010);
 
 planeX2
 shiftOut(data2, clock2, LSBFIRST, B01000100);
 shiftOut(data1, clock1, LSBFIRST, B01000100);
 
 planeX3    --    Header Side of Board
 shiftOut(data2, clock2, LSBFIRST, B10001000);
 shiftOut(data1, clock1, LSBFIRST, B10001000);
 
 
 Cathode 1    --    Bottom Layer
 cathodeOn(1);
 cathodeOff(1);
 
 Cathode 2
 cathodeOn(2);
 cathodeOff(2);
 
 Cathode 3
 cathodeOn(3);
 cathodeOff(3);
 
 Cathode 4    --    Top Layer
 cathodeOn(4);
 cathodeOff(4);
 
 ALL CATHODES
 cathodeOn(0);
 cathodeOff(0);
 
 ****INDIVIDUAL LEDs / Columns  ****
 
 Given in X,Y coordinates.
 X = "vSlice" - running from Cathode side of board to Headers
 Y = "vWide"  -Running from Transistor side of board to empty end of board
 
 (1,1)
 shiftOut(data2, clock2, LSBFIRST, B00000001);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (1,2)
 shiftOut(data2, clock2, LSBFIRST, B00000010);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (1,3)
 shiftOut(data2, clock2, LSBFIRST, B00000100);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (1,4)
 shiftOut(data2, clock2, LSBFIRST, B00001000);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (2,1)
 shiftOut(data2, clock2, LSBFIRST, B00010000);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (2,2)
 shiftOut(data2, clock2, LSBFIRST, B00100000);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (2,3)
 shiftOut(data2, clock2, LSBFIRST, B01000000);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (2,4)
 shiftOut(data2, clock2, LSBFIRST, B10000000);
 shiftOut(data1, clock1, LSBFIRST, B00000000);
 
 (3,1)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00000001);
 
 (3,2)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00000010);
 
 (3,3)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00000100);
 
 (3,4)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00001000);
 
 (4,1)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00010000);
 
 (4,2)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B00100000);
 
 (4,3)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B01000000);
 
 (4,4)
 shiftOut(data2, clock2, LSBFIRST, B00000000);
 shiftOut(data1, clock1, LSBFIRST, B10000000);
 
 
 */

WOW! And that's all of it.

** I plan on making a library out of most of it! (I just need to figure out how to do that....)
That's (partly) why I've done it the way I have....and included a lot of functions/patterns/sequences that aren't currently being used. I just sort of wrote any/all functions I thought might be useful.... got them working...and plan to call them if/when I need to.

Thanks!

Thanks for all that information Dave, I wasn't expecting such a comprehensive reply. Well done XD Yes I did have all the cathodes connected to ground in that crude matrix that I made. Maybe that why I never go too far with it.I am pretty busy with other things right at this moment, but in the near future I will definitely be trying out your cube and seeing how it goes for me. I just thought that while your initial post was "fresh", so to speak, I would ask you for some information and you have certainly provided me with plenty to digest XD

Thank you again, and I will let you know how I go when I get around to trying it all out, Pedro.

1ChicagoDave,

Nice work. Tell me, what's the music you've chosen? I could play that loud all day!
Not sure which I like more - your impeccable soldering and positioning of the leds, or the music. :slight_smile:

Not a problem.

Like I said, once I get the kinks worked out....and tidy it up a bit, I plan to make a library out of all the functions, patterns, motions, etc. After I do that, and document everything better, I'll post it all online somewhere (Github? Instructables?), and provide a link here.

I'd REALLY like to figure a way to use even less Arduino pins and get it all to fit into a package small enough to make a keychain out of it! :grin: Maybe even an all SMD version...?
I'm thinking something kinda similar in design to the DigiSpark — Digistump - Home of the Digispark - built in USB connection, and maybe a small button / IR sensor / tilt switch / something...to provide simple controls. That ought to keep me busy for a while.

As far as yours goes....I really think the key is being able to control both the anodes AND cathodes in some way. Keep us updated whenever you get back around to it!

enhzflep:
1ChicagoDave,

Nice work. Tell me, what's the music you've chosen? I could play that loud all day!
Not sure which I like more - your impeccable soldering and positioning of the leds, or the music. :slight_smile:

Ha! Thanks on both counts!
Yeah...that was a lot of soldering. I owe a lot of the quality to my liberal use of flux. — I had to soak the entire cube in rubbing alcohol for a while just to clean it all off after I was finished.

The music is just one of the stock background tracks from iMovie on my iPad (I shot & edited it all on iPad). Then I added some sound effects as filler in certain spots — camera shutter, race car, stereotypical-movie-style-build-suspense-sound, etc..

I need to post an updated video now that I have my cube doing more interesting patterns & such. And, I think I need to show it next to a quarter or something to demonstrate how small it really is. But, I'll make sure to keep the same background track! XD

Thanks again -

:smiley: You're welcome.
Heh heh. I was just the same when soldering jewellery. One must try pretty hard to have too much flux most times.

Bugger! I hadn't even considered it might be a stock music clip. To be honest, I was halfway expecting "my mate made it" or something similar..

Yes! Something for scale would be pretty neat. If I could be so forward, I'd suggest that a ruler would be a more universally-known implement to display the scale with. (I'm in Aus - wouldn't know a quarter unless I read one side of it, much less how big they are)

Hey you know, I've got an 8channel relay shield here, from Freetronics. The neat thing is that it uses I2C. This means you get up to 64 outputs just using 2 arduino pins. Pins that can of course, be used for other things 'simultaneously' (or at least, one after the other, faster than the human vision system can detect)

Anyway, some details are here: RELAY8 8-Channel Relay Driver Shield Quickstart Guide | Freetronics
To quote the important part -

"When communicating with the shield, your sketch must specify the I2C address of the particular shield it wants to talk to. With all jumpers removed (the default) the address is 0x20. All possible addresses are shown in the table below. "0" shows the jumper is off, "1" shows the jumper is on. Up to eight 8-Channel Relay Driver Shields can be stacked and addressed independently, giving you up to 64 relay output channels using only two pins on your Arduino."

The i/o expander chip used is
MP23017-E/SO
1132DM6

Digikey has them for $1 each in a 28ssop package, here: MCP23S17T-E/SS Microchip Technology | Integrated Circuits (ICs) | DigiKey
Given that it has pin spacing of ~1mm, it shouldn't be that bad to solder.

Though, if you're really after teeny, you can get it in a qfn28 (6mm x 6mm - 0.25" x 0.25") package for about $1.7 MCP23017T-E/ML Microchip Technology | Integrated Circuits (ICs) | DigiKey

I hear that heat-embossing pens are pretty good at reflow soldering, though they cost around AU $30 and you can get a temperature controlled SMT reflow station for about AU $70 or $80.

Subscribed to your youtube, looking forward to more..... UP LOUD! XD