Go Down

Topic: timer errors due to narcoleptic power save (Read 2834 times) previous topic - next topic


Hi Everyone,

I'm quite new and I'm having difficulty with using a timer with a power saving mode.

My project is to run an LED at the same time each day for 6 hours and I'd like to have the arduino board use as little power as possible.
I'm using the Arduino Pro Mini 5V 16 MHz.
The narcoleptic function seemed like the best option but it seems to progress faster than it should. Over 24 hours it seems to advance by an hour so my LED comes on 1 hour earlier every day. I've tried it over various different time lengths and found that this 1 part in 24 advancement seems quite consistent. Is there a reason for this?

Code: [Select]
#include <Narcoleptic.h>
int x=0;
/* Program to switch on an LED for 6 hours a day and then off for 18 hours
   including narcoleptic delay in order to conserve power*/

void setup() {               
  pinMode(12, OUTPUT);

void loop() {
  digitalWrite(12, LOW);   // set the LED off
  for ( x=0; x <=2700;x++)  //6 hours= 8sec*2700
     digitalWrite(12, HIGH);  // set the LED on
      Narcoleptic.delay(8000);//8000 milliseconds delay
   digitalWrite(12, LOW);    // set the LED off

   for (int x=0; x <8100;x++)//18 hours= 8sec*8100
     Narcoleptic.delay(8000);   //8000 milliseconds delay
   digitalWrite(12, LOW);    // set the LED off

I've read about how narcoleptic disables the millis() function and affects timing, is there a way to avoid this?

The way I see it is I have a few options,
~Rely that the timing error is consistent and adjust my maths so I don't end up 1 hour ahead each day (ie make each day 25.04 hours)
~Find a way to fix the timing used by narcoleptic
~Use another power saving setting that allows for reliable timing
~Use an external clock to keep time

As I am trying to conserve power, and narcoleptic is quite good at this, I hope there is a way I can use one of the first 2 options.


You're relying on the watchdog timer to match real time. Unfortunately the watchdog timer is only approximate so it's not too surprising that your program is drifting. If you want to stay synchronised with real time, you'll need to use a real-time clock.


Hi PeterH,

Thanks for your reply.
I've read about the watchdog timer only being approximate so that does explain why the timing has been off. But the timing seems to be off by a consistent amount (1 hour in 24) which I wouldn't have expected. As I've said, I'm very new to this, but if the watchdog timer is just plain inaccurate wouldn't its error vary?
The consistency of the error makes me think that it is due to something other than inaccuracy and if that was the case then it could be calibrated.

I appreciate that a real time clock would work but I would prefer to try to use one of the timers on the board either in narcoleptic mode or some other power save mode. It might mean a bit more work but I think it'd be the best option for me.


I don't know how consistent the watchdog would be on a given board - and whether that's likely to change with temperature, humidity, supply voltage, phase of the moon, or whatever.

I can't see anything you're doing that would introduce a systematic time drift; I'm pretty sure it's simply that the watchdog sleep is not taking exactly as long as you're asking for. If you believe the discrepancy is consistent (for your specific board, in the environment you're using it today) you could compensate for it in your code.


I do see what you mean, it seems consistent but there's nothing to base that on and if some factor affects it then that consistency could disappear in a poof of smoke.
I was hoping that there was a solid reason for the consistency and that I was just overlooking it.

I know that other power save modes exist, are there ones that don't affect timing?


Keep in mind that the oscillator will also affect that.  No two oscillators are exactly the same, and the environment also affects them.  So if you are consistency seeing a one hour drift, every day, that's likely the culprit which also causes the watchdog timer to be off.  There is nothing you can do other than to include an RTC in your wiring and use it to determine the time.  On the plus side, the RTC will also help with daylight savings (or wastings) changes.

If you have a second Arduino handy, try running it on there and you ought to see a difference.


There is a lot about power saving in the ATmega doc pdf at ATMEL.

The Arduino software millis() stops counting during interrupt routines too. How often you might be running an ISR even if it's very short might count.

Power saving --- why are you running 16 MHz? Do you need that speed at any time in your app? ATmegas can run ridiculously slow (how about 128 KHz power saving mode?) and only need low voltage.

What Ralph says, yes get yourself an RTC. They probably don't eat much.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts


Thanks for your replies guys,

I took your advice and looked at how a second board responds, and it's quite similar. I'm using an online stopwatch and there's also some human error from me so that adds inaccuracy.
I'll try putting it in the freezer!
Also, if I'm connecting batteries to the RAW pin, which i believe regulates to 5V, does that mean that there's no change of supply voltage? I'm just trying to rule things out.

I started reading the ATmega doc and found it very hard going, I found myself looking up acronyms and words every 30 seconds. I suppose that means I'm learning!
I think the narcoleptic code disables millis() but the interrupts might stop the watchdog counting too I suppose.
Does the 8 second narcoleptic loop automatically end with an ISR? Could that cause the issue?
If I could save power by slowing it down that'd help a lot. It only needs to turn on and off the LED so there's no need for speed at all.
But would the 128 kHz power saving mode affect the timing do you think?

As much as I resist it, the RTC does seem like the easiest option. I'd be repeating this project a lot though so it seems like adding an external timer to an arduino that already has a few timers is a bit of a waste.


The ATmegas have an internal 8 Mz oscillator that you're -supposed- to be able to calibrate but only to within +/- 1%. 3600 seconds an hour, within +/- 1% can be 3.6 seconds drift per hour, 86.4 seconds per day. 
ATmegas have an oscillator divider that can be 1, 2, 4, 8, 16, 32, 64 128 or 256. The chips ship with the 8 MHz internal clock set on and the divider set at 8, thus as shipped they default to 1 MHz CPU clock.

Ask yourself how close do you need?

An RTC would not be affected by the chip running slow.
Reading the doc has a steep learning curve but the more times I use it to put myself to sleep, the less tired I get and the more I notice and wonder about.

When you say "repeating this project" does that mean building more of the same?

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up