Big RGB Table Finally Needs Code

I see. The configuration you are talking about really comes down to how you plan to put data into the arrays I described that will make up the color patterns.
I personally think that splitting the data for each LED up across multiple locations would be awkward (i.e.slow) to make changes to as your code reacts to button pushes & stuff. Having 3 adjacent bits for an LED would seem, to me, to be easier to manage.
However, lots of real programmers here are great with functions & stuff, so if you wanted to create an array of 5 words across by24 locations deep (or as needed, I forgot the width/depth you had) where the bits were arranged like this to represent the LEDs going across the table, then Im sure it could be managed.

LED0 0, 12, 24
LED1 1, 13, 25
LED2 2, 14, 26
LED3 3, 15, 27
LED4 4, 16, 28
LED5 5, 17, 29
LED6 6, 18, 30
LED7 7, 19, 31
LED8 8, 20, 32
LED9 9, 21, 33
LED10 10, 22, 34
LED11 11, 23, 35

ok, i think for ease of programming, since im so new and all, i will go with the first configuration. I tried modifieing some of your example code, since i have a 12x24 matrix (12 RGBs) so really 36x24

// code for an 36 x 24 array (12 RGB LEDs, 24 columns) as an example
// not all code parts shown, just the highlights
// set up an array for the cathode drives
byte cathodeslower[ ] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0,0,0,0,0};  // walking 1 for lower 8 NPNs 
byte cathodesmid[ ] = {0,0,0,0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0}; //walking for mid 8 NPNs ???????? 
byte cathodeshigher[ ] = {0,0,0,0,0,0,0,0,0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80};  // walking 1 for upper 8 NPNs
byte anodes1 [12]; // array to hold 1st 3rd of RGB info, like red?
byte anodes2 [12]; // array to hold 2nd 3rd of RGB info, like blue?
byte anodes3 [12]; // array to hold 3rd 3rd of RGB info, like green?
byte columncount;
byte oe = 12; 
unsigned long updateTime = 0;

void setup(){
pinMode (oe/, OUTPUT);
digitalWrite (oe/, HIGH);
SPI.begin;
}

void loop(){
// set up for blink without delay operation
if (millis() >=updateTime){
// yes, set up for next update
updateTime = updateTime +2; // update a column every 2 milliseconds, 16 columns at ~24 Hz rate
digitalWrite (oe, HIGH);  // turn off display
SPI.transfer (anodes1[columncount]); // update anodes
SPI.transfer (anodes2[columncount]); // update anodes
SPI.transfer (anodes3[columncount]); // update anodes
SPI.transfer (cathodeslower[columncount]); // turn on a cathode
SPI.transfer (cathodesupper[columncount]); // turn on a cathode
digitalWrite (oe, LOW); / turn display back on
columncount = columncount + 1; // update for next column
if (columncount == 24){columncount = 0;} // reset if reach the end
} //end display refresh

// now the fun part, for you!
// read buttons, or whatever processing you plan to do for patterns, etc., 
// and update anodes1, anodes2, anode3 as needed
} // end void loop

I really dont know about that cathodemid section, mostly guessing when i wrote that. But i did manage to do my research on hex, so at least that is understandable now. Still a little fuzzy on arrays.

Looking like a good start.
Maybe populate the anodes arrays as test starting condition and see if this works. Then start the array changing code.

Sounds good, too bad I won't be home until Sunday....

Do you think you could show me an example of how I could get it to slowly cycle through all the columns? Like turn on red for column 1 then wait a second then move on to column 2 repeat. When it gets to the end, that is, it's gone through all 24 columns, then repeat with blue, then green, then the other combinations?? Not sue where to start for that... Thank you!!

Do what you had and thrown in a delay afterwards?

Well you seem to have timing in it. The code looks like it might potentially work. The devil is in the detail in your case ... are you bit patterns right? Only you can say that.

Can give it a shot a little later.

Thanks CrossRoads, id really appreciate it.

Ok, maybe something like this

#include <SPI.h>

// code for an 36 x 24 array (12 RGB LEDs, 24 columns) as an example
// not all code parts shown, just the highlights
// set up an array for the cathode drives
byte cathodeslower[ ] = {
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // walking 1 for lower 8 NPNs 
byte cathodesmid[ ] = {
  0,0,0,0,0,0,0,0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0,0,0,0,0,0,0,0}; //walking for mid 8 NPNs ???????? 
byte cathodeshigher[ ] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80};  // walking 1 for upper 8 NPNs
  
byte anodes1 [12]; // array to hold 1st 3rd of RGB info, like red?
byte anodes2 [12]; // array to hold 2nd 3rd of RGB info, like blue?
byte anodes3 [12]; // array to hold 3rd 3rd of RGB info, like green?
byte columncount;
byte oe = 12; 
unsigned long updateTime = 0;
unsigned long exampleTime = 0;
byte  Red = 0; // arrays go from 0 to 11
byte  Green = 12;
byte  Blue = 12;

void setup(){
  pinMode (oe, OUTPUT);
  digitalWrite (oe, HIGH);
  SPI.begin;

}

void loop(){
  // set up for blink without delay operation
  if (millis() >=updateTime){
    // yes, set up for next update
    updateTime = updateTime +2; // update a column every 2 milliseconds, 16 columns at ~24 Hz rate
    digitalWrite (oe, HIGH);  // turn off display
    SPI.transfer (anodes1[columncount]); // update anodes
    SPI.transfer (anodes2[columncount]); // update anodes
    SPI.transfer (anodes3[columncount]); // update anodes
    SPI.transfer (cathodeslower[columncount]); // turn on a cathode
    SPI.transfer (cathodesmid[columncount]); // turn on a cathode
    SPI.transfer (cathodeshigher[columncount]); // turn on a cathode
    digitalWrite (oe, LOW);  //turn display back on
      columncount = columncount + 1; // update for next column
    if (columncount == 24){
      columncount = 0;
    } // reset if reach the end
  } //end display refresh

  // now the fun part, for you!
  // read buttons, or whatever processing you plan to do for patterns, etc., 
  // and update anodes1, anodes2, anode3 as needed
  if (millis() >= exampleTime){
    exampleTime = exampleTime + 500; // 1/2 second changes
    if (Red < 12){
      anodes1[Red] = 0; // turn off prior LED
      Red = Red + 1; // set up for next LED
      if (Red == 12){  // if at last LED, set up next color
        Blue = 0;
      }
      else {
        anodes1[Red] = 1; // turn on next LED
      }
    }
    if (Blue<12){
      anodes2[Blue] = 0;
      Blue = Blue + 1;
      if (Blue == 12){
        Green = 0;
      }
      else{
        anodes2[Blue] = 1;
      }
    }
    if (Green <12){
      anodes3[Green] = 0;
      Green = Green + 1;
      if (Green == 12){ 
        Red = 0;
      }
      else{
        anodes3[Green] = 1;
      }
    }
  }

} // end void loop

Thanks, I'll give it a try tomarrow.

PHEW. ok sorry about the delay, lots of stuff to do and all that. I FINALLY got some lights on! (just spend 2 1/2 hours doing some trial and error and working my way up on code) Minus 2 leds that need replacing and what i think to be a MOSFET that might be troubled, it works perfectly! you can see in the pics the column that needs replacing, and the 2 leds that are out, one has a blue out, the other has a red. Unfortunately your code didnt work... I tried some manipulations but i really dont know what i am doing, its like trying to build the Eiffel Tower out of legos while wearing boxing gloves. But hey, who doesnt love to learn? I worked my way up to this code:

#include <SPI.h>

const int oe = 10;

byte chip1 = 0xFF;
byte chip2 = 0xFF;
byte chip3 = 0xFF;
byte chip4 = 0xFF;
byte chip5 = 0xFF;

unsigned int time = 500;

void setup(){
  SPI.begin();
  pinMode(oe, OUTPUT);
  digitalWrite(oe, LOW);
}

void loop(){
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x80);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x40);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x20);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x10);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x08);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x04);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x02);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0x01);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  
  SPI.transfer(0);
  SPI.transfer(0x80);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x40);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x20);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x10);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x08);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x04);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x02);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0);
  SPI.transfer(0x01);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  
  SPI.transfer(0x80);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x40);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x20);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x10);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x08);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x04);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x02);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
  SPI.transfer(0x01);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  delayMicroseconds(time);
}

Ewwwww, isnt that gross?? Do you know a basic way to shorten it? Fortunately the SPI is working, i started
with shiftOut(), but there was a ton of flickering, i tried messing with the output enabler, but no good.

now then; what suggestions do you have for learning how to make more complicated animations? Your code seems like it would work, and i have a BASIC understanding of it. Maybe you could revise it? I'll keep trying to expand my knowledge and fix those minor hardware issues. Thank you so much for all your help so far! and thanks for directing me towards the SPI,

none of that shiftOut nonsense

great advice.

Do you know a basic way to shorten it?

Use a loop. Use an array of what your patterns are.

Funnily enough I'm helping someone else out with SPI and shift registers:

http://arduino.cc/forum/index.php/topic,103839

I haven't tried patterns (I don't have dozens of LEDs wired up) but it would be simple enough to do, depending on the effect you are after.

Thanks Nick, the thread didnt really help but Mikes webpage on arrays was nice. Im looking for something like what CrossRoads is doing, set up something like a blinkwithoutdelay program at the beginning (or end?) of the loop that cycles the gnd MOSFETS so it really only displays one column at a time, but thanks to persistance of vision we see a whole image. I have it doing that now with 500 microsecond delays between SPI transfers, that seems to be fast enough. So if my math is correct (and i dont think it is) that would be a refresh time of about ~83 Hz? doesnt really matter, but i also want to be able to punch that in at the top of the whole thing, like right now. Anyway kinda ranting, the main thing i am having trouble with is understyanding how to set up that first main part that cycles through the columns. Thanks!

Paranemertes,
I think you have the right idea - your code is like the long hand version of the array lookups I had in a loop.
So if you had a for:next loop that went from 0 to 23,

