Millis() !? LED should blink x interval every y seconds

Hi Hackers !

didnt get it ! I understood how to use millis() function as timer (currentmillis - pervmillis > interval).
I made a void Blinkts wich flashes the LED periodically.

How can I call this function Blinkts periodically in loop with another "millis()" timer ?

At the end the LED should blink with x interval every y seconds

Here is my continously blinking LED without "delay".



int stateLED = LOW;
const int onBoardLED = 2;

unsigned long previousLEDmillis = 0;                    // timestamp stores time LED changed                            


void blinkts(int blinkLEDInterval) {

  
  unsigned long timeNow = millis();                                    //start a millis count

    if (timeNow - previousLEDmillis > blinkLEDInterval) { // counts up time until set interval
      previousLEDmillis = timeNow;                        // save it as new time (interval reset)
        if (stateLED == LOW)  {                                 // check if LED is LOW
        stateLED = HIGH;                                           // then set it HIGH for the next loop
        Serial.println("ON");                                     // Print "ON" at Serial console

      } else  {      
        stateLED = LOW;                                       // in case LED is HIGH make LED LOW
        Serial.println("OFF");                            // Print "OFF" at Serial console
      }
 
      digitalWrite(onBoardLED, stateLED);            // LED goes HIGH / LOW
  }
}



void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);                                                // initialize serial interface (baudrate)
  pinMode(onBoardLED, OUTPUT);                          // initialize LED pin as output
  }


void loop() {
  // put your main code here, to run repeatedly: prevent (delay) in loop !!
  
  blinkts(30);                                                             //execute void blinkts with (int blinkLEDInterval)
}

Hint

void blinkts(int blinkLEDInterval) 
{
  static unsigned long previousLEDmillis;
  unsigned long timeNow = millis();

  if (timeNow - previousLEDmillis >= blinkLEDInterval) { // counts up time - 0, until time becomes greater than interval
  previousLEDmillis = timeNow;                        // save it as new time (interval reset)
    if (stateLED == LOW)  {
    stateLED = HIGH;
    Serial.println("ON");
  } else  {      
    stateLED = LOW;
    Serial.println("OFF"); 
  }

  digitalWrite(onBoardLED, stateLED);
}
}

Please remember to use code tags when posting code.

Im a newbie sorry. Want to call (tagged code) void blinkts(30) every 5 sec with another millis timer in loop.
Flashing 5sec. -> LED off 5sec -> flashing 5sec-> LED off 5sek and so on...

You want the LED to flash constantly at 0.2Hz ?


In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.
Use the </> icon from the ‘reply menu’ to attach the copied sketch.

See How to write Timers and Delays in Arduino for an examples.

int led = 13; // Pin 13 has an LED connected on most Arduino boards.

unsigned long DELAY_TIME = 1500; // 1.5 sec
unsigned long delayStart = 0; // the time the delay started
bool delayRunning = false; // true if still waiting for delay to finish

bool ledOn = false; // keep track of the led state

void setup() {
  pinMode(led, OUTPUT);   // initialize the digital pin as an output.
  digitalWrite(led, LOW); // turn led off
  ledOn = false;

  // start delay
  delayStart = millis();
  delayRunning = true;
}

void checkToggleLed() { // led task
  // check if delay has timed out
  if (delayRunning && ((millis() - delayStart) >= DELAY_TIME)) {
    delayStart += DELAY_TIME; // this prevents drift in the delays
    // toggle the led
    ledOn = !ledOn;
    if (ledOn) {
      digitalWrite(led, HIGH); // turn led on
    } else {
      digitalWrite(led, LOW); // turn led off
    }
  }
}
void loop() {
  checkToggleLed(); // call to toggle led based on timer
}

OR using millisDelay class (from my SafeString library, available from the library manager)

#include <millisDelay.h>

int led = 13;
// Pin 13 has an LED connected on most Arduino boards.
bool ledOn = false; // keep track of the led state

millisDelay ledDelay;

void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);   // initialize the digital pin as an output.
  digitalWrite(led, LOW); // turn led off
  ledOn = false;

  // start delay
  ledDelay.start(1500);
}

void checkToggleLed() { // led task
  // check if delay has timed out
  if (ledDelay.justFinished()) {
    ledDelay.repeat(); // start delay again without drift
    // toggle the led
    ledOn = !ledOn;
    if (ledOn) {
      digitalWrite(led, HIGH); // turn led on
    } else {
      digitalWrite(led, LOW); // turn led off
    }
  }
}
void loop() {
  checkToggleLed(); // check if should toggle led based on timer
}

