arduino, leds and a pattern

here is my code i'm trying to get working:

int colPins[3] = {9,11,10}; // r g b pins
long previousMillis = 0;

long times[] = {500, 500, 500, 500}; // 500 ms intervals
int colors[][2] = {{0,255},{0,0},{0,255}, {0,0}}; // red pin (0 = pin 9), on off on off, repeat

long change = times[0];

int pi = 0; // pattern index for loop
int patternSize;

void setup()
{
  DDRB |= 0xE; // set output pins
  Serial.begin(9600);  
  patternSize = sizeof(times) / sizeof(long); // get size of array

}

void loop()
{
    if (millis() > change) {

    digitalWrite(colPins[colors[pi][0]], colors[pi][1]);
    change = millis() + times[pi];

    if (pi == (patternSize - 1)) {
      pi = 0;
    } else {
      pi++;
    }
  } 
}

it's based on the blink led without delay. it works well for a small array like that. but when i increase the array size to lets say 400+, the arduino does nothing. it compiles fine. is there a max array size that it works for?

the arrays for time and coloring are meant to come from say a bass line of a song or something. i wrote something i can play with before i make a midi decoder just to test:

you can use numpad 1 2 and 3 to activate the colors. i'm wondering if i have a totally wrong approach to this...?

thanks

it works well for a small array like that. but when i increase the array size to lets say 400

You've got three small arrays.

int colors [] [2]

Try changing "int" for "byte".
You could probably get away with "unsigned short" instead of "long" for "times" too.

[EDIT] You could probably go to "byte" for "times" too, IFF you pick on, say, units of 10 or 100 milliseconds. Or even 5mS.
And you remember to multiply up before you use the values.

You've only got so much RAM on this microcontroller. Part of it is being used for your arrays and other global variables, what's left over is used for the stack. If you don't leave enough room for the stack, your program crashes.

So yes, there is a maximum size for your array :slight_smile: Do use a data type that is as small as possible yet large enough to hold the values you need. Beyond that, you'll need to get creative and start playing tricks (really, encoding your data more efficiently).

If I'm understanding your goal right, this array is static, you don't need to update it once the program starts running. In which case, the array can live in the program space rather than hogging all your ram. Instructions here:

*I haven't done this yet, so if that's not really what PROGMEM is for correct me plz.

i have not tried progmem but i thought of a different way to do it. for example

frame1[] = {0,....,4095} (has 64 entries, from 0 - 4095 for leds)
frame2[] = {4095,0,...,} etc

and then frameloop[] = {frame1, frame2...} etc. i have no idea how to do this in C++, is that even possible? i know in php and javascript it's quite easy.

or should i look into progmem?

thanks

frame1[] = {0,....,4095} (has 64 entries, from 0 - 4095 for leds)
frame2[] = {4095,0,...,} etc

and then frameloop[] = {frame1, frame2...}

Yes, this is doable, but if frame1 has 64 entries, each capable of holding numbers in the rang 0..4095, then frame1 will be 128 bytes long, as will frame2.
So just two frames has used up a quarter (assuming a 168) of your RAM.

PROGMEM really is the way to go.
The reference cited above is quite easy to follow.