1 sec to wake up from powerDown(LowPower) Pro Mini

In my project i want to powerDown (deep sleep)
the arduino pro mini for 2 hours using LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF).
Meaning that waking up every 2 hours ,
taking some sensors measurements and back to sleep.

I dont care to loose some seconds so i decided to NOT use some RTC
and just powerDown for an estimated time.

2 Hour have 2 * 1000 * 60 * 60 milliseconds =7.200.000 millis

So if we have an arduino that wants about 8500 millis to
a)powerDown(SLEEP_8S, ADC_OFF, BOD_OFF)
b)wake up
c)increase the counter of while..and test the while condition

then we need a while to count
(and power down for 8 seconds using powerDown(SLEEP_8S,,,, ))

for 7.200.000 / 8500 = 847 times.
And remaining some millis that we can make a simple delay.

For this purpose i created the following program
in order to give me the TIMESTAMBED output in Arduino IDE
so that i can statistiacally compute how much time
the LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF)
will take.
EstimLowPower8Seconds_1.png

#include <LowPower.h>///LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

void setup() {
  pinMode(13,OUTPUT);
  Serial.begin(9600);
  delay(100);
  Serial.println("starting");
  delay(100);
  showForEstimated();
}

void showForEstimated() {

  int i = 0;
  while (i < 101) {
    Serial.println('O');Serial.flush();
    //digitalWrite(13,HIGH);delay(23);digitalWrite(13,LOW);
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    ++i;
  }
  Serial.println('K');
}

void loop() {
}

After waiting some time to fill the output i am using onother simple java program
(or can do it manually)
to find exactly the statistics .


Now the problem is that
one of my pro mini has an estimated cycle
of 8 seconds power down = 8793 milliseconds (and lets say that this is good)

8793.064 = millis AVERAGE of 8 seconds power down 
31 Samples
Sum : 272585.0
min-max : [ 8759 , 8833 ] 
Mostly appeared 8778 for  2 times ..

but ONOTHER of pro mini (3.3 version)
has 9033 millis estimated cycle. (too large)

9033.0 = millis AVERAGE of 8 seconds power down 
8 Samples
Sum : 72264.0
min-max : [ 9016 , 9053 ] 
Mostly appeared 9033 for  3 times

So the question is.

Does any body knows

a)Why the second pro mini needs so much time (9 seconds) ??
...for a powerDown 8 seconds cycle???

b)Why my times are so big?
I was expecting to not be more than 8200 milliseconds
as per the gammon help project for lowpower
(gammon.com.au/power)
"If you are trying to save power, taking 65 mS to wake up, add 1 to a counter, and go back to sleep, is a lot. "

EstimLowPower8Seconds_1.png

The watchdog timer is not particularly accurate. It wasn't really designed for use a clock over an extended time period in scenarios such as this.

You might find this post of interest. I left a 328p running for 24hr, waking up roughly every hour to see what sort of difference there would be between actual time and watchdog generated time.

It worked out that there was around 40 seconds difference between a watchdog hour and a real hour. The value also varies between 328p devices as well as ambient temperature.

Thank you,
I updated your post with my code proposal.

My question is not WHY the times are not same every time.

But why i have so big times
(~8 seconds for power down is ok....and i am trying to adjust this by estiomation)
AFTER power down ...for the wake up time....that currently is

700 milliseconds.

Seconded on the accuracy of the watchdog timer, your are assuming it is 8 seconds, but it varies quite a bit.

My own sensor, based on a Pro Mini uses the watchdog timer to wake up every 15mins (approx), transmit a sensor reading via LoRa and go back to sleep.

A year ago I set it running with a tiny 150mA LiPo battery running it. Judging by the battery reading from yesterday, the battery now is about 55% discharged.

I am not assuming.
"your are assuming it is 8 seconds"

I am computing the estimated for 8 seconds and use this as follow.

It is working fine by my problem is why i need so much time (>700 milliseconds)
to wake up after every power down for 8 seconds

unsigned long awakeEvery = 7200000ul;//2 hours
unsigned long awakeForMin = 60000;//1 minute
unsigned long awakeForMax = 120000;//2 minute

unsigned long mustDelayOrSleep;//this is only for debug
unsigned long timesPowerDown8Seconds;//this is only for debug
unsigned long millisRemainForNormalDelay;//this is only for debug
const unsigned long estimated8SecMillis = 8792;


