Blinking at an interval independent from main LOOP

I want my program to make an LED blink at say 500 ms On, 250 ms off. I can do this easily as an isolated task using digitalWrite and delay. but I want to keep this blinking happening while my loop continues running as fast as it can. is that possible?

Look at the blink without delay example in the IDE.

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

If you are lazy, use a library like TDuino:

#include <TDuino.h>

#define BLINK_LED_PIN 3

TPinOutput pin_out;

void setup()
{
  pin_out.attach(BLINK_LED_PIN);
  pin_out.pulse(250, 500, 0, LOW);
  //Other setup code
}

void loop()
{
  pin_out.loop();
  //Other loop code
}

Any delay in your sketch may break the functionality of TDuino :slight_smile:

What about the following algorithm (tested on NANO) using TC1 running at clkTC1 = 16 MHz/256.; no polling business; just check on the fly?

bool flag = HIGH;
void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  TCCR1A = 0x00;
  TCCR1B = 0x00;
  TCNT1 = 0x85EE;  //0.5 s   C2F7  0.25
  TCCR1B = 0x04;  // /256 = 62500
}

void loop()
{
  if (bitRead(TIFR1, 0) == HIGH)
  {
    digitalWrite(13, !digitalRead(13));
    bitSet(TIFR1, 0);
    if (flag == HIGH)
    {
      TCNT1 = 0xC2F7;  //250 ms
      flag = LOW;
    }
    else
    {
      TCNT1 = 0x85EE;  //500 ms
      flag = HIGH;
    }
  }
}

@GolamMostafa: LOL.. You forgot to somehow implement an interrupt for simplicity! ;)

Danois90: You forgot to somehow implement an interrupt for simplicity! ;)

You have wanted to mean the following interrupt version -- this also works fine! So, simple (the loop house is clean); thanks and p.. for the inspiration? (But, there is an interrupt overhead push/pop out-of-stack? In which is the loop() moving faster -- the interrupt version or the non-interrupt version?)

volatile bool flag = HIGH;
void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  TCCR1A = 0x00;
  TCCR1B = 0x00;
  TCNT1 = 0x85EE;  //0.5 s   C2F7  0.25
  TCCR1B = 0x04;  // /256 = 62500
  bitSet(TIMSK1, 0); //local interrupt enable
  interrupts();     //global interrupt enable
}

void loop()
{

}

ISR(TIMER1_OVF_vect)
{
  digitalWrite(13, !digitalRead(13));
  if (flag == HIGH)
  {
    TCNT1 = 0xC2F7;  //250 ms
    flag = LOW;
  }
  else
  {
    TCNT1 = 0x85EE;  //500 ms
    flag = HIGH;
  }
}

GolamMostafa: What about the following algorithm

Does it never occur to you to give advice that a beginner might understand?

And neither do I believe that any expert Arduino programmer would go to that much trouble to solve the OP's simple problem.

When you get these bright ideas why not just write a Reply that says "I know a more complicated way to do this, let me know if you would like me to tell you about it."

...R

Robin2: When you get these bright ideas why not just write a Reply that says "I know a more complicated way to do this, let me know if you would like me to tell you about it."

Danois90: @GolamMostafa: LOL.. You forgot to somehow implement an interrupt for simplicity! ;)

Complicated..? It is totally relative?

Keep it simple

unsigned long currentTime;
unsigned long flashStartTime;
unsigned long periods[2] = {250, 500};
const byte ledPin = 13;
byte flashCounter;

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

void loop()
{
  flashLed();
  //other code goes here
}

void flashLed()
{
  currentTime = millis();
  if (currentTime - flashStartTime >= periods[flashCounter % 2])
  {
    flashStartTime = currentTime;
    flashCounter++;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}