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.

millis-cookbook-two-duty-cycles

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.

Leave a comment

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

  1. Hello
    i have a question
    if i want to print on/off time on LCD for each case separately, should i use this lcd.print( millis() / 1000); or what do you think?

  2. Hi James, I have an electric trainset, with points and signals. To control the points or signals (which are controlled by magnetics witches) I have to send a short pulse (1 or 2 seconds) to the switch by means of a relay). I need two relays for each poin or signal. I have four relays at this stage to control one point and one signal. I would like to control the relays at independant and differen times, over a span from one to two hours. For example point after 5min., than 30 min. than,80 min(of course in milli seconds), and the same for the signal. All tutorials show blinking lights, etc , but nothing like this. I tried normal arduino, but the delays are stuffing me up. Could you give me a code in Millis for this please. Regards, Martinus van Walsum

    • Sorry, I can’t provide detailed code like that. A good starting point would be to make a chart of the various “states” you want each of your relays to be in and their dependencies. It is the start of a state machine. For detailed help, I would suggest something like the Project Guidance forum on arudino.cc’s forums. There others can help you form the code you need.

  3. Hi.
    I want to do this:
    light turn on and off at certain times with a nano arduino
    my idea is that when turning on the arduino, take the time is eg. 00:00 a.m. (then connect it right then, at that time), and program it to turn on or off the light at certain times (14pm to 22pm (on) and the rest light off)
    If for some reason it were to cut off the power supply, to set it to the time it would only have to turn it on at 00:00 am.

    it is possible? can you give me a hand??

  4. Hello sir
    Your code is working well.
    I am very thankful to you.
    I need your help in a case
    I am running this code in a condition in which when distance = 30 cm this statement gets on
    I want led ” on” state every time the condition fulfill.
    Rather than in a cycle in which some time it is on when “if ” statement fulfill or off th other time .
    Thanks in advance

  5. Hi James,
    Thanks for all your great informative tutorials! Your millis examples have helped this novice out so much.
    I’ve taken this code and successfully controlled a water pump via a relay (I needed the separate on/off times), but I am having issues with coding to allow an analog value from a water level sensor (funduino) to stop the water pump from being on. The analog values also have IF statements that light up LEDs to indicate water level.

    I had previously thought I could set a boolean flag and add ” && waterLOW ==false” to the IF ‘millis timer’ statement. But due to the toggling variable, this meant that if the flag became true during the onTime of the pump that it wouldn’t reenter that IF statement and got stuck in the last state.

    I then tried to make IF and ELSE IF statements using the variable toggle like so:

    if (waterLOW == false) { 
       pumpSTATE = !(pumpSTATE);
    } else if (waterLOW == true) {
      pumpSTATE = false; 
    }
    

    But this didn’t seem to work either. Though I suspect something like this could work and it’s just my lack of grammar and knowledge of how to nest IF, ELSE and ELSE IF statements.

    Am I on track thinking that I should use a boolean flag here and use IF and ELSE statements to direct the state changes? or are there any hints you can provide me with that will reorient me? I have previously read about state machines, but am I righting thinking I don’t need to go there yet?

    Many thanks for all the help so far and for any if given here,
    DanielKhan

    • I don’t understand your requirements well enough to advise. It sounds like you have a strange set of conditions that can’t easily be defined with a flag. I’m almost positive you don’t want a situation where you are just toggling the state of pumpSTATE. Every single time that if-statement runs it is going to flip, which is probably bad thing. Instead of a simple toggle, you probably need a more robust set of logic to determine if the pumpSTATE should be changed.

  6. Hello
    I am french, could you help me please
    I would like to replace a relay, by a pwm led that turns on gradually, in my program I use a rtc DS1307 with arduino.
    when I use “for” it blocks me the time, I hope to use “up” and “down”
    but I can not .

  7. Hi James; I tried your code, “Independent On and Off Times with Millis()”. Works great, I would like to add a simple counter to flash 10 times let’s say and stop until triggered to run again. Not being a code writer, I would appreciate your expert suggestions.
    Thanks for the method to get away from “delay().

    • I would add a counter variable and set it to 10 when you want the flashing to start.

      if (whatever happens)
         counter = 10;
      
      if (counter > 0) {
        if (currentMillils - previousMillis > interval) {
          // flashing code
      
          counter--;
          previousMillis = currentMillis;
        }
      }
      

      Something like that.

  8. Hi James , can you help me?!(sorry for my bad english)

    I have a arduino uno with lm35 sensor temperature and 4 relays(1 module) , i trying to change your code to turn on 1 relay every 2 hour.
    By first , I change offTime to unsigned long, and put 7200000UL , but , dont work .
    I try a test , with 10 seconds , 30 seconds and 60 seconds , every tests sucessful.

    Can you help me?!

  9. Hi James, congrats for your helpful website.
    i am looking for a little help to figure out how to blink 3 leds.
    In my real application those represents relays that will power on 3 electrovalves for a irrigation demostration of 3 independent sectors. The common solution with delays is to:
    Sector1: Led1 ON, ontime1(ie:120 seconds), then OFF, then
    Sector2 Led2 ON, ontime2(ie:240 seconds), then OFF, then
    Sector2 Led3 ON, ontime3(ie:120 seconds), then OFF, then back to Sector1.

    My problem is that in real life the next Led to be ON must not to start before the previous led go to OFF. This is for water pressure compensation and avoid a water hammer. So that time before to next led will be ON i will define it in my code as “OffsetTime” and for this example will be 10 seconds. So the led2 will be ON when the time elapse “ontime1” is 110 seconds and led3 will be ON when “ontime2” is 230 seconds. (ontime2-OffsetTime).

    Can you help with a tips to figure out the code?

    Thank you in advance!!

  10. Hello. Thank you for the tutorial of millis() code in Arduino. I have a question for blinking the LED with the opposite on and off statement. I mean, the codes are like this:

    digitalWrite(13,HIGH);
    delay(10);
    digitalWrite(13,LOW);
    delay(10);

    digitalWrite(12,LOW);
    delay(10);
    digitalWrite(12,HIGH);
    delay(10);

    If I’m using code millis() for the opposite blinking, what have I to add/change from those code I wrote before?

    Thank you very much