2 dimensional array readout problem

Hi Builders,
It's been almost five hours since I found this mismatch in my own sketch. Now I have no idea how to go further. The problem in short.
My goal: read out a huge 2 dimensional (many lines, 16 columns) array, each row, one after another in sequence. (All data will be sent to a TLC5940 PWM driver.)
The problem: at the beginning and at the end of initial for... cycle, there are many unwanted, strange readouts from the array.

Here is the code (simplifed for debugging):

int channel;
int line;
int value;
int intensity;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
int leds [66][16] = {
  { 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255  },
  { 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255  },
  { 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255  },
  { 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0  },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255  },
  { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255  },
  { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 218, 234, 255  },
};

  for (line = 0; line <= 65; line ++)
  {
    for (channel = 0; channel < 16; channel ++)
    {
      value = leds [line][channel];
      Serial.print(line, DEC);
      Serial.print('.');
      Serial.print(channel, DEC);
      Serial.print('\t');
      Serial.println(value, DEC);
    }
    Serial.println('.');
    delay(10);
  } 
}

Here is a copy of Serial Monitor with some notes:

[b]Line 64 and 65 are correct:[/b]

64.0 255
64.1 255
64.2 255
64.3 255
64.4 255
64.5 255
64.6 255
64.7 255
64.8 255
64.9 255
64.10 255
64.11 255
64.12 255
64.13 255
64.14 255
64.15 255

65.0 0
65.1 16
65.2 32
65.3 48
65.4 64
65.5 80
65.6 96
65.7 112
65.8 128
65.9 144
65.10 160
65.11 176
65.12 192
65.13 218
65.14 234
65.15 255

Line 0 has 255s instead of 0s.
0.0 255
0.1 255
0.2 255
0.3 255
0.4 255
0.5 255
0.6 255
0.7 255
0.8 255
0.9 255
0.10 255
0.11 255
0.12 255
0.13 255
0.14 255
0.15 255

Line 1 seems as line 65 should.
1.0 0
1.1 16
1.2 32
1.3 48
1.4 64
1.5 80
1.6 96
1.7 112
1.8 128
1.9 144
1.10 160
1.11 176
1.12 192
1.13 218
1.14 234
1.15 255

Strange values from line 2 to 8.
2.0 0
2.1 0
2.2 867
2.3 1032
2.4 761
2.5 810
2.6 778
2.7 851
2.8 2048
2.9 512
2.10 0
2.11 0
2.12 0
2.13 9842
2.14 0
2.15 10097

3.0 0
3.1 33
3.2 0
3.3 0
3.4 0
3.5 0
3.6 0
3.7 0
3.8 0
3.9 0
3.10 0
3.11 0
3.12 0
3.13 0
3.14 0
3.15 0

4.0 0
4.1 0
4.2 0
4.3 0
4.4 0
4.5 0
4.6 0
4.7 0
4.8 0
4.9 0
4.10 0
4.11 0
4.12 0
4.13 0
4.14 0
4.15 0

5.0 0
5.1 0
5.2 0
5.3 12288
5.4 2573
5.5 11829
5.6 2355
5.7 12849
5.8 14386
5.9 3384
5.10 13578
5.11 12337
5.12 12553
5.13 13619
5.14 14391
5.15 2573

6.0 11829
6.1 14385
6.2 14642
6.3 2573
6.4 11830
6.5 2353
6.6 13361
6.7 14387
6.8 3383
6.9 13834
6.10 14382
6.11 13065
6.12 14387
6.13 3379
6.14 13834
6.15 13112

7.0 3380
7.1 13834
7.2 12590
7.3 10805
7.4 13824
7.5 18176
7.6 9
7.7 -6144
7.8 3
7.9 0
7.10 0
7.11 26112
7.12 -22007
7.13 -15095
7.14 -15360
7.15 -16384

8.0 -16128
8.1 -15872
8.2 -14848
8.3 1024
8.4 1795
8.5 261
8.6 1
8.7 0
8.8 255
8.9 0
8.10 0
8.11 0
8.12 0
8.13 0
8.14 0
8.15 0

[All values are good from 9 to 59.]

Line 60 is wrong again.
60.0 0
60.1 0
60.2 0
60.3 0
60.4 0
60.5 0
60.6 0
60.7 0
60.8 0
60.9 0
60.10 0
60.11 -22007
60.12 6400
60.13 9472
60.14 25346
60.15 768

61.0 117
61.1 1026
61.2 2337
61.3 238
61.4 0
61.5 2048
61.6 1234
61.7 2161
61.8 1205
61.9 1220
61.10 196
61.11 0
61.12 0
61.13 255
61.14 0
61.15 0

62.0 0
62.1 0
62.2 0
62.3 0
62.4 0
62.5 -5111
62.6 -4599
62.7 13362
62.8 13875
62.9 53
62.10 2542
62.11 0
62.12 0
62.13 -22007
62.14 16128
62.15 3072

