Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Multi_Blink

A sketch that demonstrates how to do many things at once using a table driven approach. The method is extensible to many applications. Shown here is blinking a number of LEDs at different frequencies.

The latest version of Multi_Blink can be found here.

// Multi_Blink.h
//
// Blink lots of LEDs at different frequencies simultaneously
//
// Header file is required to be able to define the structured types
//
#include <Arduino.h>

#ifndef  MULTIBLINKH
#define  MULTIBLINKH

typedef struct
{
  uint8_t  activeVal;     // digital value for this state to be active (HIGH/LOW)
  uint16_t activeTime;    // time to stay active in this state stay in milliseconds
} stateDef;

typedef struct
{
  uint8_t  ledPin;         // Arduino I/O pin number
  uint8_t  currentState;   // current active state
  stateDef state[2];       // the ON and OFF state definitions. Add more states if required
  uint32_t lastTransTime;  // the 'time' of the last state transition - saves the millis() value
} ledTable;

#endif

// Multi_Blink
//
// Blink lots of LEDs at different frequencies simultaneously
//
// Marco Colli - May 2012
//
// Demonstrates the way to carry out multiple time based tasks without using the delay() function
// Demonstrates the use of structures (and structures within structures)
// Demonstrates a data driven approach to programming to create compact, reusable code
//

#include "Multi_Blink.h"  // type definitions

// Blink Table T - Modify this table to suit whatever the output requirements are
// Add or delete lines as required to achieve the desired effects.
//
ledTable  T[] =
//Pin  St   State 0      State 1  LastTime
{
  { 3, 0, {{HIGH, 300}, {LOW, 300}}, 0 },
  { 4, 1, {{HIGH, 300}, {LOW, 600}}, 0 },
  { 5, 0, {{HIGH, 500}, {LOW, 500}}, 0 },
  { 6, 1, {{HIGH,  50}, {LOW, 100}}, 0 },
  { 7, 0, {{HIGH, 100}, {LOW,  50}}, 0 },
  { 8, 1, {{HIGH, 500}, {LOW, 500}}, 0 },
  { 9, 0, {{HIGH, 400}, {LOW, 600}}, 0 },
  {10, 0, {{HIGH, 600}, {LOW, 400}}, 0 },
};

// Self adjusting constants for loop indexes
#define  MAX_STATE  (sizeof(T[0].state)/sizeof(stateDef))
#define  MAX_LED    (sizeof(T)/sizeof(ledTable))

void setup()
{
  for (int i=0; i < MAX_LED; i++)
  {
    pinMode(T[i].ledPin, OUTPUT);

    T[i].lastTransTime = millis();
    digitalWrite(T[i].ledPin, T[i].state[T[i].currentState].activeVal);
  }
}

void loop()
{
  for (int i=0; i < MAX_LED; i++)
  {
    // check if the state active time has expired (ie, it is less than current time)
    if (millis() >= T[i].lastTransTime + T[i].state[T[i].currentState].activeTime)
    {
      // switch to the next state with wrapround
      T[i].currentState = (T[i].currentState + 1) % MAX_STATE;

      // write out the next state value
      T[i].lastTransTime = millis();
      digitalWrite(T[i].ledPin, T[i].state[T[i].currentState].activeVal);
    }
  }
}