Blink Pattern without Delay

I need to blink an led in a certain pattern, nothing too complicated, something like blink every 250mS but skip every 5th for example. So blink 4 times every 250mS wait 500mS blink 4 times every 250mS etc etc.

I have looked at this: http://www.gammon.com.au/blink installed the library and got it working.

What do I need to do in order to make it blink in a pattern as described above?

The LED_flasher library is not ment to generate a sequence of led flashes. Do you understand how millis() is used ?

You could use a table with the sequence, or use a software timer with millis() and count the software timer events.

How long should the led be on when it blinks ? 20 ms ? Should it work without disturbing the rest of the sketch ? Is the skipped blink a variable, or is it a fixed sequence ?

You could have an array with the blink durations in it and by iterating through the array you could have any pattern you want.

I think you need to write some code and post it so that we get a better idea of the overall project.

The demo Several Things at a Time is an extended example of BWoD and may help to understand the concept.

...R

// yet another blink sketch by aarg, Arduino forum
//
// circular list of intervals, alternating off and on
unsigned long intervals[] = {100, 100, 100, 100, 100, 100, 50, 2000, 50, 1000, 500};
const byte NUM_OF_INTERVALS = sizeof(intervals) / sizeof(unsigned long);
byte currentInterval = 0;

unsigned long previousMillis = 0;
void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();          //get current value of millisecond counter
  if (currentMillis - previousMillis >= intervals[currentInterval])  //if the time interval has elapsed
  {
    currentInterval = currentInterval + 1;     // select the next interval in the list
    if (currentInterval >= NUM_OF_INTERVALS)
      currentInterval = 0;
    digitalWrite(LED_BUILTIN, not digitalRead(LED_BUILTIN));    //change state of the LED
    previousMillis = currentMillis;                //save the time of change
  }
}

aarg, Could you explain this code a bit by adding comments? How would you for example, change the "master clock" of this entire sequence to be slower of faster with a potentiometer?

Interesting question: you could scale “interval” with a variable “intervalFactor”.

So this line:

if (currentMillis - previousMillis >= intervals[currentInterval])

… would be:

if (currentMillis - previousMillis >= intervalFactor*intervals[currentInterval])

The variable “intervalFactor” could in turn be modified by reading a pot and use map() to create “intervalFactor”:

intervalFactor= map(analogRead(potPin), 0, 1023, <whatever>, <whatever>);

E&OE… not yet 0530 on a Saturday and brain not fully engaged. Something like the above, anyway :slight_smile:

thanks JimboZA, I’ve tried ‘map’ but it doesn’t quite act as an even divisor-- So if I wanted the overall speed to be divided by 2 at the lowest end of the pot and multiplied by 2 at the highest end, I tell it:

intervalFactor= map(analogRead(potPin), 0, 1023, 0.5, 2) and then :

if (currentMillis - previousMillis >= intervalFactor*intervals[currentInterval])

but that doesn’t work correctly. It only multiplies by 2 at one far end of the pot, and nothing else changes.
For now I’ve made it add 0-1023 to [currentInterval] to get a similar effect (for now.)

Map doesn’t act like “assign”, so that’s the problem i’m having.
anyway thanks for the help, if anybody can help with trying to do the above, I’d appreciate the input!

Well it was very early, but glad that it works at all even if it's with a kluge right now.

intervalFactor = map(analogRead(potPin), 0, 1023, 0.5, 2);

does not work with floats, so the 0.5 probaly ends in a 1.

How about

float intervalFactor = map(analogRead(potPin), 0, 1023, 1, 4)/2.0;

If I was. doing this, I'd use the concept described above-EXCEPT, I'd use a signed int array for the pulse durations. A negative value indicates ab 'off' period and 'positive duration indicates 'on'

Use abs() to derive the actual delay time... and use millis() not delay()!

arch_ive: aarg, Could you explain this code a bit by adding comments?

There is a comment on almost every line.

lastchancename: If I was. doing this, I'd use the concept described above-EXCEPT, I'd use a signed int array for the pulse durations. A negative value indicates ab 'off' period and 'positive duration indicates 'on'

Use abs() to derive the actual delay time... and use millis() not delay()!

Adjacent identical states are redundant. Why would you have an off state followed by an off state? All you really need is an initial state. I should have added that so you could have an odd number of intervals. Edit - that's redundant as well, since with an odd number of intervals, the first and last interval would have the same polarity. I threw it in, just to prevent problems if the functionality is extended.

Untested:

// yet another blink sketch by aarg, Arduino forum
//
// circular list of intervals, alternating off and on
// with variable speed set by analog reading

unsigned long intervals[] = {100, 100, 100, 100, 100, 100, 50, 2000, 50, 1000, 500};
const byte NUM_OF_INTERVALS = sizeof(intervals) / sizeof(unsigned long);
byte currentInterval = 0;
const byte startingLEDstate = HIGH;
byte LEDstate = startingLEDstate;
unsigned long previousMillis = 0;

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

void loop()
{
  int speedSetting = analogRead(A0);
  // 0 = 1/4 speed, 512 = normal, 1023 = roughly quad speed
  float speedFactor = pow(2, (speedSetting - 512) / 256 );

  unsigned long currentMillis = millis();          //get current value of millisecond counter
  //if the time interval has elapsed
  if (currentMillis - previousMillis >= (unsigned long)(speedFactor * intervals[currentInterval]))
  {
    currentInterval = currentInterval + 1;     // select the next interval in the list
    if (currentInterval >= NUM_OF_INTERVALS)  // start at beginning if end is reached
    {
      currentInterval = 0;
      LEDstate = startingLEDstate;
    }
    digitalWrite(LED_BUILTIN, LEDstate);  // output
    LEDstate = !LEDstate;  //change state of the LED
    previousMillis = currentMillis;                //save the time of change
  }
}

Why would you have adjacent off states?

lastchancename: Why would you have adjacent off states?

Exactly. They have no use. So having an array of on/off states, or using the sign to store on/off states makes no sense. You only need the initial state, and a series of intervals.