63.0 6656
63.1 768
63.2 630
63.3 1060
63.4 81
63.5 2
63.6 1282
63.7 66
63.8 16911
63.9 -27327
63.10 15
63.11 1187
63.12 3
63.13 104
63.14 91
63.15 255

Lines 64 and 65 are correct.
64.0 255
64.1 255
64.2 255
64.3 255
64.4 255
64.5 255
64.6 255
64.7 255
64.8 255
64.9 255
64.10 255
64.11 255
64.12 255
64.13 255
64.14 255
64.15 255

65.0 0
65.1 16
65.2 32
65.3 48
65.4 64
65.5 80
65.6 96
65.7 112
65.8 128
65.9 144
65.10 160
65.11 176
65.12 192
65.13 218
65.14 234
65.15 255

And the trouble continues.
0.0 255
0.1 255
0.2 255
0.3 255
0.4 255
0.5 255
0.6 255
0.7 255
0.8 255
0.9 255
0.10 255
0.11 255
0.12 255
0.13 255
0.14 255
0.15 255

Many thanks in advance for your support.

Regards,

Tom

int leds [66][16] = {

Grab your calculator. How many bytes is this? Mine says 2112. The 328-based machines have 2048 bytes of SRAM, where this array lives.

Try a smaller array (say 30 lines) and if that works then you are running out of memory.

Paul, Marco,

Thanks for your support. It has been fixed, the sketch works flawlessly.

Another question based on this issue. I was trying to define more than one array and use them one after another in separate for... loops. The resutls were similar as in the previous post. I guess, the right way is to use PROGMEM (pgmspace.h library) for this purpose (of course, except using external memory). Am I right?

Thanks again, have a nice day!

Tom

Yes.

The data is static (in your case defined as global variables) so the space is allocated before he program, starts to run. If you want to free up that space you should use storage outside the RAM and PROGMEM is one option.

Hi Marco,

Thanks for your answer.

marco_c:
If you want to free up that space you should use storage outside the RAM and PROGMEM is one option.

I guess, an SD card is another option. Are there any more?

Do you need an array at all ?
It looks to me like there is a pattern that could be output by a couple of nested for loops for the majority of the lines.

Doing it this way also made your program run slower than it should, since it had to re-initialize this array each time loop() started. You should have made it global or static.

I agree that this should be easy to calculate on the fly, though.

This is one array only. At least 30 more planned (That's why I think bout SD card storage.) It will be changed in a regular basis (once a week or so). The sketch will do something similar to a slideshow.
I'm not completly shure, but guess, a series of nested for loops are not the very best way to handle this requirement. Please, correct if any of you have a more elegant/useful idea!

Perhaps if you showed your actual data you might get more relevant suggestions, but the bulk of that array seems to contain a trivial pattern that you could generate programmatically - only the last couple of lines have anything interesting in.

You're all right. The sample code is a bit misleading.
An array looks similar to this sample:

int leds1 [48][16] = {
{1, 16, 50, 42, 12, 1, 1, 1, 1, 26, 179, 255, 125, 1, 1, 52},
{1, 97, 230, 221, 170, 107, 54, 22, 1, 1, 62, 161, 72, 1, 1, 135},
{1, 74, 197, 238, 255, 255, 230, 194, 134, 54, 4, 7, 3, 1, 5, 207},
{1, 3, 24, 63, 122, 183, 227, 253, 255, 223, 101, 2, 1, 1, 54, 248},
{1, 1, 1, 1, 1, 17, 49, 94, 175, 252, 224, 54, 1, 1, 128, 255},
{1, 1, 1, 1, 1, 1, 1, 1, 51, 219, 254, 86, 1, 4, 196, 244},
{1, 1, 1, 1, 1, 1, 1, 23, 142, 254, 211, 44, 1, 50, 235, 232},
{1, 1, 1, 1, 1, 18, 82, 182, 255, 238, 93, 1, 1, 121, 240, 226},
{1, 1, 1, 17, 88, 178, 245, 255, 216, 100, 7, 1, 4, 184, 229, 221},
{1, 1, 52, 170, 247, 255, 223, 142, 50, 1, 1, 1, 46, 220, 217, 216},
{1, 46, 198, 255, 224, 135, 49, 4, 1, 1, 1, 1, 112, 224, 211, 211},
{6, 144, 255, 196, 60, 2, 1, 1, 1, 1, 1, 3, 171, 212, 205, 205},
{22, 198, 251, 91, 1, 1, 1, 1, 1, 1, 1, 43, 203, 201, 200, 200},
{21, 195, 250, 82, 1, 1, 1, 1, 1, 1, 1, 102, 206, 194, 194, 194},
{6, 157, 255, 132, 1, 1, 1, 1, 1, 1, 3, 156, 194, 188, 188, 188},
{1, 95, 251, 203, 32, 1, 1, 1, 1, 1, 39, 184, 183, 182, 182, 182},
{1, 32, 203, 253, 110, 1, 1, 1, 1, 1, 93, 186, 175, 175, 176, 176},
{1, 1, 115, 253, 209, 40, 1, 1, 1, 3, 140, 175, 169, 170, 169, 169},
{1, 1, 28, 192, 255, 128, 1, 1, 1, 34, 165, 164, 163, 163, 163, 163},
{1, 1, 1, 96, 249, 230, 104, 17, 1, 81, 166, 156, 156, 156, 156, 157},
{1, 1, 1, 18, 159, 255, 251, 171, 71, 126, 153, 150, 150, 150, 150, 150},
{1, 1, 1, 1, 29, 132, 225, 255, 235, 194, 150, 141, 143, 144, 143, 143},
{1, 1, 1, 1, 1, 3, 56, 158, 249, 253, 203, 145, 135, 137, 136, 137},
{1, 1, 1, 1, 1, 1, 1, 18, 169, 248, 251, 175, 128, 129, 130, 130},
{1, 1, 1, 1, 1, 1, 1, 21, 126, 201, 255, 198, 124, 122, 123, 123},
{1, 1, 1, 1, 1, 1, 1, 60, 120, 177, 255, 203, 120, 115, 117, 117},
{1, 1, 1, 1, 1, 1, 2, 88, 116, 188, 255, 200, 113, 109, 110, 110},
{1, 1, 1, 1, 1, 1, 19, 108, 170, 243, 254, 169, 103, 103, 103, 103},
{1, 1, 1, 1, 1, 1, 57, 173, 244, 252, 188, 111, 95, 97, 97, 97},
{1, 1, 1, 1, 1, 1, 117, 246, 254, 181, 100, 88, 90, 90, 91, 90},
{1, 1, 1, 1, 1, 13, 125, 242, 250, 152, 82, 83, 84, 84, 84, 84},
{1, 1, 1, 1, 1, 38, 89, 173, 254, 214, 98, 75, 78, 78, 78, 78},
{1, 1, 1, 1, 1, 59, 67, 113, 240, 238, 108, 68, 72, 71, 72, 72},
{1, 1, 1, 1, 13, 64, 87, 177, 254, 216, 88, 62, 65, 66, 66, 66},
{1, 1, 1, 1, 29, 71, 172, 254, 238, 134, 60, 59, 60, 59, 59, 60},
{1, 1, 1, 1, 40, 78, 217, 252, 141, 57, 52, 54, 54, 54, 54, 54},
{1, 1, 1, 9, 45, 67, 207, 249, 109, 42, 48, 48, 48, 48, 48, 48},
{1, 1, 1, 22, 43, 50, 183, 255, 133, 39, 42, 43, 43, 43, 43, 43},
{1, 1, 1, 31, 38, 37, 148, 255, 171, 43, 35, 38, 37, 37, 37, 37},
{1, 1, 7, 33, 32, 28, 99, 245, 220, 68, 28, 33, 32, 33, 32, 32},
{1, 1, 14, 30, 28, 24, 51, 202, 253, 116, 23, 27, 28, 28, 28, 28},
{1, 1, 19, 24, 23, 22, 22, 139, 255, 179, 35, 19, 23, 23, 23, 23},
{1, 3, 19, 19, 19, 19, 13, 73, 232, 241, 95, 14, 18, 18, 19, 19},
{1, 7, 16, 14, 14, 14, 12, 21, 148, 255, 195, 42, 8, 15, 14, 14},
{1, 9, 11, 10, 11, 11, 10, 6, 51, 208, 255, 148, 23, 8, 11, 11},
{2, 7, 7, 7, 7, 7, 7, 6, 4, 104, 249, 250, 120, 8, 6, 7},
{2, 4, 4, 4, 4, 4, 4, 4, 1, 19, 162, 255, 203, 32, 1, 3},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 218, 241, 71, 1, 1}
};
int leds1 [48][16]

Did I miss a value that NEEDS an int array?

PaulS:
Did I miss a value that NEEDS an int array?

I don't think so, Paul. Every item in the array will be used as PWM value for an LED strip. I think, volatile int may be good too.
If you have any better idea, I would be very pleased to read it.

If you have any better idea, I would be very pleased to read it.

If all the values fit in a byte, USE A BYTE.

I think, volatile int may be good too.

Any particular reason for that line of thought?

AWOL:

I think, volatile int may be good too.

Any particular reason for that line of thought?

Absolutely nothing. Just a guess. Based on Arduino reference, volatile is used to be a variable qualifier for store variables in flash instead of SRAM. By the way, it's not completly cear to me yet.

PaulS:
If all the values fit in a byte, USE A BYTE.

Paul, thank you very much. A very useful idea indeed. (It's a good time for me to learn again.)

volatile is used to be a variable qualifier for store variables in flash instead of SRAM.

One of us needs to read the reference again, and this time, it isn't me.

AWOL:
One of us needs to read the reference again, and this time, it isn't me.

Agree... By the way, I read it many times today, but I'm still far from clear understanding.

To store stuff in the flash memory, use PROGMEM. Volatile does sort of the opposite. And, as Paul suggested, use the smallest possible type. Memory is limited on an arduino, and you can't even use all of it.