LED delay off with milli()

The LED blinky is quite easy but how can this be done to switch OFF after it is ON for a second.

void LED(int val) {
  unsigned long CurrentMillis = millis();
  if (CurrentMillis - PreviousMillis >= val)
  {
    digitalWrite(LED, HIGH);
    PreviousMillis = CurrentMillis;
  }
}

void loop()
{
  LED(600);
}

here i've created function and called it within the loop. This way i could call it several times like

void loop();
{
  LED (100) 
  LED(1000);
  LED(600);

would the above approach would be the best

(deleted)

wouldn't that just turn it off after a blink and back on ? where would that part go ?

PreviousMillis = CurrentMillis;

Wherever you put that line. That's the point you're timing from. If you want to wait two seconds after you turn on an LED, then put that line with the line turning on the LED.

Don't look at those lines as magic lines that magically do some timing. Think about what's actually going on. It's really quite simple.

Waves magic wand Blinkiio!

hmmmm still don't get it. :confused:

void LED(int val) {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= val) //turns on LED after val number of millis
  {
    digitalWrite(LED, HIGH);
    previousMillis = currentMillis; //restarts the timer but LED still on
  }

 if(currentMillis - previousMillis >= 1000) //after a literal second has passed, turns off LED
 {
    digitalWrite(LED, LOW);
    previousMillis = currentMillis; //restarts the timer
  }

}

The approach has merit, but you need to call the function repeatedly to determine when the timeout has expired. It seems more complicated than it needs to be.

I assume previousMillis is declared global or static somewhere...
As Delta_G alluded, you need to understand what's happening, not just cut & paste from examples.

There are several approaches to address your requirement, and you're on the right track - just work through what's actually happening.

It's good to see you're using millis(), and not delay() !!

Here is what I believe you want, do you understand the example, would you be able to add a one minute flashing led on D8 ?

//Blink without Delay Function skeleton
//LarryD
 
unsigned long currentMillis;
 
//each new timer requires similar three lines of code
unsigned long Millis13;
boolean       repeat13    = true; //repeat this sequence?
boolean       flag13      = true; //is this timer enabled?
//
 
//**********************************************************************
 
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
 
 
} //  >>>>>>>>>>>>>> E N D  O F  s e t u p ( ) <<<<<<<<<<<<<<<<<
 
 
void loop()
{
  //***************************   HeartBeat LED
  //toggle pin 13 every 200mS
  if (flag13 == true && CheckTime(Millis13, 200UL, repeat13))
  {
    //toggle pin 13
    digitalWrite(13,!digitalRead(13));
   
    //if you only want this section of code to happen once
    //uncomment the next line
    //flag13 = false; //disables the above code
  }
  //***************************
 
 
  //put other non-blocking stuff here
 
 
} //  >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<
 
 
//======================================================================
//                      F U N C T I O N S
//======================================================================
 
//**********************************************************************
//Delay time expired function
//lastMillis = time we started, wait = delay in mS, restart = do we start again 
boolean CheckTime(unsigned long &lastMillis, unsigned long wait,boolean restart)
{
  //is the time up for this task?
  if (millis() - lastMillis >= wait)
  {
    //should this start again?
    if(restart)
    {
      //get ready for the next iteration
      lastMillis = millis(); //get ready for the next iteration
    }
    return true;
  }
  return false;
 
} // END of CheckTime()
 
//**********************************************************************
 
//======================================================================
//                      E N D  O F  C O D E
//======================================================================
int LED = 5;
int LedState = LOW;
unsigned long PreviousMillis = 0;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  unsigned long CurrentMillis = millis();
  if (CurrentMillis - PreviousMillis >= 100) //turns on LED after val number of millis
  {
    digitalWrite(LED, HIGH);
    PreviousMillis = CurrentMillis; //restarts the timer but LED still on
  }

 if(CurrentMillis - PreviousMillis >= 100) //after a literal second has passed, turns off LED
 {
    digitalWrite(LED, LOW);
    PreviousMillis = CurrentMillis; //restarts the timer
  }
}

This was something i had tried out earlier seems to be same thing suggested by @INTP. here again the LED just stays on and does not go off after the mentioned time.

@LarryD - I am sure that would work but am among those who wish to learn the stuff before implementing. Yours is a little long and confusing to me. Am still trying out things.

Delta_G:

PreviousMillis = CurrentMillis;

Wherever you put that line. That's the point you're timing from. If you want to wait two seconds after you turn on an LED, then put that line with the line turning on the LED.

