Blink without delay but with inequal interval

`I was wondering if I can make an arduino to blink an LED at an inequal interval. I tried searching but I could not find anything like that. Example code works with an equal interval, like a 1000ms and can be changed.

For delay function, it is easy to change the inequal interval like shown below but delay will stop other codes and wait.

  digitalWrite(LED_BUILTIN, HIGH);   
  delay(200);                     
  digitalWrite(LED_BUILTIN, LOW);   
  delay(5000);

Can we make it blink like that, without delay ?

Easy.
Just change interval every time you changed the LED state:

  unsigned long currentMillis = millis();
  unsigned long interval = 1000;

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
      interval = 200;
    } else {
      ledState = LOW;
      interval = 5000;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
2 Likes

..and that’s the long-form, easy to understand version !

Just an other proposal:

unsigned long currentMillis = millis();
unsigned long previousMillis = millis();
unsigned long interval[] = {5000,200};
constexpr uint8_t ledPin = LED_BUILTIN;
uint16_t ledState=LOW;
void setup()
{
  pinMode (ledPin, OUTPUT);
}
void loop()
{
  currentMillis = millis();
  if (currentMillis - previousMillis >= interval[ledState]) 
  {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
{
      ledState = HIGH;
    }
    else 
    {
      ledState = LOW;
    }
    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

hth

3 Likes

Wow! That was fast. Thanks, it really worked.

Both of your codes are very good. I'm awarding the solution to @b707 because it was dead simple to understand for a beginner like me.

@paulpaulson , if you don't mind, why using constexpr. They work without that also, so why use that?

YAM (yet another mousetrap) YAB (yet another blink-without-delay)

byte ledPin = LED_BUILTIN;
int ledON = 200, ledOFF = 5000; // LED state intervals
unsigned long timer;

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

void loop() {
  if (millis() - timer >= (digitalRead(ledPin) == 0 ? ledOFF : ledON)) { // read pin state, set interval
    timer = millis(); // set new timer for next interval
    digitalWrite(ledPin, !digitalRead(ledPin)); // set LED pin state to opposite (!) current pin state
  }
}
5 Likes

brilliant solution

1 Like

What is brilliancy -- someone says that it is the simplicty with clarity?

1 Like

Good one.

1 Like

... I put various bits of what I learned on this Forum from you lot. I don't understand a lot of your (collective) solutions, but I try to read and learn (some stuff I just do not have the capacity to comprehend). Thank you for showing your many different ideas. It is loads of fun.

My way: :grin:

void setup()
{
  //Serial.begin(9600);
  pinMode(LED_BUILTIN,OUTPUT);
}

void loop()
{
  static unsigned long
    timer,
    elapsed;
  unsigned int
    onTime = 100,
    offTime = 900,
    cycleTime = onTime + offTime;

  elapsed = millis() - timer;
  if(elapsed >= cycleTime)
  {
    timer += cycleTime;
  }
  digitalWrite(LED_BUILTIN, elapsed < onTime);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.