I want to use my arduino to turn a light off for 16 hours and on for 8 hours. I know the general code, just using delays and the relay shield code as well. I want to know how accurate this will be? ( I tagged uno and leonardo, as I have access to both)

  • Arduino delay() is not really meant for timekeeping. In single uses at moderate duration it might in the best case approach the accuracy of the clock, but using it repetitively to add up to a longer period of time is a mistake as the start/end error and granularity will accumulate. Instead, you should use something that looks at the cumulative number of clock ticks that have elapsed over the entire interval of interest. Jun 28, 2016 at 3:50

7 Answers 7


I made a temperature and humidity sensor in August 2013. It uses a RTC chip (DS1307) which you can buy on eBay for $1 if not less. It has a battery backup (lithium cell).

I don't recall ever resetting the clock on it. It is now about 3 years later, and it is running about 11 minutes slow. This would be an acceptable error for something like turning garden lights on and off. Even for taking the temperature, a few minutes out when logging a reading is probably not going to matter.

Using the internal clock probably won't be as accurate, but could be OK in this case. I suggest you follow Chris Stratton's suggestion and code so that errors are not cumulative. For example, if you delay for an hour, and then do something, make sure that the "do something" isn't added to the next delay time.

If you want super accuracy (sounds like you don't) then connecting up a GPS module lets you query the exact time from the satellite, which could cut the error down to negligible amounts. Those GPS modules however aren't cheap.

Something to consider if you try to make do with the internal clock is: what happens if the power goes off? Then it loses track of when to turn the lights on and off. A clock chip however (usually) has a battery backup, and will "know the time" once the power comes back on.

  • 2
    If you go to eBay, to buy and RTC, just spend an extra buck and get a DS3231 instead of a DS1307. This one has a temperature compensated oscillator, resulting in even better accuracy. 2 minutes off per year, maximum. I have mine running for 2 year, and it is still correct to the minute (i.e. less than 60 seconds off).
    – Gerben
    Jun 28, 2016 at 9:30
  • 1
    Sounds like very good advice. :)
    – Nick Gammon
    Jun 30, 2016 at 9:23

There are multiple versions and "clones" of the Arduino, and each one will probably use different components. The time you refer, in this case "millis()" I believe, is maintained from a timer interrupt, which is derived from the main clock (normally 16Mhz).

The main clock on your board might be generated by a ceramic resonator, which is not very accurate: around 0.5%-1% error. It also might be from good quartz crystal, with up to 0.001% accuracy. Those variations on the frequency source will produce some drift over time... Like your watch needs to be readjusted from time to time.

Another factor that affects accuracy, including for RTCs using a 32.768KHz crystal, is the temperature. Here an Application Note on this: http://www.st.com/content/ccc/resource/technical/document/application_note/55/e2/3d/2a/87/ab/4d/e1/CD00232494.pdf/files/CD00232494.pdf/jcr:content/translations/en.CD00232494.pdf

Your application might not require too much precision, and you could simply write a sketch to print the time every second on the serial... let it run from one hour, one day, and check how much drift you're getting. After that will be easy to estimate how much drift you'll have a after a month.

  • 2
    you still have some losses for the little overhead of your software to increment millis()”. No, you don't. The hardware timer driving millis() does not stop counting while the software increments timer0_millis. Unless you do something very wrong, like blocking interrupts for more than 1 ms, you will not loose a single tick of the crystal/resonator. Jun 28, 2016 at 7:43
  • Yep, you're right, the little overhead to increment the millis won't be cumulative.
    – Talk2
    Jun 28, 2016 at 10:54

I think that RTC modules and real time clock chips have some sort of "mistake" said that, it CAN max. delay for fast forward for max. 6 seconds per month. Something as this, I've read year or so ago, when I was dealing with some sort of doors locking mechanism.

But for app. 8 hours, there's an arduino RTC module more than enough, I'd say. I assume, that seconds doesn't matter.


Just because it's always an option... I'm usually connecting my Arduinos to the Internet one way or another, so I just get the time from NTP servers once every day or so using UDP to keep the clock accurate, or accurate enough.

The advantage is that, even if power is lost, it's relatively easy to ask Arduino to get the time while booting up. Then it always knows, and is always on time.

Happy to share fave code, but I found mine in UDP library examples and have adapted it to my own needs.


By definition, the Arduino is as accurate as it's crystal clock/resonator.

This clock runs at approximately 16mhz for an Uno.

The Arduino's internal time is just a count of how many times this crystal has vibrated.

READ THIS! - these next two paragraph are apparently incorrect. See Nick Gammon's comment below.

The crystal in question is approximately like this one: https://www.sparkfun.com/products/536 - this one from SparkFun is accurate to 50 ppm - that's parts per million. So, if your Arduino has that EXACT crystal, it may lose or gain 50 parts per million - in a million seconds, it would count somewhere between 999,950 and 1,000,050 seconds. This would mean you gain/lose less than 4.3 seconds per day, or 2 minutes per month. If you find the crystal on your board, google the code (probably something like 16.000N, for the Sparkfun one), which should tell you exactly what the accuracy is for that chip. Note that, if you can find the datasheet, it should tell you the accuracy, at particular temperatures - as the temperature goes up and down, the error will change too.

Remember also that an Arduino's clock is in volatile memory - that is, if you power down the Arduino, and power it back up, it has no idea what time it is - you would need to set the clock again, either by connecting it to a PC, network, or via buttons/display on your project.

There are a number of alternatives, depending on your need, to work around this: you can get the data from LAN or WIFI, if your project has that, or you can use a RTC module - you need to set this to the correct time once, then it will remember after that.

Alternatively, you can use a light-dependent resistor (aka photoresistor), and trigger automatically when it gets dark. This may trigger when it gets dark for some other reason, e.g. a storm, which may or may not be an advantage.

  • 3
    The Uno has a resonator connected to the Atmega328P, not a crystal. The crystal you see on the board is connected to the Atmega16U2 (the USB interface) because that needs more accurate timing. A resonator is not as accurate as a crystal, generally speaking.
    – Nick Gammon
    Jun 28, 2016 at 4:38
  • H'm, if there is an accurate crystal for the USB, would it not have made design sense to push the output of that to the AtMega328P? I know the AtMega328P has a clock-out, I assume the 16U2 has a clock out too? The AtMega328P definitely has a clock in.... Jun 28, 2016 at 21:29
  • Interesting question. They could have saved a cent or two by doing that. There must be some reason, if only the desire to keep high frequency signals from going from one side of the board to the other.
    – Nick Gammon
    Jun 30, 2016 at 9:22
  • Would that be an issue? The signal delay would not - the two chips aren't synchronized, and nothing assumes that they are (obviously, otherwise separate clocks wouldn't work). The clock-out is generated by the first chip, so I would expect it to be a strong clear signal - surely 16mhz over a few cm wouldn't be an issue? It would also save a pin (as the crystal requires two pins). Jul 12, 2016 at 21:34
  • True. And the two chips are quite close together too. I don't know why. Maybe by the time it occurred to them it was too late because of the way the other traces on the board ran.
    – Nick Gammon
    Jul 13, 2016 at 20:47

Not very.

For that kind of period of timing you are far better off using a Real Time Clock (RTC) module.

  • How long off will I end up being? It doesn't need to be super accurate
    – Peter
    Jun 27, 2016 at 23:30
  • 1
    The longer it is running for the longer it will drift. The oscillator (ceramic) on the Arduino Uno is very poor. It's better on the Leonardo since it has to drive USB, but the whole delay() / millis() thing is inaccurate at best.
    – Majenko
    Jun 27, 2016 at 23:31
  • Alright, I may just use a phone and another shield to interface with it and get the time. Thank you very much :)
    – Peter
    Jun 27, 2016 at 23:32
  • That sounds massively more complex and expensive than using an RTC...
    – Majenko
    Jun 27, 2016 at 23:39
  • You may think, but I have all the materials and an old ipod that just begs to be used for this :)
    – Peter
    Jun 27, 2016 at 23:42

I want to know how accurate this will be?

accuracy is a function of coding and hardware. with good coding, you can make it as accurate as your hardware is capable of.

I experimented with a tco-919 high accuracy oscillator (19.2Mhz), in an unairconditioned environment, no meaningful timing drift after a month.

So if you really want accuracy, go with a good oscillator.

if you just care about reasonable accuracy (1%?), the internal oscillator will do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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