Flying LED matrix

Heres the code to run a 4x4x4 LED cube. It uses a loop to cycle through each of the 4 layers, and another loop and an array to hold the data for each column in a single plane. Its not exactly what you want, but its an example of how you may do something similar.

// OCT32012 editing changes to adapt this program to work with shift registers,
// and to work with Common Cathode LED cube. hippynurd@gmail.com

#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 10 // 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

B0001,B0000,B0000,B0000,B0001,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
B0011,B0000,B0000,B0000,B0011,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
B0011,B0010,B0000,B0000,B0011,B0010,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
B0011,B0011,B0000,B0000,B0011,B0011,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
B0110,B0110,B0000,B0000,B0110,B0110,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
B0000,B0000,B0000,B0000,B0110,B0110,B0000,B0000,B0110,B0110,B0000,B0000,B0000,B0000,B0000,B0000,10,
B0000,B0000,B0000,B0000,B0000,B0110,B0110,B0000,B0000,B0110,B0110,B0000,B0000,B0000,B0000,B0000,10,
B0000,B0000,B0000,B0000,B0000,B0000,B0110,B0110,B0000,B0000,B0110,B0110,B0000,B0000,B0000,B0000,10,
// NOTE: Most of the data was snipped out to fit in this forum posting



// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 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
*/
// Just a note to say we dont do things this way anymore. Data is serialized
// to pin 7 via 74hc595 shift registers, and the planes(layers) are controlled 
// by pins 11,10,9,6. The first shift register controls the first 8 pins, the
// second shift register controls pins 9-16.
// Looking down on the cube, the column pin matrix looks like this:

// 16 15 14 13
//
// 12 11 10  9
//
//  8  7  6  5  
//
//  4  3  2  1

// This code is for common cathnode, meaning ground the plane(layer), and send 5 volts to
// the column to illuminate the individual led.

 
//OLD
//int LEDPin[] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 14, 15};
//int PlanePin[] = {16, 17, 18, 19};
//NEW
int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int PlanePin[] = {11, 10, 9, 6};
int dataPin = 7; //Data  I added these for Shift Register
int clockPin = 12; // Clock 
int latchPin = 13; // Latch

// 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 pins for serial output
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, 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
int pinState; //pinState is used to send the correct bit to the data pin

// 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 (low is on, high is 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++;
}
*/
// I used code from shiftout, to redo this to serialize the plane data
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
  
 digitalWrite(clockPin, 0);
   
// digitalWrite( dataPin, PatternBuf[patbufidx] & (1 << ledcol) );
if (PatternBuf[patbufidx] & (1 << ledcol))
    {
      pinState= 1;  // Flip these bits to suit your cubes common lead (cathode or anode)
    }
    else
    {
      pinState= 0;  // Flip these bits to suit your cubes common lead (cathode or anode)
    }
 
    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(dataPin, pinState); // this is where data is sent to the shift register.
    //register shifts bits on upstroke of clock pin
    digitalWrite(clockPin, 1);

ledpin++;
}
patbufidx++;
}
digitalWrite(latchPin, 1);

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