# Arduino: Independent On-Off Times with Millis()

When using delay() to flash a LED there is a time for the LED to be on and then off. This makes it easy to have independent control of the “on” and “off” times. The standard blink without delay example doesn’t give you this flexibility.

This example code gives you complete independant control of how long a LED (or any OUTPUT pin) stays “ON” or “OFF”. This also demonstrates a very simple two-state state machine.

The variable “LED13state” is used to track what should happen each time the millis() event fires.

// On and Off Times (as int, max=32secs)
const unsigned int onTime = 1000;
const unsigned int offTime = 500;

// Tracks the last time event fired
unsigned long previousMillis=0;

// Interval is how long we wait
int interval = onTime;

// Used to track if LED should be on or off
boolean LED13state = true;

// Usual Setup Stuff
void setup() {
pinMode(13, OUTPUT);
}

void loop() {
// Set Pin 13 to state of LED13state each timethrough loop()
// If LED13State hasn't changed, neither will the pin
digitalWrite(13, LED13state);

// Grab snapshot of current time, this keeps all timing
// consistent, regardless of how much code is inside the next if-statement
unsigned long currentMillis = millis();

// Compare to previous capture to see if enough time has passed
if ((unsigned long)(currentMillis - previousMillis) >= interval) {
// Change wait interval, based on current LED state
if (LED13state) {
// LED is currently on, set time to stay off
interval = offTime;
} else {
// LED is currently off, set time to stay on
interval = onTime;
}
// Toggle the LED's state, Fancy, eh!?
LED13state = !(LED13state);

// Save the current time to compare "later"
previousMillis = currentMillis;
}
}


Long comments, URLs, and code tend to get flagged for spam moderation. No need to resubmit.

ALL comments submitted with fake or throw-away services are deleted, regardless of content.

Don't be a dweeb.

## 56 thoughts on “Arduino: Independent On-Off Times with Millis()”

1. tofa says:

Nice tutorial. But sir, how if use 2 LEDs, blinks alternatly. With off-delay both leds before they change their blink.

• I don’t understand your question.

• tofa says:

Thank you sir and sorry for my bad english. I mean…

( led 1 on , led 2 off ) then

( led 1 off, led 2 off ) then

( delay 5 second ) then

( led 1 off, led 2 on ) then

( led 1 off, led 2 off ) then

( delay 5 second )

And so on.

2. Alan Burgess says:

Hi There all

I hope someone can help me here.

So a quick question, I have a built a small greenhouse controller, with relays controlling the Humidifier and Temperature, that’s all working great with some sketch I found online.

The question Im asking is when the humidity drops in the greenhouse the relay kicks in and starts a fine mist spray system, which is great but goes continuously until the humidity is back up above the trigger level, what I want is for the relay once its on to stay on for say one minute then off again for ten and repeat, until the humidity is up high again

Im assuming its a very simple line of code to do that, but at this early stage in my learning of the code, I have no idea how to do that.

So if anyone can tell me how, or point me in the right direction of how I can make the relay output stay on for a bit, go off and repeat, I would be very happy.

Cheers Alan

• The code on this example can do exactly that. The only caveat is when you setup the intervals. If you put something like “interval_OFF = 60000 * 10;” you’re going to run into a casting problem. So if you use inline math to calculate the interval, the compiler you intended to use an unsigned long, like this: “interval_OFF = 60000UL * 10UL;”

Lastly you might want to look at Delayed Events after a Button Press. Of course you aren’t using a button press in this case, but it shows how to “trigger” a timer.

3. David Nottelling says:

How would you/ or can you, go about using this to delay the on/off of a relay?
Would it be the same as the LED

Yes, it’s the same.

• Thank you, I can get your sketch working, and have played with it a bit within the scope of the LED’s. I wondered if you have another tutorial similar to this but dealing with temperature or other variable that is not directly controlled by the user… (more of an if/then). Such as temp or other such sensor controls the LED(s), but the LED(s) stay on/off for set time before resetting to the original if/then condition. I get how this works by looking at the previous state, but either overthinking or missed how this could be used in something like my example where on or off is set by an IF statement, but delayed where the rest of the code still runs.

I am doing a double traffic light project that also has a button, for pedestrian crossing, and a photo-sensor, for emergency vehicles. I’m trying not to use delay(); since if I press the button while the lights are on the program is on pause and won’t respond.

