Esp_light_sleep wakes after 40 minutes instead of 3 hours

I have two devices in my network, i’m settnig both to sleep for 10800 seconds (or three hours). I do this by setting
int sleeptime = 10800;
esp_sleep_enable_timer_wakeup((unsigned long)((unsigned long)sleeptime*1000000UL));
(ok, in reality the sleep time is calculated, hence it is an int that has a value of 10800 which a printout clearly shows).

However, both devices wake up after about 40 minutes. they also more or less wake up synchronously, so it can’t just be a really weird time drift.

I’m using the internal oscillator, as my code crashes for no apparent reason when i try and use it with an external crystal but that’s a topic for another time.

Any idea what i might be doing wrong?

It would be great to have absolute minimal test project to reproduce the error and take a closer look at what might causing the error.

This would let us also know the used board and framework version.

You said you are using the internal oscillator.
Sounds like your code is modifying some clock sources which might be the reason for your issue.
That’s just a guess without seeing your code.

it’s an esp32 s3, custom board design.
i mean you’re right, i should just actually test that in an isolated manner. i’ll try that right now.

1 Like

@hdsjulian Note my edit about the clock source.

so i changed nothing about the clock source.
rtc_slow_freq_t slow_clk_src = rtc_clk_slow_src_get();
equals RTC_SLOW_FREQ_RTC.
Thats what i mean with internal oscillator.

what i mean with the comment about setting the clock to the 32k XTAL:

rtc_clk_32k_enable(true);
rtc_clk_slow_src_set(RTC_SLOW_FREQ_32K_XTAL);
works and slow_clk_src = rtc_clk_slow_src_get(); then gives me RTC_SLOW_FREQ_32K_XTAL, however when i then set the timer_wakeup to 10 seconds and do
esp_err_t result = esp_light_sleep_start();

i get a coredump that doesn’t really get me anywhere (it references a line in the sleep library that doesn’t give me any info about what i might be doing wrong)

@sivar2311 so, i might have figured it out, it might be a type error after all

1 Like

Suspicious numbers are suspicious.

3 hours = 180 minutes
40 minutes = 40 minutes

Their ratio: 180 / 40 = 4.5.

Meaning, the sleep time is passing 4.5 faster than it should. (Or by reverse. only factor 22.22% of the expected time is slept).

The possible timers that sleep is based upon are:

external 32.768 kHz (“clock quartz”)
internal 150 kHz RC (RC-based clocks are inaccurate with a few percent).

==> 32.768 * 4.5 = 147.45 kHz. So, approximately 150 kHz.

Thus it seems to me that esp_sleep_enable_timer_wakeup() is calculating the number of “sleep / slow clock ticks” with respect to a 32.768 kHz clock, while the system is actually running with the faster 150kHz clock; This is about 4.5 times faster, and thus the system also wakes up 4.5 times after. Thus the number of ticks to sleep are over faster than anticipated.

When you ask for

int sleeptime_ms = 45000; // 45 seconds
esp_sleep_enable_timer_wakeup((unsigned long)((unsigned long)sleeptime*1000UL));`

Does it wake up after 10 seconds instead? Is that reproducable in an absolute minimal example?

1 Like

thank you, very interesting theory. It turned out to be a type error after all. max unsigned long is 4 billion and 10800 times a million overflows that.
had to use an unsigned long long (or 64 bit int) and now it works :slight_smile:

2 Likes