ESP32 esp_deep_sleep传入大uint64_t值失效问题求助
ESP32 esp_deep_sleep 传参异常与24小时深度睡眠解决方案
问题概述
ESP32的esp_deep_sleep函数官方定义接收uint64_t类型参数(表示深度睡眠的微秒时长),但传入uint64_t最大值18446744073709551615时,设备会提前重启,无法正常进入深度睡眠;传入该值的一半9223372036854775807时,设备能正常睡眠。当前需要实现连续24小时深度睡眠以节省电量,已通过分段睡眠的临时方案实现,寻求更官方、简便的解决办法。
测试验证
测试代码1(传入最大值,失效)
#include <esp_sleep.h> #include <stdlib.h> #include "RTClib.h" RTC_DS3231 rtc; void setup() { Serial.begin(115200); // 初始化RTC if (!rtc.begin()) { while (1) delay(10); } // 有效代码(uint64_t最大值的一半) // Serial.println("before uint64_t / 2 sleep"); // esp_deep_sleep((uint64_t)9223372036854775807); // 正常工作 // Serial.println("after uint64_t / 2 sleep"); // 无效代码(uint64_t最大值) Serial.println("before uint64_t sleep"); esp_deep_sleep((uint64_t)18446744073709551615); // 无法正常睡眠 Serial.println("after uint64_t sleep"); } void loop() { }
对应输出
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:4832 load:0x40078000,len:16460 load:0x40080400,len:4 load:0x40080404,len:3504 entry 0x400805cc E (57) esp_core�xump_flash: Core dump data check failed: Calculated checksum='9d56f9c2' Image checksum='ffffffff' before uint64_t sleep etS Jul 29 2019 12:21:46 rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:4832 load:0x40078000,len:16460 load:0x40080400,len:4 load:0x40080404,len:3504 entry 0x400805cc E (57) esp_corefxump_flash: Core dump data check failed: Calculated checksum='9d56f9c2' Image checksum='ffffffff' before uint64_t sleep etS Jul 29 2019 12:21:46
测试代码2(传入半值,正常)
#include <esp_sleep.h> #include <stdlib.h> #include "RTClib.h" RTC_DS3231 rtc; void setup() { Serial.begin(115200); // 初始化RTC if (!rtc.begin()) { while (1) delay(10); } // 有效代码(uint64_t最大值的一半) Serial.println("before uint64_t / 2 sleep"); esp_deep_sleep((uint64_t)9223372036854775807); // 正常工作 Serial.println("after uint64_t / 2 sleep"); // 无效代码(uint64_t最大值) // Serial.println("before uint64_t sleep"); // esp_deep_sleep((uint64_t)18446744073709551615); // 无法正常睡眠 // Serial.println("after uint64_t sleep"); } void loop() { }
对应输出
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:4832 load:0x40078000,len:16460 load:0x40080400,len:4 load:0x40080404,len:3504 entry 0x400805cc E (152) esp_cor �VW}���͡: Core dump data check failed: Calculated checksum='9d56f9c2' Image checksum='ffffffff' before uint64_t / 2 sleep
官方解决方案
直接使用精确的24小时微秒值
24小时对应的微秒数为 24LL * 60 * 60 * 1000000 = 86400000000ULL,该值远小于uint64_t的一半,直接传入即可实现连续24小时深度睡眠,无需分段:
#include <esp_sleep.h> #include <stdlib.h> #include "RTClib.h" RTC_DS3231 rtc; void setup() { Serial.begin(115200); // 初始化RTC if (!rtc.begin()) { while (1) delay(10); } // 直接传入24小时对应的微秒数 Serial.println("before 24h sleep"); esp_deep_sleep(86400000000ULL); Serial.println("after 24h sleep"); } void loop() { }
原因分析
uint64_t最大值18446744073709551615本质是无符号的-1,在ESP32的睡眠定时器处理逻辑中,该值会被判定为异常参数,导致睡眠流程失败触发重启。而9223372036854775807是int64_t的最大值,属于合法的超大睡眠时长范围,因此能正常工作。但对于24小时的需求而言,直接使用精确的微秒数是最简洁的方案,无需依赖超大值或分段睡眠。
当前临时解决方案代码
#include <esp_sleep.h> #include <stdlib.h> #include "RTClib.h" RTC_DS3231 rtc; RTC_DATA_ATTR int is_init = 0; RTC_DATA_ATTR uint64_t multiply_sleep_time = 1; void setup() { // 初始化完成后,通过两次12小时睡眠实现24小时总时长 if (is_init == 1 && multiply_sleep_time > 0){ multiply_sleep_time--; esp_deep_sleep((uint64_t)9223372036854775807); } Serial.begin(115200); // 初始化RTC if (!rtc.begin()) { while (1) delay(10); } // 启动时及每24小时需要执行的代码 is_init = 1; Serial.println("init"); // 第一次进入12小时睡眠 Serial.println("before uint64_t / 2 sleep"); esp_deep_sleep((uint64_t)9223372036854775807); Serial.println("after uint64_t / 2 sleep"); } void loop() { }
内容的提问来源于stack exchange,提问作者reZach
相关产品推荐
相关产品推荐

