Big RGB Table Finally Needs Code

yeah they are indeed all daisy chained, anodes and cathodes all together. I see what your saying, that does sound easier, but too late now.

Can you post the schematic for the control logic?

What exactly is that? And do you know why this code wouldnt work? Its just the short hand simple version of what i started out doing, and when i look at the values it prints at the end it all checks out, but nothing lights up. no pin changes.

// code for a 36 x 24 array (12 RGB LEDs, 24 columns)

#include <SPI.h>

// set up an array for the cathode drives
byte cathode6[] = { //chip 6, first 3rd of display
  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
byte cathode7[] = { //chip 7, second 3rd of display
  0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0, 0, 0, 0, 0, 0, 0
};
byte cathode8[] = { //chip 8, third 3rd of display
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};

byte chip5 = 0xFF; //chip values
byte chip4 = 0xFF;
byte chip3 = 0xFF;
byte chip2 = 0xFF;
byte chip1 = 0xFF;

int columncount = 0;
unsigned int time = 500;

const int oe = 10;

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

void loop(){
  //we have to transfer out the cathodes first
  SPI.transfer(cathode8[columncount]);
  SPI.transfer(cathode7[columncount]);
  SPI.transfer(cathode6[columncount]);
  columncount = columncount + 1; // update for next column
  if (columncount == 24){
  columncount = 0; // reset if reach the end
  }
  //transfer out those colors
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  Serial.println(cathode8[columncount], HEX);
  Serial.println(cathode7[columncount], HEX);
  Serial.println(cathode6[columncount], HEX);
  Serial.println(chip5, HEX);
  Serial.println(chip4, HEX);
  Serial.println(chip3, HEX);
  Serial.println(chip2, HEX);
  Serial.println(chip1, HEX);
  delay(time);
} // end void loop

http://arduino.cc/forum/index.php/topic,97488.15.html
Reply #29 in this thread, "ok so i have a final version of the board."
Is there a schematic that goes with it? Or is that the best there is to work with?
If so, SPI.transfer() is not going to work, you don't have the SPI clock line, SCK, connected to anything.
Doesn't fritzing have some kind of schematic feature as well?

yes fritzing has a schematic function, ill work on that. but i did set up the board so that SPI would work, all the long-hand SPI i have done works perfectly, its the short-hand that doesn't. Give me a little bit and ill have a schematic for you.

Why are you using flip-flops and not shift registers? I'm not sure that in a single transition they will ripple along the way you describe. They might.

Octal latches were used to provide high current drive, vs the 4-6mA of a shift register Nick.

If you drive the anode info and cathode at the same time, and use the cathode OE to actually turn on the column, should end up looking like a normal display.
I'm thinking Paranemertes is just missing something real subtle in the loop code.

That and not understanding about having the anode info for each column coming from an array, vs creating it all on the fly.

Yeah this code is just to see if that short hand stuff will cycle the anodes, i just dont know why it wont display...

// code for a 36 x 24 array (12 RGB LEDs, 24 columns)

#include <SPI.h>

// set up an array for the cathode drives
byte cathode6[] = { //chip 6, first 3rd of display
  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
byte cathode7[] = { //chip 7, second 3rd of display
  0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0, 0, 0, 0, 0, 0, 0
};
byte cathode8[] = { //chip 8, third 3rd of display
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};

byte chip5 = 0xFF; //chip values
byte chip4 = 0xFF;
byte chip3 = 0xFF;
byte chip2 = 0xFF;
byte chip1 = 0xFF;

int columncount = 0;
unsigned int time = 500;

const int oe = 10;

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

void loop(){
  //we have to transfer out the cathodes first
  SPI.transfer(cathode8[columncount]);
  SPI.transfer(cathode7[columncount]);
  SPI.transfer(cathode6[columncount]);
  columncount = columncount + 1; // update for next column
  if (columncount == 24){
  columncount = 0; // reset if reach the end
  }
  //transfer out those colors
  SPI.transfer(chip5);
  SPI.transfer(chip4);
  SPI.transfer(chip3);
  SPI.transfer(chip2);
  SPI.transfer(chip1);
  Serial.println(cathode8[columncount], HEX);
  Serial.println(cathode7[columncount], HEX);
  Serial.println(cathode6[columncount], HEX);
  Serial.println(chip5, HEX);
  Serial.println(chip4, HEX);
  Serial.println(chip3, HEX);
  Serial.println(chip2, HEX);
  Serial.println(chip1, HEX);
  delay(time);
} // end void loop

The board is working perfectly, the octals are acting just like shift registers. but the oe isnt working, they are all connected though.

Use a meter and confirm all the OE pins are actually connected to D10, which is physical pin 16. Maybe a trace got left out somewhere.

Paranemertes:
Yeah this code is just to see if that short hand stuff will cycle the anodes, i just dont know why it wont display...

...

const int oe = 10;

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



The board is working perfectly, the octals are acting just like shift registers. but the oe isnt working, they are all connected though.

SPI.begin does this amongst other thing:

  digitalWrite(SS, HIGH);

SS is pin 10. So your oe has gone high again.

THAT mistake deserves a face palm. Works just like i wanted now. thanks Nick, i knew it had to be something small i was overlooking.

CrossRoads, what do you think would be an easy way to set up the anodes so that they are more workable in the code? Maybe some type of array?

Yes, go look at some of the earlier code listings I had.
You need 5 arrays that are 24 bytes each. Each bit each byte represents 1 LED, the 24 bytes represent the 24 columns going across the table:

numbers represent "column_count"
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
r r r r r r r r r r r r r r r r r r r r r r r r // bit 7 of chip5 array (spacing vs the numbering above is hosed)
:
:
r r r r r r r r r r r r r r r r r r r r r r r r // bit 0 of chip5 array

r r r r r r r r r r r r r r r r r r r r r r r r // bit 7 of chip4 array
:
r r r r r r r r r r r r r r r r r r r r r r r r // bit 4 of chip4 array
b b b b b b b b b b b b b b b b b b b b b b b b // bit 3 of chip4 array
:
b b b b b b b b b b b b b b b b b b b b b b b b // bit 0 of chip4 array

b b b b b b b b b b b b b b b b b b b b b b b b // bit 7 of chip3 array
:
:
b b b b b b b b b b b b b b b b b b b b b b b b // bit 0 of chip3 array

g g g g g g g g g g g g g g g g g g g g g g g g // bit 7 of chip2 array
:
:
g g g g g g g g g g g g g g g g g g g g g g g g // bit 0 of chip2 array

g g g g g g g g g g g g g g g g g g g g g g g g // bit 7 of chip1 array
:
g g g g g g g g g g g g g g g g g g g g g g g g // bit 4 of chip1 array

x x x x x x x x x x x x x x x x x x x x x x x x // bit3 of chip1 array (3-2-1-0 not used)
:
x x x x x x x x x x x x x x x x x x x x x x x x // bit0 of chip1 array

So for every column_count, you will pull data from 1 column above and put it in the shift registers.
Your loop will cycle thru all 24 columns (0-23), after each pass thru loop, or after each column count increment, or however you decide, you will: accept serial data to update the array, read a button to update the array, do some time based thing to update the array (think tetris), whatever. Just make sure it happens quickly, within the on-time delay for each column even, so the display refresh rate stays high and does not flicker.

ok, still learning at a snails pace, but we're getting there. Ill give it a try and see what i can do...

uggg, i still don't understand what you mean, sorry. are you talking about a 24 byte array for each row? for each color? for each?????? what exactly. how many of these do i need? some example code would be much appreciated, i seem to learn that way best.

Yes, 24 byte array for each anode shift register, just like there are 24 bits of cathode shift registers.
When column_count = x, then the xth byte goes out to the anodes and the xth bit of cathode turns on to drive the xth column.

I posted example code for you a couple of times, go re-read some of those with an eye to the above statement.
I'm working on my own 12x8 array, using a different driver approach where 1 is off and 0 is on, I may go to your approach if it doesn't work like I want it to.

OK, that makes a little more sense, but i still dont fully understand how i can update the anodes in that while loop.

// code for a 36 x 24 array (12 RGB LEDs, 24 columns)

#include <SPI.h>

// set up an array for the cathode drives
byte cathode6[] = { //chip 6, first 3rd of display
  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
byte cathode7[] = { //chip 7, second 3rd of display
  0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0, 0, 0, 0, 0, 0, 0
};
byte cathode8[] = { //chip 8, third 3rd of display
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};

byte chip5[24];
byte chip4[24]; 
byte chip3[24]; 
byte chip2[24]; 
byte chip1[24]; 

int columncount = 0;
int rowcount = 0;
int time = 500;

const int oe = 10;

void setup(){
  SPI.begin();
  pinMode(oe, OUTPUT);
  digitalWrite(oe, LOW);
  Serial.begin(9600);
  randomSeed(analogRead(A0));
}

void loop(){
  //we have to transfer out the cathodes first
  for (int x = 0; x < 24; x++){
  SPI.transfer(cathode8[x]);
  SPI.transfer(cathode7[x]);
  SPI.transfer(cathode6[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
  int randomnum1 = random(0, 255);
  int randomnum2 = random(0, 255);
  int randomnum3 = random(0, 255);
  int randomnum4 = random(0, 255);
  int randomnum5 = random(0, 255);
  SPI.transfer(chip5[randomnum5]);
  SPI.transfer(chip4[randomnum4]);
  SPI.transfer(chip3[randomnum3]);
  SPI.transfer(chip2[randomnum2]);
  SPI.transfer(chip1[randomnum1]);
    } // end while
// 'while' finally expires, the display refresh runs the next x
 } // end void loop

When i only assign full on i get strange colors everywhere that dont move or change, this just gives very faint random colors. what is wrong? and how can i update those anodes?

Thanks for being so patient with me on this, i really appreciate it.

I believe this part here is the cause of your random colors:

   while(micros() - startTime <= 500){
   // read buttons, update array, etc
  int randomnum1 = random(0, 255);
  int randomnum2 = random(0, 255);
  int randomnum3 = random(0, 255);
  int randomnum4 = random(0, 255);
  int randomnum5 = random(0, 255);
  SPI.transfer(chip5[randomnum5]);
  SPI.transfer(chip4[randomnum4]);
  SPI.transfer(chip3[randomnum3]);
  SPI.transfer(chip2[randomnum2]);
  SPI.transfer(chip1[randomnum1]);
    } // end while
// 'while' finally expires, the display refresh runs the next x

so for 500uS, you're writing random numbers to the shift registers.
Think you need a plan of attack here so you can see what is going on.
Try setting the chip1-5 arrays to 0 to start, then every 100 mS pick one byte in 1 array and change it.
ex.
put this in setup:

for (int i = 0; i<24; i=i+1){
chip1[i] = 0;
chip2[i] = 0;
chip3[i] = 0;
chip4[i] = 0;
chip5[i]] = 0;
}

put this before setup:

unsigned long nextUpate;
byte colortest;

put this in void loop, in place of the while random number thing:

if (millis()>nextUpdate){
nextUpdate = nextUpdate + 100; 
chip1[colortest] = chip1[colortest]+1;
colortest = colortest+1;
}

Now you should see a pattern of 00000001, 00000010, 00000011, 00000100, 00000101,etc. going across the chip1 LEDs at 100mS interval, where 1 is an LED turned on.
I'm not 100% on this, still trying to get my array working, think I have some wiring issues to fix.

Moderator edit: [code] ... [/code] tags added. (Nick Gammon)

byte chip5[24];
...
  int randomnum5 = random(0, 255);
  SPI.transfer(chip5[randomnum5]);

randomnum5 will be in the range 0 to 254, right?

So you are indexing into chip5 in that range, but chip5 is only 24 bytes.

Ooops, off the end of the array. That will give random results.

ummm, ok CrossRoads i tried your stuff but i get an error about that setup part:

incompatible types in assignment of 'int' to 'byte [24]'

so whats with that? i would think you would assign them to zero in a different way... but then again, what do i know?

He didn't use code tags, so the subscript became italics. I fixed up the post.

Thanks for fixing that Nick.

This line
for (int i = 0; i<24; i=i+1){

should probably have been
for (byte i = 0; i<24; i=i+1){

as the array is defined as bytes.