@isname_b Hi, welcome to the forum. This topic is a little confusing (both your question and the answers).

Could you please edit your first post and put the sketch between code tags ? Put your sketch between lines with three backslash-single-quotes.

```
Your sketch
```

LarrayD wrote about the </> button, they will also give those lines with those backslash-single-quotes.

The first example by drmpf shows the 'bool' variable "delayRunning" to be able to turn on and off a millis-timer and a 'bool' variable "ledOn" to keep track of the state of the led.

Using global 'bool' variables for that is a good an easy way to guide the Arduino through the sketch.

I think you want a millis-timer to turn another millis-timer on and off.
My solution is to put both millis-timers in the main level of the loop(). I have the same 'bool' variables as drmpf, but I call them "enableBlink" and "blink" in my millis_within_millis.ino example.

If you look at my Fun with millis page, you can find the millis_within_millis.ino example and there is a button to try it in Wokwi.

@drmpf, You use the more dangerous delayStart += DELAY_TIME; which should only be used when it should stay synced with time. If the variable delayRunning would be used, then the millis-timer will catch up with a burst of led toggles. If the delayRunning would be made false, the led could be on at the moment and then the led stays on.

If the second interval is an exact multiple of the first, you don't need any more messing around with millis(). Just count first intervals with a counter variable. When it reaches its limit, perform the second action and reset it. That way you can use the same timer for both tasks.

Yes very true, particularly if delays( ) are use elsewhere in the code.
The millisDelay code uses
ledDelay.repeat(); // start delay again without drift
which does the same thing, with the possible same problem

But you can also use
ledDelay.restart(); // start delay again may drift
which avoids that issue, but drifts

@aarg you didn't say if you want an extra 'bool' variable or use the 'count' itself for turning on and off the blinking.

This is with using the 'count':

// Blink a led 10 times with 150ms and then stay off for 10 times.

const int ledPin = LED_BUILTIN;

unsigned long previousMillis;
int count;
bool blink;

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

void loop()
{
  unsigned long currentMillis = millis();

  if( currentMillis - previousMillis >= 150)
  {
    previousMillis = currentMillis;

    if( count < 10)   // even number to turn led off during longer interval
    {
      blink = !blink;
      digitalWrite( ledPin, blink ? HIGH : LOW);  // turn bool variable into HIGH and LOW
    }

    count++;
    if( count > 20)
      count = 0;      // reset the variable
  }
}

This sketch in Wokwi:

@isname_b I hope you have a few good examples now. Don't pick a working sketch that is weird, pick one that you feel most comfortable with, adapt it for your own project and show us your sketch.

This is for example a working sketch that you should not pick. It is the most ugly sketch that I can think of:

void setup(){DDRB=bit(5);}void loop(){digitalWrite(13,millis()%2000>1000&&millis()%300>150);}

Hello and good morning
I have designed a sketch using two millis() based timer.

  1. Timer to blink the LED
  2. Timer to control the LED blinking.
struct TIMER {
  unsigned long stamp;
  unsigned long duration;
  bool state;
};
TIMER ledBlink {0, 100, 0};  // timer for LED to blink with 100 msec
TIMER blinkBlink {0, 2000, 0}; // timer to control LED blinking with 2000 msec
unsigned long currentTime;

void setup() {
  pinMode (LED_BUILTIN, OUTPUT);
}
void loop () {
  currentTime = millis();
  // timer for LED
  if (currentTime - ledBlink.stamp >= ledBlink.duration && ledBlink.state) {
    ledBlink.stamp = currentTime;
    digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN) ? 0 : 1);
  }
  // timer to control blinking LED
  if (currentTime - blinkBlink.stamp >= blinkBlink.duration)   {
    blinkBlink.stamp = currentTime;
    ledBlink.state = !ledBlink.state;
    digitalWrite(LED_BUILTIN, ledBlink.state );
  }
}

Have fun and enjoy the weekend.

2 Likes

yes 0.3hz :slight_smile:

oh THANK YOU !! It is beautiful :partying_face:
There is the bool ! yay !

You made the right choice - with the count, you can easily implement arbitrary sequences of actions, including changing the number of blinks on/off and so on... you just provided the 50% duty cycle condition with the 10/20 arrangement.

Thanks ! Thats an awesome example. Will have fun with millis :slight_smile: