I'm trying to make an opening and closing little door that should open or close every 12 hours. I was wondering if I could just make a small looping script with a delay() for 12 hours, delay(43 200 000 000); I guess? However, I have no idea if that's possible and/or recommendable. Some feedback/alternatives(if needed) would be nice :)

  • ok, i think delay has a max of 65535 µs, but now i need an alternative... Aug 21, 2014 at 12:20
  • 4
    Timing in more mature, MCU-alone systems is usually done by programming a hardware timer channel of the MCU to fire an interrupt periodically, and then counting these - that lets the processor do other things in the meantime, and is cumulatively as accurate as the clock crystal. Aug 21, 2014 at 17:27
  • 3
    Using delay will magnify an ever so slight overhead error. It is better to use an interrupt to time a known good period and then count from there. Here is a proof of concept on my personal website: blog.linformatronics.nl/213/electronics/…
    – jippie
    Aug 21, 2014 at 18:20
  • 1
    If it doesn't have to be perfectly timed, you can use unconventional things, like a light sensor to sense morning and evening. Aug 21, 2014 at 20:05
  • yes, I thought about that, however I only have a little light detector part and I'm not sure how to protect it from the weather (the little door is outside) Aug 21, 2014 at 21:28

6 Answers 6


The real time clock method is the most accurate way but otherwise use millis

unsigned long startMillis = millis();
while (millis() - startMillis < LONG_DELAY_MS);

This will delay up to approx. 4294967295ms (2^32-1) or 49 days, after which the timer will catch up to the value of startMillis

  • 1
    What is wrong with just using delay(LONG_DELAY_MS)? The arduino implementation accepts unsigned longs. I'm also not entirely sure you code works correct when millis() wraps around, and is smaller than startMillis
    – Gerben
    Aug 21, 2014 at 15:34
  • Delay makes your arduino completely inactive while waiting if I'm correct. I don't know how this will act when millis is back to 0. Aug 21, 2014 at 15:38
  • @Gerben good stuff, put it as an answer! Aug 22, 2014 at 22:54
  • 2
    @FredPannekoek overflow will work fine, so long as unsigned long is used. Aug 22, 2014 at 22:54
  • 1
    @23ars The main reason Arduino is so successful is its easy-to-use hardware abstraction library, if you are against functions from libraries you are limiting yourself somewhat. Anyway, the function of comments is to improve the answer, if you have a better solution, write your own answer. ;) May 20, 2015 at 9:32

delay() has its uses, but for long delays it's no good. It simply tells the microcontroller to do nothing for x clock cycles. During that time, your Arduino can't do anything else.

Your best bet would be to use a thing called a Real Time Clock (RTC). These chips are specifically made to keep track of time, and you can connect them to your Arduino with ease. Here's an example of how you could do that.

  • +1 - The RTC solution is specially good if you want more accuracy than the MCU can give you.
    – Ricardo
    Aug 21, 2014 at 15:42
  • 1
    @Ricardo - an RTC is not likely to be any more accurate than an MCU with a clock crystal using one of its hardware timers to fire a periodic interrupt; what it does usually get you is tracking across power loss, and perhaps some knowledge of calendar schemes. Aug 21, 2014 at 17:26
  • 1
    Afaik uno does not use a quartz bit a ceramic resonator for its clock, thus with much less accuracy than an rtc.
    – jfpoilpret
    Aug 21, 2014 at 17:31
  • @ChrisStratton - Right. Point taken. The RTC will be much better option if the OP has to open or close the door at a given time of day.
    – Ricardo
    Aug 21, 2014 at 17:39

You could use the watchdog interrupt and have your MCU sleep while waiting and save power.

But notice that you'll only save power if your board also saves it. That means you have to have a low quiescent voltage regulator instead of the usual regulators that equip the most common Arduino boards, such as the Uno. Otherwise, it doesn't matter whether your MCU saves energy if your board doesn't.

Here's the code (untested):

#include <avr/sleep.h>
// This variable is made volatile because it is changed inside an interrupt function
volatile int sleep_count = 0; // Keep track of how many sleep cycles have been completed.
const int interval = 720; // Interval in minutes between waking and doing tasks.
const int sleep_total = (interval*60)/8; // Approximate number of sleep cycles 
// needed before the interval defined above elapses. Not that this does integer math.

void setup(void) {
    watchdogOn(); // Turn on the watch dog timer.
    // Disable the ADC by setting the ADEN bit (bit 7) to zero.
    ADCSRA = ADCSRA & B01111111;
    // Disable the analog comparator by setting the ACD bit (bit 7) to one.
    ACSR = B10000000;
    // Disable digital input buffers on all analog input pins by setting bits 0-5 to one.
    DIDR0 = DIDR0 | B00111111;

void loop(void) {
    goToSleep(); // ATmega328 goes to sleep for about 8 seconds
    // and continues to execute code when it wakes up
    if (sleep_count == sleep_total) {

void goToSleep() {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.
    sleep_enable(); // Enable sleep mode.
    sleep_mode(); // Enter sleep mode.
    // After waking from watchdog interrupt the code continues
    // to execute from this point.
    sleep_disable(); // Disable sleep mode after waking.

void watchdogOn() {
    // Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
    MCUSR = MCUSR & B11110111;
    // Set the WDCE bit (bit 4) and the WDE bit (bit 3) of WDTCSR. 
    WDTCSR = WDTCSR | B00011000; 
    // Set the watchdog timeout prescaler value to 1024 K 
    // which will yeild a time-out interval of about 8.0 s.
    WDTCSR = B00100001;
    // Enable the watchdog timer interupt.
    WDTCSR = WDTCSR | B01000000;
    MCUSR = MCUSR & B11110111;

    sleep_count ++; // keep track of how many sleep cycles have been completed.

The code I copied is from this page: Low-Power Arduino Using the Watchdog Timer.


Do you have a sleep(unsigned int seconds) available?

If not, this would allow you to delay() a very long time:

for (unsigned int bigloop=0; bigloop<65535; bigloop++)
   for (unsigned int smallloop=0; smallloop<65535; smallloop++)
      for (unsigned int tinyloop=0; tinyloop<65535; tinyloop++)
  • I could try this if I don't manage to get an rtc like Tom said. Thanks for helping! Aug 21, 2014 at 13:59

This will work:

longDelayInSeconds = 120; //two minutes;   
while (p < longDelayInSeconds) {


  • 4
    not the best solution and the OP asked for 12 hours, not 2 minutes.
    – Madivad
    Dec 8, 2015 at 4:05

I just use for loops when I don't want to do stuff in between:

for (int Hours = 0; Hours < 12; Hours++) {            //Creates 12 hours
  for (int Minutes = 0; Minutes < 60; Minutes++) {    //Creates 1 hour
    for (int Seconds = 0; Seconds < 60; Seconds++) {  //Creates 1 minute
      delay(1000);                                    //Creates 1 second
  • 4
    Explaing how this is better than a simple delay(43200000).
    – user31481
    Jan 23, 2018 at 9:49
  • 1
    Well for starter it would be easier to modify how long you want to wait. Just change the number for each hour, minutes and seconds without needing to convert into miliseconds.
    – GeneCode
    Jun 11, 2018 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.