• Sorry, I don’t provide project level help. I would suggest posting your project on arduino.cc’s “Project Guidance” forum.

• ian stringer says:

Hi Abraham, did you get anywhere with this? I am working on something similar and would love to hear what you did.

5. Neil says:

Hi James.
I am new to arduino, and want to control 3 or 4 relays, triggering at different times, in sequence of each other. However the timing in between each step is not the same. I’ve writtin the code using “delay”, as it was the first example I got, and seemed easy. Now its restricting me to go further, and for example have an count down timer indicating time left untill all steps are completed. Please note the time I’ve put in is only for testing.The actual times are 1-8hours.

See below:

int right=8;//right relay//
int left=10;//left relay//
int down=13;//down relay//
int ButtonTwo=2;//trigger 2 day programme//
int ButtonFive=4;//trigger 5 day programme//
int ButtonSeven=7;//trigger 7 day programme//

void setup() { //Setup runs once//

pinMode(right, OUTPUT); //Set right as an output//
pinMode(left, OUTPUT); //Set left as an output//
pinMode(down, OUTPUT); //Set down as an output//
pinMode(ButtonTwo, INPUT_PULLUP); //Set twoDay as an input//
pinMode(ButtonFive, INPUT_PULLUP); //Set fiveDay as an input//
pinMode(ButtonSeven, INPUT_PULLUP); //SetsevenDay as an input

}

void loop() { //Loop runs forever//
{
delay(1000);            //for 3.5 seconds//
digitalWrite(right,HIGH); //Motor runs clockwise, Step 1//
delay(1000);            //for 3.5 seconds//
digitalWrite(right, LOW); //Motor stops//
delay(1000);              //Motor right wait for 2hours//
digitalWrite(left,HIGH); //Motor runs left//
delay(1000);            //for 1 second//
digitalWrite(left,LOW); //Motor left Stops//
delay(1000);            //Motor left stop for 1 second//
digitalWrite(left,HIGH); //Motor runs left//
delay(1000);            //for 1 second//
digitalWrite(left,LOW); //Motor left Stops//
delay(1000);            //Motor left stop for 1 Second//
digitalWrite(left,HIGH); //Motor runs left, Step 4//
delay(1000);            //for 1 second//
digitalWrite(left,LOW); //Motor left Stops//
delay(1000);
digitalWrite(right,HIGH); //Motor runs clockwise, //
digitalWrite(down,HIGH); //Motor runs down, //
delay(1000);            //for 3.5 seconds//
digitalWrite(right, LOW); //Motor stops//
digitalWrite(down, LOW); //Motor stops//
delay(1000);


And so it goes on to five and seven day as well.

• Stan says:

James, I was able to get your Arduino code to work. I do have a particular problem I’m trying to solve using the Arduino though. I’m using a 12v LED and having to power it with a separate power source using a transistor. What I need the LED to do is (1) when a switch is closed LED is off (2) When switch first opens the LED flashes briefly then turns off. I have a circuit that works, but to throw an additional issue into the mix, I can only run one wire to the LED due to physical limitations. The circuit I have connects the LED to +12vdc then to the drain of a transistor. I do have the ability to run a ground to the case from one side of the LED. Would you happen to have any suggestions.

6. guanxo says:

Hello,
How can I do a ON time of 1 hour? doent it work for longer time than 30 seconds?.

Thank you!

• You need to change the data type for “onTime” from int to long, so it can hold:

$1000ms\times60seconds\times60minutes=3,600,000$

const unsigned long onTime = 3600000UL;

7. This is great, Solved my problem of independent ON and OFF time. Thanks James

8. malik says:

I am trying to calculate the time after occurrence of two different events (cool and heat), totally independent from each other.  for starting cooling I have to wait for a specific time from last turn off, if time interval is reached and temperature condition also satisfied the cool function will start but heat should not start at same time. for heat also need to check the time from last turn off to now and by satisfying temperature condition  the heat function will start. I tried to use millis but millis is turning on both functions with a very slight time difference. How i can use millis to independently monitor time interval for two independent tasks.

9. wow, this great, thanks for sharing,…
how if I use 3 or more led with diffrent on time and off time?
 blinkLed(red, 50, 1000); //led color, on delay, off delay blinkLed(blue, 500, 50); //led color, on delay, off delay blinkLed(green, 1000, 2000); //led color, on delay, off delay 

10. Thanks for sharing. I was searching for last couple of days on how to solve independent on/off without using delay().