New to arrays - want to sequence correctly

Howdy,

I'm working on a project which runs prebuilt patterns of LEDs each time one of 12 buttons are pressed. I was hoping that instead of writing long lines of code, like:

digitalWrite(led[34], HIGH);
  delay(400);
  digitalWrite(led[34], LOW);
  digitalWrite(led[32], HIGH);
  delay(400);
  digitalWrite(led[32], LOW);
  digitalWrite(led[31], HIGH);
  delay(400);
  digitalWrite(led[31], LOW);
  digitalWrite(led[30], HIGH);
  delay(400);
  digitalWrite(led[30], LOW);
  digitalWrite(led[27], HIGH);
  delay(400);
  digitalWrite(led[27], LOW);
  digitalWrite(led[28], HIGH);
  delay(400);
  digitalWrite(led[28], LOW);
  digitalWrite(led[29], HIGH);
  delay(400);
  digitalWrite(led[29], LOW);
    digitalWrite(led[24], HIGH);
  delay(400);
  digitalWrite(led[24], LOW);

I'd like a more succinct way of writing sequences of LEDs turning on, then turning off (some patterns do require multiple LEDs on at the same time), Other than the:

 i =0; i< 12; i++

style of writing, is there any way I can write:

run each of these for 400 ms, in succession:
    30, 32&&31, 34&&30, 32, 33&&31, 29&&25, 22

or

run each of these for 500 ms, in succession:
    23, 24, 25, 29, 22, 28, 34, 30, 32

(I'm not asking for anyone to write my code [though, if you want to...]), I'm just looking for some pointers in the arduino software side.

Thanks in advance!
Raffikki

You can group things like this into any pattern you want, if you don't mind the code for it.

It seems you have two needs:

  • Simultaneous lighting of more than one LED (like 29 & 25).

  • Flexible timing amounts (400/500 msec)

One way to do this would be the use of sentinels (flags). For example, any number over 100 in the list is a time in msec, and any other number is a pin (just an example, you can use any idea you want).

So both entries combined would look like this:

int code[]={30,400,32,31,400,34,30,400,32,400,33,31,400,29,25,400,22,400,23,500,24,500,25,500,
29,500,22,500,28,500,34,500,30,500,32,500,-1};

As you walk through the array you would note all the pins, and at any entry >100, light those noted pins for that many milliseconds. In effect, you are creating a mini language for pin lighting (the -1 marks the end of the list).

In this case, you'd light pin 30 for 400msec, then turn it off and light both 32 and 31 for 400msec, then turn them off, and so forth.

Of course, this is just one way of encoding; but if this is the way you are thinking, the code becomes simple:

int code[] = {
30,400,32,31,400,34,30,400,32,400,33,31,400,
29,25,400,22,400,23,500,24,500,25,500,29,500,
22,500,28,500,34,500,30,500,32,500,
-1 };

void loop()
{
  int i, k, n;
  byte pins[99];
  for (k=0;k<99;++k) // clear pins
    pins[k]=0;
  // begin sequence
  i=0;
  while (1)
  {
    n=code[i++]; // get next array entry
    if (n<0)
      break; // done when -1
    else if ( n>0 && n <100 )
      pins[n]=1; // note that pin goes on next
    else // delay time - light them up
    {
      // first turn off old lights then turn on any new ones
      for (k=22;k<34;++k)
      {
        digitalWrite(led[k], LOW);
        if (pins[k]) // any on?
          digitalWrite(led[k], HIGH);
      }
      for (k=0;k<99;++k) // clear pins list for next entry
        pins[k]=0;
      delay(n); // wait
    }
  }
}

Using this, you can flash on/off groups as you wish. Of course, this code is not small or optimized (deliberately so - I didn't want to make it hard to understand). The 'pins' array for example can be much smaller (or even a bitfield). You could even wrap this in a function, and call it with the code[] array - this opens up the possibility of creating different array 'sequences' and just running them as you wish.

small improvement as leds are not turned off unneccessary

      for (k=22;k<34;++k)
      {
        digitalWrite(led[k], pins[k]);
      }