Multipurpose LED blinks

I am trying to get a single LED to indicate five different states: off, 1 flash per sec, 2 per sec, 3 per sec and on solid.

The on and off are no issue. But I want the flash on and off durations to be different, and the off to have a lengthier duration to make counting the flashes easier. I'm trying to avoid a simple blink interval where you can't easily count the blinks per second.

So:
1 flash could be 500ms on, 500ms off. Simple enough.
2 flashes could be 200 on 50 off, 200 on, 550 off
3 flashes could be 150 on, 50 off, 150 on, 50 off, 150 on, 450 off

Something like that, but open to improvement ideas.

And of course, non-blocking.

I have tried and made no progress. I feel like this has been done a million times but I'm coming up zeroes on how to work it out. Would appreciate some help! Thanks.

const byte ledPin =  13;

unsigned long previousMillis;

unsigned long offPeriods[] = {100, 200, 300, 400, 500};
byte offPeriodIndex = 0;
unsigned long onPeriod = 200;
unsigned long currentPeriod = offPeriods[offPeriodIndex];

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > currentPeriod)
  {
    if (digitalRead(ledPin))
    {
      currentPeriod = offPeriods[offPeriodIndex];
    }
    else
    {
      currentPeriod = onPeriod;
    }
    digitalWrite(ledPin, !digitalRead(ledPin));
    previousMillis = currentMillis;
  }
}

Change the value of offPeriodIndex to alter the off period of the blinking.

The demo Several Things at a Time flashes 3 LEDs without blocking. It uses separate values for the length of the ON and OFF periods.

...R

Thanks, Bob. I tried it, but it only flashes once per second with varying off durations. Unless I missed a setting in the example.

I am trying to get two and three blinks in rapid succession followed by a long off period of 1 second.

Like this: |||_________ or ||__________ where each is representing a cycle of 3 or 2 blinks.

What I came up with is silly but kinda shows hope:

byte loops;

const int PHLED  = 12;

unsigned long previousMillis = 0;




void setup() {
 pinMode(PHLED, OUTPUT);
}


void loop() {
 ledTwoBlinks(PHLED,100,200,100,1000,loops);

}


void ledTwoBlinks (int pin, int on1, int off1, int on2, int off2, byte pass) {
 if (pass == 0) {
   digitalWrite(pin, HIGH);
   previousMillis = millis();
   loops++;
 }
 if (millis() - previousMillis >= on1 && pass == 1) { //ready to turn off
   digitalWrite(pin, LOW);
   previousMillis = millis();
   loops++;
 }
 if (millis() - previousMillis >= off1 && pass == 2) { //ready to turn on for 2nd blink
   digitalWrite(pin, HIGH);
   previousMillis = millis();
   loops++;
 }
 if (millis() - previousMillis >= on2 && pass == 3) { //ready to turn off 2nd blink
   digitalWrite(pin, LOW);
   previousMillis = millis();
   loops++;
 }
 if (millis() - previousMillis >= off2 && pass == 4) { //waiting for next round
   loops = 0;
 }
}

Mm, I remember I kind of started on a library for that. But my need for it faded a bit… I works but it’s a bit rough / undocumented so I never published it. But here you go.

For example for the cases make the objects

BlinkX ledA(11, 500, 500); //just set on and off time
BlinkX ledB(12, 200, 50, 550); //pin 12, 200ms on, 50ms off, pause of 550ms
BlinkX ledB(13, 150, 50, 450); //pin 13, 150ms on, 50ms off, pause of 450ms

And call

ledA.blink(); //just continues blinking
ledB.blink(2, true); //2 blinks, then pause, does this continues
ledC.blink(3, true); //3 blinks, then pause, does this continues

And in loop() call

ledA.update();
ledB.update();
ledC.update();

Like I said, it’s a bit rough. If I have more time I’ll finish it including documentation :slight_smile:

BlinkX.cpp (2.93 KB)

BlinkX.h (1.28 KB)

Thanks Septillion. I have another issue to work and then I'll tear up the way I'm doing it now to try this lib. Thanks for posting.