for (x = 0; x<24; x=x+1){

and each of these was an array of 24 bytes

  SPI.transfer(0);          >> SPI.transfer(lower_cathode[x]);
  SPI.transfer(0x10);    >> SPI.transfer(middle_cathode[x]);
  SPI.transfer(0);          >> SPI.transfer(upper_cathode[x]);
  SPI.transfer(chip5);   >> SPI.transfer(chip5_anode[x]);
  SPI.transfer(chip4);   >> SPI.transfer(chip4_anode[x]);
  SPI.transfer(chip3);   >> SPI.transfer(chip3_anode[x]);
  SPI.transfer(chip2);   >> SPI.transfer(chip2_anode[x]);
  SPI.transfer(chip1);   >> SPI.transfer(chip1_anode[x]);

then every time thru the for:next loop it would cycle thru all the data in the arrays.

for (x = 0; x<24; x=x+1){
  SPI.transfer(lower_cathode[x]);
  SPI.transfer(middle_cathode[x]);
  SPI.transfer(upper_cathode[x]);
  SPI.transfer(chip5_anode[x]);
  SPI.transfer(chip4_anode[x]);
  SPI.transfer(chip3_anode[x]);
  SPI.transfer(chip2_anode[x]);
 SPI.transfer(chip1_anode[x]);
}

and during the 500uS ontime you could do whatever logic you wanted, reading buttons, updating chip5/4/3/2/1 array values, etc.

void loop(){
for (x = 0; x<24; x=x+1){
  SPI.transfer(lower_cathode[x]);
  SPI.transfer(middle_cathode[x]);
  SPI.transfer(upper_cathode[x]);
  SPI.transfer(chip5_anode[x]);
  SPI.transfer(chip4_anode[x]);
  SPI.transfer(chip3_anode[x]);
  SPI.transfer(chip2_anode[x]);
 SPI.transfer(chip1_anode[x]);

unsigned long startTime  = micros();
   while (micros() - startTime <=500){
   // read buttons, update array, etc
    } // end while
// 'while' finally expires, the display refresh runs the next x
   } // end for:next, 0:23
} // end loop

Ok great,i think we are off to a good start, still cant get anything to light up with the shorter code though. got those bad leds fixed and the faulty mosfet out of there so the hardware is 100% now. I gave a shot at trying to turn on all the colors at once with some of your new stuff and some guessing on my part (its really like boxing gloves and legos) unfortunately it didnt do anything.

#include <SPI.h>

// set up an array for the cathode drives
byte lower_cathode[ ] = {
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // walking 1 for lower 8 NPNs 
byte middle_cathode[ ] = {
  0,0,0,0,0,0,0,0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0,0,0,0,0,0,0,0}; //walking for mid 8 NPNs 
byte upper_cathode[ ] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80};  // walking 1 for upper 8 NPNs

//are these arrays neccesary?
byte chip5 [8]; //holds green 9-12
byte chip4 [8]; //holds green 1-8
byte chip3 [8]; //holds blue 5-12
byte chip2 [8]; //holds red 9-12 and blue 1-4
byte chip1 [8]; //holds red 1-8
 
byte chip5_value = 0xFF; //chip values
byte chip4_value = 0xFF;
byte chip3_value = 0xFF;
byte chip2_value = 0xFF;
byte chip1_value = 0xFF;

byte anodes1 [12]; // array to hold 1st 3rd of RGB info, like red?
byte anodes2 [12]; // array to hold 2nd 3rd of RGB info, like blue?
byte anodes3 [12]; // array to hold 3rd 3rd of RGB info, like green?

byte columncount;

byte oe = 10; 

unsigned long updateTime = 0;
unsigned long exampleTime = 0;

byte  Red = 0; // arrays go from 0 to 11
byte  Green = 12;
byte  Blue = 12;

int x = 0;
int i = 0;

void setup(){
  pinMode(oe, OUTPUT);
  digitalWrite (oe, LOW);
  SPI.begin();
}

void loop(){
  
for (x = 0; x < 24; x++){
  SPI.transfer(lower_cathode[x]);
  SPI.transfer(middle_cathode[x]);
  SPI.transfer(upper_cathode[x]);
  SPI.transfer(chip5[x]);
  SPI.transfer(chip4[x]);
  SPI.transfer(chip3[x]);
  SPI.transfer(chip2[x]);
 SPI.transfer(chip1[x]);

unsigned long startTime = micros();
   while (micros() - startTime <= 500){
   // read buttons, update array, etc
   
   for(i = 0; i < 12; i++){
     SPI.transfer(chip5[chip5_value]);
     SPI.transfer(chip4[chip4_value]);
     SPI.transfer(chip3[chip3_value]);
     SPI.transfer(chip2[chip2_value]);
     SPI.transfer(chip1[chip1_value]);
   } // end while
   
// 'while' finally expires, the display refresh runs the next x

   } // end for:next, 0:23
} //end first for
} // end loop

and each of these was an array of 24 bytes

SPI.transfer(0);          >> SPI.transfer(lower_cathode[x]);

SPI.transfer(0x10);    >> SPI.transfer(middle_cathode[x]);
  SPI.transfer(0);          >> SPI.transfer(upper_cathode[x]);
  SPI.transfer(chip5);  >> SPI.transfer(chip5_anode[x]);
  SPI.transfer(chip4);  >> SPI.transfer(chip4_anode[x]);
  SPI.transfer(chip3);  >> SPI.transfer(chip3_anode[x]);
  SPI.transfer(chip2);  >> SPI.transfer(chip2_anode[x]);
  SPI.transfer(chip1);  >> SPI.transfer(chip1_anode[x]);

this confuses me just a bit, could you possibly show me those 24 byte arrays? What im after is all leds on throughout the table, no fancy animations, no bling, just all on. thanks! really happy with how this is coming along.

So you basically have this (see schematic):
5 8-bit registers down the left side to drive to 36 anodes of the 12 RGB LEDs.
3 8-bit registers across the bottom controlling MOSFETs, one per each column of 24 LEDs.

You will basically have 8 arrays that hold the data to write to those registers.
(you could do it other ways, I find this easiest to visualize implement)
Going down the side, you have 24 byte arrays for each of the 5 anode drivers. These are your Red, Green, Blue data
So, chip5[ 0 ] to chip5[ 23 ], same for chip4, chip3, chip2, chip1

Going across, you have 24 byte arrays for each of the 3 cathode drivers.
So, left_cathode [ 0 ] to leftcathode [ 23 ], same for mid_cathode, and right_cathode (or whatever we called them).

Now to cycle thru the array, you'll count from 0 to 23 and output data from a particular array into that driver.

void loop(){
for (x =0; x<24; x=x+1){
SPI.transfer (chip5 [x] );  // send the data from chip5 array position x into the chip5 shift register
SPI.transfer (chip4 [x] );  // send the data from chip4 array position x into the chip4 shift register
SPI.transfer (chip3 [x] );  // send the data from chip3 array position x into the chip3 shift register
SPI.transfer (chip2 [x] );  // send the data from chip2 array position x into the chip2 shift register
SPI.transfer (chip1 [x] );  // send the data from chip1 array position x into the chip1 shift register

// now the anodes are set with their highs & lows, turn on the cathode driver
SPI.transfer (left_cathode [x] );  // the data in these, 1,2,4,8,10,20,40,80, is set so that only 1 at a time is driven
SPI.transfer (mid_cathode [x] );
SPI.transfer (right_cathode [x] );
delayMicroseconds (500); //  let the column shine a bit
} // now you've gone thru all 24 columns

// now tweak the data on chip1[ ], chip2[ ], chip3[ ], chip4[ ] and chip5[ ] to make the display change
// its late, I can't think of a pattern, do something simple for now:

if (millis()>=previousMillis){ // time to update the displays!
previousMillis = previousMillis + 500); // change every 1/2 second
color = color+1; // define color as an int
if (color == 256){color = 0;} // reset back to 0
for (x=0; x<24; x=x+1){
chip5[x] = color; // cycle thru from 0 to 255
chip4[x] = color;
chip3[x] = color;
chip2[x] = color;
chip1[x] = color;
}
] // end loop

Your are correct about the shift registers, 8 8 bits, all daisy chained. first 5 control anodes, last 3 control MOSFETs and cathodes. Im still a little confused about your reasoning for the arrays. I understand where you get 24 byte from, thats understandable, but why a 24 byte array for each chip? the chips are handling specific colors on their own, this is how they are wired currently:
chip1 = r1-r8
chip2 = r9-12/b1-b4
chip3 = b5-12
chip4 = g1-g8
chip5 = g9-12/ 4 unused pins
chip6 = 1-8 mosfets
chip7 = 9-16 mosfets
chip8 = 17-24 mosfets
So why do i need a 24 byte array if they only are dealing with 8 outputs? (sorry, big learning curve for me i guess) Ill give your code a try and see if i can make something work. Also, what about this part:

byte cathodeslower[ ] = {
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // walking 1 for lower 8 NPNs 
byte cathodesmid[ ] = {
  0,0,0,0,0,0,0,0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0,0,0,0,0,0,0,0}; //walking for mid 8 NPNs 
byte cathodeshigher[ ] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80};  // walking 1 for upper 8 NPNs

If you dont mind, could you explain this a bit more to me? Thank you

okey dokey, well i just tried this:

#include <SPI.h>

// set up an array for the cathode drives
byte left_cathode[ ] = {
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // walking 1 for lower 8 NPNs 
byte mid_cathode[ ] = {
  0,0,0,0,0,0,0,0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0,0,0,0,0,0,0,0}; //walking for mid 8 NPNs 
byte right_cathode[ ] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80};  // walking 1 for upper 8 NPNs

//set up array for anodes
byte chip5 [24]; //holds green 9-12
byte chip4 [24]; //holds green 1-8
byte chip3 [24]; //holds blue 5-12
byte chip2 [24]; //holds red 9-12 and blue 1-4
byte chip1 [24]; //holds red 1-8

int x = 0;
int previousMillis = 0;

void setup(){
  SPI.begin();
}

void loop(){
for (x =0; x<24; x=x+1){
SPI.transfer(chip5 [x] );  // send the data from chip5 array position x into the chip5 shift register
SPI.transfer(chip4 [x] );  // send the data from chip4 array position x into the chip4 shift register
SPI.transfer(chip3 [x] );  // send the data from chip3 array position x into the chip3 shift register
SPI.transfer(chip2 [x] );  // send the data from chip2 array position x into the chip2 shift register
SPI.transfer(chip1 [x] );  // send the data from chip1 array position x into the chip1 shift register

// now the anodes are set with their highs & lows, turn on the cathode driver
SPI.transfer(left_cathode [x] );  // the data in these, 1,2,4,8,10,20,40,80, is set so that only 1 at a time is driven
SPI.transfer(mid_cathode [x] );
SPI.transfer(right_cathode [x] );
delayMicroseconds(500); //  let the column shine a bit
} // now you've gone thru all 24 columns

// now tweak the data on chip1[ ], chip2[ ], chip3[ ], chip4[ ] and chip5[ ] to make the display change
// its late, I can't think of a pattern, do something simple for now:

if (millis() >= previousMillis){ // time to update the displays!
previousMillis = (previousMillis + 500); // change every 1/2 second
int color = color + 1; // define color as an int
if (color == 256){color = 0;} // reset back to 0
for (x=0; x<24; x=x+1){
chip5[x] = color; // cycle thru from 0 to 255
chip4[x] = color;
chip3[x] = color;
chip2[x] = color;
chip1[x] = color;
 }
}
}// end loop

no big suprise, it didnt work. I think we are getting closer though. Check that code, i might have made a dumb mistake.

// its late, I can't think of a pattern, do something simple for now:

yeah.. i know what you mean, i think we are both night owls...

Let me format that for you:

#include <SPI.h>

// set up an array for the cathode drives
byte left_cathode[ ] = {
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // walking 1 for lower 8 NPNs 
byte mid_cathode[ ] = {
  0,0,0,0,0,0,0,0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0,0,0,0,0,0,0,0}; //walking for mid 8 NPNs 
byte right_cathode[ ] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40, 0x80};  // walking 1 for upper 8 NPNs

//set up array for anodes
byte chip5 [24]; //holds green 9-12
byte chip4 [24]; //holds green 1-8
byte chip3 [24]; //holds blue 5-12
byte chip2 [24]; //holds red 9-12 and blue 1-4
byte chip1 [24]; //holds red 1-8

int x = 0;
int previousMillis = 0;

void setup(){
  SPI.begin();
}

void loop(){
  for (x =0; x<24; x=x+1){
    SPI.transfer(chip5 [x] );  // send the data from chip5 array position x into the chip5 shift register
    SPI.transfer(chip4 [x] );  // send the data from chip4 array position x into the chip4 shift register
    SPI.transfer(chip3 [x] );  // send the data from chip3 array position x into the chip3 shift register
    SPI.transfer(chip2 [x] );  // send the data from chip2 array position x into the chip2 shift register
    SPI.transfer(chip1 [x] );  // send the data from chip1 array position x into the chip1 shift register

    // now the anodes are set with their highs & lows, turn on the cathode driver
    SPI.transfer(left_cathode [x] );  // the data in these, 1,2,4,8,10,20,40,80, is set so that only 1 at a time is driven
    SPI.transfer(mid_cathode [x] );
    SPI.transfer(right_cathode [x] );
    delayMicroseconds(500); //  let the column shine a bit
  } // now you've gone thru all 24 columns

  // now tweak the data on chip1[ ], chip2[ ], chip3[ ], chip4[ ] and chip5[ ] to make the display change
  // its late, I can't think of a pattern, do something simple for now:

  if (millis() >= previousMillis){ // time to update the displays!
    previousMillis = (previousMillis + 500); // change every 1/2 second
    int color = color + 1; // define color as an int
    if (color == 256){
      color = 0;
    } // reset back to 0
    for (x=0; x<24; x=x+1){
      chip5[x] = color; // cycle thru from 0 to 255
      chip4[x] = color;
      chip3[x] = color;
      chip2[x] = color;
      chip1[x] = color;
    }
  }
}// end loop

Now, how many chips do you have? 192?

  for (x =0; x<24; x=x+1){
    SPI.transfer(chip5 [x] );  // send the data from chip5 array position x into the chip5 shift register
    SPI.transfer(chip4 [x] );  // send the data from chip4 array position x into the chip4 shift register
    SPI.transfer(chip3 [x] );  // send the data from chip3 array position x into the chip3 shift register
    SPI.transfer(chip2 [x] );  // send the data from chip2 array position x into the chip2 shift register
    SPI.transfer(chip1 [x] );  // send the data from chip1 array position x into the chip1 shift register

    // now the anodes are set with their highs & lows, turn on the cathode driver
    SPI.transfer(left_cathode [x] );  // the data in these, 1,2,4,8,10,20,40,80, is set so that only 1 at a time is driven
    SPI.transfer(mid_cathode [x] );
    SPI.transfer(right_cathode [x] );
    delayMicroseconds(500); //  let the column shine a bit
  } // now you've gone thru all 24 columns

Each SPI.transfer shifts out (best not leave out the F eh?) 8 bits, so you are sending out 24 * 8 * 8 bits. That's 1536 bits. Do you have 1536 LEDs?

I don't see you latching the data anywhere.