Blinking two LEDs in and out of phase

This is, again, trying to run both patterns simultaneously. If your patterns are non-blocking you have to have loop() decide which pattern should be playing at any one time.

One way is to have loop() keep a (static or global) counter of which pattern is running. If you want the pattern to have control of when it is done, have it return a flag to say if it is done or not.

const byte led1 = 2;
const byte led2 = 8;

unsigned long cycleCount = 0;

unsigned long previousMillis = 0;

// Return 'true' when done.
boolean blink(unsigned long onTime, unsigned long phaseDifference, unsigned long rate, unsigned long repetitions)
{
  if (cycleCount >= repetitions)
    return true; // done

  unsigned long timePassed = millis() - previousMillis;

  if (timePassed >= rate)
  {
    previousMillis = millis(); // Start a new cycle
    timePassed = 0;
    cycleCount++;
  }

  if (timePassed < onTime)
  {
    digitalWrite(led1, HIGH);
  }
  else
  {
    digitalWrite(led1, LOW);
  }

  if (timePassed >= phaseDifference && timePassed < (phaseDifference + onTime))
    digitalWrite(led2, HIGH);
  else
    digitalWrite(led2, LOW);

  return false; // Not done yet
}

void setup()
{
  Serial.begin(115200);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop()
{
  static int whichPattern = 0;
  boolean done = false;

  switch (whichPattern)
  {
    case 0:
      done = blink(50, 0, 500, 10);
      break;

    case 1:
      done = blink(500, 50, 1000, 5);
      break;

    default:
      done = true; // No such pattern
      whichPattern = -1; // before the first pattern
      break;
  }

  if (done)
  {
    whichPattern++; // next pattern
    cycleCount = 0; // starting a fresh pattern
  }
}
1 Like