Don't look at those lines as magic lines that magically do some timing. Think about what's actually going on. It's really quite simple.

can't help but think....

PreviousMillis = CurrentMillis;
delay (2000);

anishkgt:
This was something i had tried out earlier seems to be same thing suggested by @INTP. here again the LED just stays on and does not go off after the mentioned time.

I think what's happening is that since val is probably less than 1000 (you didn't post your whole code so assumptions have to be made) it only ever enters the first loop.

I would try throwing in an extra condition that says to turn it on only if it was off, otherwise go onto that second loop to check time to go from off to on.

That is the whole code. So i will do some serial print and see what is which.

creaate a new field

boolean ON ;

this will be either 1 or 0
 if(CurrentMillis - PreviousMillis >= 100) 
{
ON = !ON;
digitalWrite(LED,ON);
}
this will set your LED to the current state of the value of ON

AND, every time the IF is true, it will toggle the state of ON.

the problem is that you are not controlling it to be OFF at any particular place in the sketch.

I was referring to your first post.

The most recent one you posted, you took out val and replaced it with 100.

You have two condition checks for the same thing.

What’s happening is:

Timer starts
Timer notices 100ms has passed
First loop executes (turns LED on, resets timer difference result to 0)
Entire loop runs a whole bunch of times for all timer differences from 0 to 99, and nothing happens, because it’s just waiting for some condition to be found.
Timer notices again 100ms has passed
First loop executes again (but LED was already on, resets timer)

never gets to the second loop to turn off the LED.

I’m guessing you want to avoid using delay, in case this is a ramp up to something more complex like simultaneous events, but if your end goal is to just have an LED turn on for X amount of time every so often, then a delay between on and off command is all you need.

[code=]
int LED = 5;
int LedState = LOW;
unsigned long PreviousMillis = 0;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  unsigned long CurrentMillis = millis();

  if (CurrentMillis - PreviousMillis >= 100) && (CurrentMills
 -PreviousMills <=110) { //turns on LED after val number of millis
  {
    digitalWrite(LED, HIGH);
  }

 if(CurrentMillis - PreviousMillis >= 200) //after a literal second has passed, turns off LED
 {
    digitalWrite(LED, LOW);
   PreviousMillis = CurrentMillis; //restarts the timer
  }
}
duration = (millis() - PreviousMills );

if (durantion <= 100 ){
digitalWrite(LED,HIGH);     // turns LED OFFF\
}

if(duration >=101){
ditialWrite(LED,LOW);  // after the timing.. turns the LED ON
}

if (duration >=200){
PreviousMills=millis());  // effectively turning the LED OFF 
}

this has the problem that the led will not come on until the first timing period.
if you swap high and low, it will always be on.

I like to use this format as it makes it easier for me to read.

alternately, you can re-set duration just before you do any testing.
need to do this if the program gets long.

duration = (millis() - PreviousMills );

if (duration >=200){
PreviousMills=millis());  // effectively turning the LED OFF 
}

if (duration >=10) && ( duration <= 100 ){ 

                     // 10ms delay to allow the program to spend time doing other things 

digitalWrite(LED,LOW);     // turns LED ON
}

if(duration >=101){
ditialWrite(LED,HIGH);  // after the timing.. turns the LED OFF
}

So after a while reached somewhere closer.

int LED = 5;
bool LedState;

void setup() {
  pinMode(LED, OUTPUT);
  LedState = digitalRead(LED);
  Serial.begin(9600);
}

void loop() {
  unsigned long CurrentMillis = millis();
  unsigned long PreviousMillis = 0;
  digitalWrite(LED, HIGH);
  if (CurrentMillis - PreviousMillis >=1000)
  {
    PreviousMillis = CurrentMillis;
    digitalWrite(LED,LOW);
  }
  }

so the above did not work but adding a delay at the end does it but why a dealy() again :o

int LED = 5;
bool LedState;

void setup() {
  pinMode(LED, OUTPUT);
  LedState = digitalRead(LED);
  Serial.begin(9600);
}

void loop() {
  unsigned long CurrentMillis = millis();
  unsigned long PreviousMillis = 0;
  digitalWrite(LED, HIGH);
  if (CurrentMillis - PreviousMillis >=1000)
  {
    PreviousMillis = CurrentMillis;
    digitalWrite(LED,LOW);
    delay(1000);
  }
  }

ok Silly me. It was the delay() that was causing the blink.