#ifdef USE_LOW_POWER
#include <LowPower.h>
#endif
void myDelay(unsigned long someTime) {//finally this function release from RTC need...good enough

#ifdef USE_LOW_POWER
  //Serial.println("Power down");
  timesPowerDown8Seconds = someTime / estimated8SecMillis;
  millisRemainForNormalDelay = someTime % estimated8SecMillis;
  unsigned long times = timesPowerDown8Seconds; //hold this to be able to show it after for debug
  //WARNING .This delay must be before while because???
  //is not working fine if after
  delay(millisRemainForNormalDelay);
  while (times > 0) {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    --times;
  }
  //delay(millisRemainForNormalDelay);//not working here
#endif

#ifndef USE_LOW_POWER
  //Serial.println("delay() down");
  delay(someTime);
#endif

}

//this function computes the ammount of time that actual we must sleep
//the work() time is excluded (in each implementetion of it)
//so lets say if must sensoring every 1 hour=60 minutes
//and work/sensor time may take 1-2 minutes
//we want to sleep 58-59 minutes..(to come exactly every...)
void workingStep() {
  unsigned long startMillis = millis();//reference to when on this line
  work();
  mustDelayOrSleep = awakeEvery ;
  mustDelayOrSleep += startMillis;
  mustDelayOrSleep -= millis();
//just to call millis as last command to be more accurate
//Above is equivalent to
//mustDelayOrSleep=awakeEvery -(millis()-startMIllis)

  myDelay(mustDelayOrSleep);
}




void setup() {
  Serial.begin(9600);

}

void loop() {
  workingStep();
}

Its not clear how you appear to be assuming the wakeup takes 700mS ?

I am using Arduino IDE output with TIMESTAMBS
like below.

EstimLowPower8Seconds_1.png
After that, i manually or with some other program
..computing average...

Manual example.

39:103 - 30:344 = 8 seconds and 759 millis
30:344 - 21:543 = 8 seconds and 801 millis
etc
So ... lets assume that the power down function ONLY,,
,,is taking from 7.500 up to 8.500 seconds

And if this is true then my waking UP time is at minimum 259 milliseconds.

Lets say that is ok ...even if in gammon page i ve read for max 100 millis (wake up ).

But my other pro mini needs almost 500 milliseconds for wake up.(~9000 millis per cycle)

This is my problem.
Why so much time??

The only way you can really time how long the processor takes to wake up is to monitor the current it uses with a scope, put a resistor in line with VCC.

Then you can monitor the start of power on with the program turning a logic pin on when first awake and off when it goes to sleep. I dont recall how long this wake up period (the current consuming period) was when I measured it, but it was only a few ms.

To get some estimate of the duration of the sleep/wakeup cycles, you'll have to use an oscilloscope and watch the power consumption. Ultimately, unless it is an academic exercise, it is power consumption that is the issue here.

You can look at turning off the Brown out detection by a fuse setting, instead of doing it in each sleep/wake up cycle. You can also turn the ADC off in setup and, assuming you are not using, simply don't switch it on again. There are other fuse settings which may be relevant (crystal stabilisation time etc.)

edit

crossed with @srnet

Not sure about the Pro Mini, but I have a barebone 328P which uses a 32KHz crystal in combination with Timer2 for waking up and that gives me 10 minutes sleep cycles which are only off by +/- ~6ms.

I started with the WatchDog but it was impossible to get stable results because even one degree change in temperature was enough to cause a difference of up to 25 seconds for each 10 minutes sleep cycle. The WDT is absolute and completely useless for accurate timing.

If you look at the real world test mentioned in #3, then the average current consumption of the node is 10uA, measured over a year.

With the watchdog timer itself using around 6uA, that means 4uA average to wake up once every 8seconds, increment a counter and go back to sleep. And within that 4uA, is also the power used every 15mins to read a sensor and transmit it with LoRa.

I would suggest the actual time of the wakeup is of little consequence.

But my other pro mini needs almost 500 milliseconds for wake up.(~9000 millis per cycle)

The difference does seem odd. Are these identical (ambient temperature / voltage / crystal / resonator etc.) and with the same fuse settings ?
The data sheet ( ch 31.1.11) for the Atmega328p shows graphs of temperature and voltage affecting the watchdog oscillator. The ranges are between about 104kHz to 116kHz.

" even one degree change in temperature was enough to cause a difference of up to 25 seconds for each 10 minutes sleep cycle"
Ok...i am very beginner and i have missed this.
Now that i know i will take it intoo account.


