Accuracy of sleep period for Gen3 devices

Calling System.sleep({},{}, sleepPeriod); i.e. stop sleep on a Xenon where sleepPeriod is 50 say will produce an actual stop of anything between 20 and 50 seconds! Is there anyway that this variability can be reduced? I understand about the Gen3 devices not having an RTC but surely the sleep period for such a short time can be made to be reasonably accurate without needing to use an external RTC alarm/interrupt?

1 Like

Physically they have an RTC (according to the schematics and the nRF52840-datasheet) :face_with_monocle:.
The largest variability I observed is the fact the the user firmware is stopped until the device has reestablished the connection to the cloud. I didn’t measure it but my test-xenon some time ago seemed to sleep roughly the amount of time I wanted it to. The largest drifts over time were in fact the different amounts of time it took to reconnect before continuing my app.

The problem with acronyms is that they may look the same but mean something different :wink:
Unlike Gen2 RTC on these devices does not stand for Real Time Clock but Real Time Counter and these are not very accurate with regards to world time across different modes of operataion.

1 Like

I understand about the Gen3 devices not having an RTC

I did mean Real Time Clock for RTC in both cases.

I accepted the use of an external Real Time Clock IC because I need accurate wake up at a specific HH:MM:SS and the DS3231 is just brilliant for that with 2 alarms.

My point was that the Real Time Counter use should be fairly accurate (1s in 60 seconds) but that isn’t what I am seeing when in stop sleep. I may as well stick in random() for the seconds!

[Edit] I can be very certain about the actual sleep time because the time stamps used are taken from the Real Time Clock time and that is accurate to +/- 1 second a day.

I was actually refering to @glx’s comment :wink:

Understood - I wanted to remove all doubt. Hoping for a Particle reply!

I have a Xenon that sleeps for 1 hour with System.sleep({},{}, sleepPeriod).
It wakes exactly 1 hour plus the previous run-time (which ranges from 4 to 9 seconds).
The accuracy seems to be within ~1 second…looking back at recent logs.
I’m using Automatic Mode and Threading, if that matters.

The accuracy may be impacted by those settings - I would be very happy with such accuracy. 1 second in 1 hour is near to some Real Time Clock accuracies. I previously have seen a note from Rick along the lines that the counter used in Xenon’s is really not accurate and certainly not for an hour. I need to do a bit more digging into the schematic because it could be something else is waking it - there are interrupts from the IR sensor and the RTC - I need to make sure they have correct pull-ups.

Hmmm… you’ve peaked my interest. I’ll dump the logs to a spreadsheet to quantify the 1 hour accuracy and stop assuming based on the line graph timestamps.

Here’s a snapshot :
image

This Xenon Wakes every hour and performs a Particle.publish through an Argon, with a webhook to ThingSpeak.
The Timestamps are when ThingSpeak receives the data.
So the ~1 second error might not even be the Xenon’s fault.

The “Calculated Wake Time” column is the Previous Timestamp + the runtime in seconds.
Delta is the difference between the actual Timestamp verses Calculated.

Note: this particular Xenon is testing a Solar + SuperCAP + PIR solution, so I’m feeding the 3v3 pin directly with the EN pin grounded.

Is there any chance that using the 3V3 pin to supply power (and disabled on-board regulator) is helping the Sleep Time accuracy ?

Hm now I was kind of curious. I just wrote a quick test-program for my xenon:

SYSTEM_MODE(MANUAL);

void setup() {
    Serial.begin();
    while(!Serial.isConnected()) {
        delay(100);
    }
    Serial.println("Hello. This is a short sleep test.");
}

void loop() {
    Serial.println("s"); //sleep
    System.sleep({}, {}, 60); //send to sleep
    /*
    it took a short time to reattach the serialport on the pc side, 
    because of that I had to include the delays.
    */
    delay(2000);
    Serial.println("w"); //wakeup (2 sec ago)
    delay(3000);
}

And logged the output:

Log Timestamp difference between sleeps difference to 00:01:05
[2019-11-12 19:27:16,317] Hello. This is a short sleep test. 19:27:16,317
[2019-11-12 19:27:16,317] s 19:27:16,317 00:00:00,000
[2019-11-12 19:28:18,442] w 19:28:18,442
[2019-11-12 19:28:21,442] s 19:28:21,442 00:01:05,125 00:00:00,125
[2019-11-12 19:29:23,570] w 19:29:23,570
[2019-11-12 19:29:26,569] s 19:29:26,569 00:01:05,127 00:00:00,127
[2019-11-12 19:30:28,696] w 19:30:28,696
[2019-11-12 19:30:31,696] s 19:30:31,696 00:01:05,127 00:00:00,127
[2019-11-12 19:31:33,823] w 19:31:33,823
[2019-11-12 19:31:36,823] s 19:31:36,823 00:01:05,127 00:00:00,127
[2019-11-12 19:32:38,949] w 19:32:38,949
[2019-11-12 19:32:41,951] s 19:32:41,951 00:01:05,128 00:00:00,128
[2019-11-12 19:33:44,079] w 19:33:44,079
[2019-11-12 19:33:47,078] s 19:33:47,078 00:01:05,127 00:00:00,127
[2019-11-12 19:34:49,205] w 19:34:49,205
[2019-11-12 19:34:52,206] s 19:34:52,206 00:01:05,128 00:00:00,128
[2019-11-12 19:35:54,339] w 19:35:54,339
[2019-11-12 19:35:57,333] s 19:35:57,333 00:01:05,127 00:00:00,127
[2019-11-12 19:36:59,604] w 19:36:59,604
[2019-11-12 19:37:02,461] s 19:37:02,461 00:01:05,128 00:00:00,128
[2019-11-12 19:38:04,591] w 19:38:04,591
[2019-11-12 19:38:07,585] s 19:38:07,585 00:01:05,124 00:00:00,124
[2019-11-12 19:39:09,713] w 19:39:09,713
[2019-11-12 19:39:12,713] s 19:39:12,713 00:01:05,128 00:00:00,128
[2019-11-12 19:40:14,842] w 19:40:14,842
[2019-11-12 19:40:17,838] s 19:40:17,838 00:01:05,125 00:00:00,125
[2019-11-12 19:41:19,967] w 19:41:19,967
[2019-11-12 19:41:22,966] s 19:41:22,966 00:01:05,128 00:00:00,128
[2019-11-12 19:42:25,093] w 19:42:25,093
[2019-11-12 19:42:28,092] s 19:42:28,092 00:01:05,126 00:00:00,126
[2019-11-12 19:43:30,220] w 19:43:30,220
[2019-11-12 19:43:33,219] s 19:43:33,219 00:01:05,127 00:00:00,127

So there’s a quite uniform inaccuracy, but I’d guess that’s not necessarily an inaccuracy of the sleep-timer but some time the irq needs to wake up the processor and get it running again.

1 Like

If I’m reading @glx’s results correctly, I only see 1/8 of a second later than the expected time, after a 1-minute sleep.
And that appears very systematic verses random… only a 3 ms spread, or 50 ppm after removing the 0.125 (ms) bias.

It looks like the Xenon Sleep Time accuracy is pretty good, no?

I agree - I am going to close this as solved. Thanks for your help - your tests (@rftop and @glx) show that the real time counter is accurate over short periods with stop sleep. I think the issue with wake from sleep I am seeing is due to something else happening in the circuit that I am testing - essentially there is an interrupt going on from the sensor which should be ignored but isn’t. I am going to fit pull-up resistors rather than rely on the pinMode(pin, INPUT_PULLUP); and I need to look again at the ISR for this.

How are you powering your devices?
VUSB/VBUS fluctuations can cause premature wakes - IIRC.

1 Like

LiPo battery powered - I have fitted pull-up resistors on the interrupt pins (2) and I am re-running the test will all the devices.

I have also noticed good sleep time accuracy over months of time using Xenons, Argons, and Borons running off 3.7v LiPo Cells.

I was having them sleep for 30 seconds, wake up, change what was displayed on a 2.7 inch Sharp Memory low power LCD screen which included the time that was synced on the first cloud connection and then it never reconnected to the Cloud for a time update.

The time only drifted 1 min or so off over 30 days which impressed me. The 30 second wake up cycles stayed pretty much 30 seconds as programmed also.

So Sleep timing is pretty dam good from my testing of 4 different Gen 3 devices at the same time.

2 Likes

The main problem will be that as soon as external interfaces are involved (especially complex stuff like cloud-connections), that those are pretty unpredictable. The point will be that the time of your sensor’s measurement is the cruical part and not the exact time of the submission of that value, isn’t it? So maybe you could face that with a slightly different approach with a workflow like :thinking:

  • wake up from sleep
  • read that sensor-data
  • establish a connection to the cloud and publish the event (maybe with the exact timestanp of the reading)
  • check the current time (so variables like the time to connect to the cloud are eliminated)
  • sleep for an adjusted time when the net reading should be done

since there are always factors within the process from reading the data to publishing it like quality of the device’s connection quality and stuff, that can’t be predicted :slight_smile:.