You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

ESP8266两次深度睡眠间隔时长测量方法咨询

获取ESP8266深度睡眠间隔时长的可行方案

好问题!我之前用ESP8266做低功耗数据采集项目时,刚好遇到过一模一样的需求——既要支持定时唤醒,又要支持中断提前唤醒,还得准确记录每次睡眠的时长。给你分享几个靠谱的实现思路:

方案一:利用RTC内存+内置RTC计数器(推荐)

ESP8266的RTC模块在深度睡眠时会持续运行,而且有一块专门的RTC内存区域(断电/深度睡眠不会丢失数据),刚好用来存储睡眠前的计时点。

具体步骤:

  1. 定义一个存放在RTC内存的全局变量,用来记录进入睡眠前的RTC计数器值:

    // 用RTC_DATA_ATTR标记,变量会存在RTC内存,深度睡眠不丢失
    RTC_DATA_ATTR uint32_t sleep_start_rtc = 0;
    
  2. 在进入深度睡眠前,读取当前RTC计数器值并保存:

    void enterDeepSleep() {
      // 获取当前RTC计时值(单位:RTC时钟tick,ESP8266的RTC时钟是150kHz)
      sleep_start_rtc = system_get_rtc_time();
      // 设置唤醒规则:定时20秒 + 允许外部中断唤醒
      // WAKE_RF_DEFAULT表示唤醒后恢复WiFi功能
      ESP.deepSleep(20e6, WAKE_RF_DEFAULT);
    }
    
  3. 每次唤醒后,计算睡眠时长:

    void setup() {
      Serial.begin(115200);
      delay(100); // 给串口初始化留时间
    
      uint32_t current_rtc = system_get_rtc_time();
      if (sleep_start_rtc != 0) { // 排除第一次上电的情况
        uint32_t sleep_ticks;
        // 处理RTC计数器溢出(32位无符号数约8小时溢出一次)
        if (current_rtc >= sleep_start_rtc) {
          sleep_ticks = current_rtc - sleep_start_rtc;
        } else {
          sleep_ticks = (0xFFFFFFFF - sleep_start_rtc) + current_rtc + 1;
        }
        // 转换成秒:150kHz时钟,每秒150000个tick
        float sleep_duration = sleep_ticks / 150000.0;
        Serial.print("本次深度睡眠时长:");
        Serial.print(sleep_duration);
        Serial.println(" 秒");
      } else {
        Serial.println("首次上电,无睡眠时长记录");
      }
    
      // 这里写你的数据采集、WiFi传输代码...
    
      // 完成任务后进入深度睡眠
      enterDeepSleep();
    }
    
    void loop() {
      // 深度睡眠后不会执行到这里,无需编写内容
    }
    

为什么推荐这个方案?

  • 完全不需要额外硬件,利用ESP8266内置资源即可实现
  • RTC内存读写无Flash损耗(不像EEPROM是模拟在Flash上的)
  • 不管是定时唤醒还是中断唤醒,都能精准计算睡眠时长

方案二:结合唤醒原因+预设时长(适合简单场景)

如果你的中断唤醒场景不多,也可以通过判断唤醒原因来估算时长:

  • esp_sleep_get_wakeup_cause()函数获取唤醒源:
    • ESP_SLEEP_WAKEUP_TIMER:定时唤醒,时长就是你设置的ESP.deepSleep()参数
    • ESP_SLEEP_WAKEUP_EXT0/ESP_SLEEP_WAKEUP_EXT1:外部中断唤醒,这时候需要额外记录进入睡眠的时间(还是得用方案一的RTC计数器思路)

这个方案本质上是方案一的简化版,只在定时唤醒时直接用预设值,中断唤醒时再计算实际时长。

关于EEPROM的补充说明

你提到可以用EEPROM,但我不推荐:

  • ESP8266的EEPROM是模拟在Flash上的,频繁写入会缩短Flash寿命(Flash有擦写次数限制)
  • 读写EEPROM需要额外的初始化和操作代码,比RTC内存麻烦得多
  • 如果一定要用,逻辑和方案一类似:进入睡眠前把RTC计数器值写入EEPROM,唤醒后读取并计算差值,但要注意处理EEPROM的擦写和溢出问题

内容的提问来源于stack exchange,提问作者EnriqM

火山引擎 最新活动