The other pro mini is 8Mhz (3.3) instead of 16Mhz(5.0) that is the firts.
And maybe ,forgive my ignorance, maybe those +300 millis
is just the doubled time just to print the 'O'

I will try to not print and just use an RTC (storing its time) after each powerDown(8 seconds)
and i will come back with results...as soon as i can.

This is from an Arduino Uno R3
8302 millis for a cycle
instead of 8792 from a Pro mini 16M(5.0 volt)
instead of 9000 from a Pro mini 8M(3.3 volt)

8300 is more reasonable and also closer to gammon value.

8302.516 = millis AVERAGE of 8 seconds power down 

33 Samples
Sum : 273983.0
min-max : [ 8272 , 8326 ] 

Mostly appeared 8315 for  3 times 

8272 * 1 ... ( -43 )
8278 * 1 ... ( -37 )
8280 * 1 ... ( -35 )
8281 * 1 ... ( -34 )
8282 * 1 ... ( -33 )
8285 * 2 ... ( -30 )
8286 * 1 ... ( -29 )
8287 * 1 ... ( -28 )
8290 * 1 ... ( -25 )
8291 * 2 ... ( -24 )
8293 * 2 ... ( -22 )
8296 * 1 ... ( -19 )
8303 * 1 ... ( -12 )
8307 * 1 ... ( -8 )
8308 * 1 ... ( -7 )
8309 * 1 ... ( -6 )
8313 * 1 ... ( -2 )
8315 * 3 ... ( 0 )
8316 * 2 ... ( 1 )
8318 * 1 ... ( 3 )
8319 * 1 ... ( 4 )
8320 * 2 ... ( 5 )
8323 * 1 ... ( 8 )
8324 * 1 ... ( 9 )
8326 * 2 ... ( 11 )

From a simple while that we print millis()
I assume that
the reason for so much big differences (8300 vs 8700 vs 9000)
IS NOT
from the Serial.println(something)

As you can see from below...the Serial.println
taking only a few millisecond to execute
(not more 10 millisecond)

so i believe my question is still valid.

  int i = 0;
  while (i < 101) {
    //Serial.println('O');Serial.flush();
    Serial.println(millis());Serial.flush();
    Serial.println(millis());Serial.flush();
    Serial.println(millis());Serial.flush();
    Serial.println();Serial.flush();
    //digitalWrite(13,HIGH);delay(23);digitalWrite(13,LOW);
    //LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    delay(8000);
    ++i;
  }

OUTPUT:
09:09:58.966 -> 198
09:09:58.966 -> 204
09:09:58.966 -> 210
09:09:58.966 -> 
09:10:07.001 -> 8218
09:10:07.035 -> 8224
09:10:07.035 -> 8230
09:10:07.035 -> 
09:10:15.038 -> 16238
09:10:15.071 -> 16246
09:10:15.071 -> 16254

What are you trying to proof with you last post? It seems like you do not take into account that there are interrupts which may interfere with your timing. When you do a "Serial.print()", the data is stored in a buffer and that buffer is then transmittet "in the background". Since there is only one core on the arduino, instructions/code executed in interrupts will be "mixed" with the primary instructions in "loop()".

If you want measure the accuracy of the clock you must disable interrupts while doing so. Disabling interrupts will cause "micros()", "millis()" and "delay()" not to work properly because they rely on a timer interrupt to work, so you will have to find a workaround for that.

Here is the current spike (top trace) of a ATmega328P waking up from an 8 second watchdog sleep.

As soon as the processor wakes the program puts a logic pin high, you can see that the spike in current at wakeup and the logic pin change are very close in time.

Bottom trace is a zoom in of the current spike, you can see from the start of the current spike (the processor starts to power up) to the logic pin change is around 1mS. A pretty fast wakeup I think.

NewFile6.jpg

NewFile7.jpg

NewFile6.jpg

NewFile7.jpg

" It seems like you do not take into account"

Ok... you (all) are right ...

I just now understood that finally ,the 'problem' must be on the Serial.println

because in a real and with batteries experiment
i had put as an estimated 8 seconds millis the value =8792.
And i had a drift -4 minutes on every 2 hours (sensoring and sending data)

And this morning i changed to 8500
and now is better ..meaning that drifting is less that +1 minute

So i will experiment a little more and i will come back.

LessThanMinuteAt8500.png

LessThanMinuteAt8500.png