Multiple independent LED patterns

Handling multiple patterns at the same time is certainly possible with a platform like Arduino, and there are a number of ways you could go about it.

One method I would consider is writing functions which effectively represent each pattern mathematically. You'd just pass it the total time that's elapsed in your program so far, and it will do the appropriate action for that specific moment in time. It will return immediately afterwards (no delays or anything).

To do that, you'll first need to know how long a single cycle of the pattern lasts. You can then use the modulo operator to figure out how far through the current cycle you are. From there, all you need to do is have some if conditions to determine what to do at any given time.

Here's what it might look like for your "5 seconds on, 5 seconds off" pattern:

function pattern5on5off(unsigned long totalTime)
{
  // Calculate how far through the current cycle we are
  const unsigned long cycleTime = totalTime % 10000;

  // If we're in the first 5 seconds of the cycle then turn the light on.
  // Otherwise, turn it off.
  if (cycleTime < 5000)
    digitalWrite(3, HIGH);
  else
    digitalWrite(3, LOW);
}

Admittedly, constantly calling digitalWrite() when you don't technically need to isn't very efficient. It shouldn't cause any harm though, and is fairly easy to optimise if necessary.

To use the above example in a sketch, you'd just need to call it in loop(), and pass the number you get from millis(); e.g.:

void loop()
{
  const unsigned long totalTime = millis();

  pattern5on5off(totalTime);

  // call other patterns here...
}

Other patterns will be more complex, but follow the same principle. You'd just to use appropriate if statements to express your logic.

The vital thing to remember is that the function represents a specific moment in time. It should never pause or delay the program, otherwise it will prevent the other patterns from running.

Edit: Timing on the first cycle
As jfpoilpret noted in the comments, the very first cycle will start at a random point. This is because the first time you call millis() in loop(), it won't start at 0 (the device will already have been running for a short time before loop() gets called). It's easy to resolve though, if necessary.

You would do it by offsetting the totalTime value by the whatever value you got on the very first time around loop(). For example:

unsigned long g_startTime = 0;

void loop()
{
  unsigned long totalTime = 0;

  if (g_startTime == 0) {
    // This is the first cycle.
    // Store the start time so we can compensate later.
    g_startTime = millis();

  } else {
    // This is not the first cycle.
    // Compensate for the start time.
    totalTime = millis() - g_startTime;
  }

  pattern5on5off(totalTime);
  // etc..
}

Arduino is a fine choice for the task - easy to get started with. The key is to write non-blocking code. You could take a look at the BlinkWithoutDelay example.

I made a suggestion for your task:

// Timing suquences for the LED's in milliseconds
// First value is on time, second value is off time,
// third value on time and so on (up to 10 values)
// One row for each LED
unsigned int led_timing[][10] = {
  {5000, 5000},
  {100, 1000},
  {100, 100, 100, 1500, 100, 1500}
};

// The pins the LED's are connected to
byte led_pins[] = {11, 12, 13};

// Keep track of timing sequence
// Array size taken from led_pins
unsigned long last_change[sizeof(led_pins)/sizeof(led_pins[0])];
byte timing_i[sizeof(led_pins)/sizeof(led_pins[0])];

void setup()
{
  // Initialize LED's as output
  for (byte i = 0; i < sizeof(led_pins)/sizeof(led_pins[0]); i++)
  {
    pinMode(led_pins[i], OUTPUT);
    digitalWrite(led_pins[i], HIGH);
  }
}


void loop()
{
  // Current timestamp
  unsigned long now = millis();

  // Keep track of sequence for each LED
  for (byte i = 0; i < sizeof(led_pins)/sizeof(led_pins[0]); i++)
  {
    if (now - last_change[i] >= led_timing[i][timing_i[i]])
    {
      digitalWrite(led_pins[i], !digitalRead(led_pins[i]));
      timing_i[i]++;

      // Start over at the end of timing sequence
      timing_i[i] %= sizeof(led_timing[i])/sizeof(led_timing[i][0]);

      last_change[i] = now;
    }
  }
}