Using PROGMEM for large 3D arrays?

Hey everyone, I am currently working on an 8x8x8 LED cube, in which I am using an array of values to determine LED brightness anywhere from 0 -> 255 on each LED so my array would be something like this

byte myanimation[][8][64]

With an undefined amount of frames (first brackets) second is Layer and Third is LED so essentially

myanimation[0][0][63] = 255;

would make First Frame of the animation, Bottom layer of the Cube, last light on.

This works as a 2D array without the Frame dimention only allowing solid images...

I believe the 3D array is not working as 4 Frames, 8 Layers and 64 LEDs as an array is 4*(8*64) = 2048 bytes, pretty much filling up the SRAM I am using the Arduino Uno or possibly NANO for this project as I have both handy I am unsure yet at the moment I am testing with the UNO.

I was hoping that by using PROGMEM I could still use the array but have it from the FLASH instead... I have looked at http://www.arduino.cc/en/Reference/PROGMEM and gotten the example working but I would like to do this for my mentioned array which I had this but its not working

PROGMEM const byte string_table[][8][64] =     // change "string_table" name to suit
{   
  {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
},{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
},{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
}
};

Can some one please give me some help on how to use PROGMEM for a very large 3D array? Thanks, Kriogenic.

but its not working

Can we ban that phrase?

Fair deal, Redefined: I am not sure what I have done wrong? (How else can something like that be phrased... REALLY?)

I was trying to use something like this to run it...

    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i][0][0]))); // Necessary casts and dereferencing, just copy. 
    Serial.println( buffer );
    delay( 500 );

But I get no output? Any step in the right direction would be great.

I managed to get multiplexing with my Shift Register circuit (I had no LED drivers decided on Registers and SPI) and 2D arrays (Solid Frame) running fine. Just when adding in the frames I require the use of more then 2kb and am not sure how to go about using PROGMEM for the task.

Thanks.

If you're using strcpy_P, and your source has zeroes in it, it's going to end pretty quickly. A zero defines the end of the string. If strcpy finds a zero in the first location, you won't get any output. Use memcpy_P instead.

How else can something like that be phrased... REALLY?)

It can be qualified; "I expected x to happen, but y happened instead" or something similar.

Yeah true that is a good point.
Is there a certain way to create the const string_table or have I done it correctly?

I looked up memcpy_P and changed the way I accessed the string_table (badly named)

for (int i = 0; i < 6; i++)
  {
 memcpy_P(buffer, (char*)pgm_read_byte(&(string_table[1][3][i])),sizeof(string_table)); // Necessary casts and dereferencing, just copy. 
 Serial.println(buffer);
    delay( 500 );
  }

so I added the sizeof(string_table changed pgm_read_… to pgm_read_byte and used memcpy…
To see if it was accessing any data at all I just made it print buffer unfortunately it outputs nothing at all.

I think I am not setting up the structure of string_table correctly or am messing up my memcpy_P call.
Thanks again for the help.

You're messing up the call to memcpy_P. The second parameter already is a PROGMEM pointer (IIRC), so the explicit read is unnecessary.

I have already tried without the explicit read, or what I think is without it?

  memcpy_P(buffer, (char*)&string_table[1][3][i],sizeof(string_table));

and it still refuses to print anything to the serial.

Am I still missing something :S? I have tried so many different things with none of them giving me the expected output or any at all.

Thanks again for the help. Really appreciate it.

memcpy_P(buffer, (char*)&string_table[1][3][i],sizeof(string_table));

Is "buffer" really the same size as "string_table" ?

no its not as big as string_table it is however as big as string_table[x][y][z]? I thought buffer only had to be as big as the information being read from memcpy_P in my case string_table[1][3] for testing

I thought buffer only had to be as big as the information being read from memcpy_P

It does. The point was that the 3rd argument defines the number of bytes to copy, not the size of the array that holds the data to be copied.

Ahhh I see thanks for the help its now working perfectly how it should.

Won't sizeof() give the size of an element of string_table, ie 1 byte?

Why isn't your led brightness array myanimation[frames][8][8][8]?

Is this stand-alone or can it run from a connected PC?

No, sizeof gives the size in bytes of the whole object.