天天看點

ESP32定時器睡眠模式

定時器喚醒

ESP32 可以進入深度睡眠模式,然後在預定義的時間段内喚醒。如果您正在運作需要時間戳或日常任務的項目,同時保持低功耗,則此功能特别有用。

ESP32定時器睡眠模式

ESP32 RTC 控制器具有一個内置計時器,可用于在預定義的時間後喚醒 ESP32。

啟用定時器喚醒

讓 ESP32 在預定義的時間後喚醒非常簡單。在 Arduino IDE 中,您隻需在以下函數中以微秒為機關指定休眠時間:

法典

讓我們使用庫中的示例來看看它是如何工作的。打開 Arduino IDE,轉到 ESP32 >深度睡眠>檔案>示例,然後打開 TimerWakeUp 草圖。

/*
Simple Deep Sleep with Timer Wake Up
=====================================
ESP32 offers a deep sleep mode for effective power
saving as power is an important factor for IoT
applications. In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

This code displays the most basic deep sleep with
a timer to wake it up and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli <[email protected]>
*/

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");

  /*
  Next we decide what all peripherals to shut down/keep on
  By default, ESP32 will automatically power down the peripherals
  not needed by the wakeup source, but if you want to be a poweruser
  this is for you. Read in detail at the API docs
  http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html
  Left the line commented as an example of how to configure peripherals.
  The line below turns off all RTC peripherals in deep sleep.
  */
  //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");

  /*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  delay(1000);
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}
           

檢視原始代碼

讓我們看一下此代碼。第一條評論描述了在深度睡眠和定時器喚醒期間關閉電源的内容。

In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories
           

使用定時器喚醒時,将通電的部件是RTC控制器、RTC外設和RTC存儲器。

定義睡眠時間

前兩行代碼定義了 ESP32 将休眠的時間段。

#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ 
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */
           

此示例使用從微秒到秒的轉換因子,以便您可以在TIME_TO_SLEEP在幾秒鐘内變量。在這種情況下,該示例會将 ESP32 置于深度睡眠模式 5 秒鐘。

将資料儲存在 RTC 存儲器上

借助 ESP32,您可以将資料儲存在 RTC 存儲器上。ESP32 在 RTC 部分具有 8kB SRAM,稱為 RTC 快速存儲器。儲存在此處的資料在深度睡眠期間不會被删除。但是,當您按下重置按鈕(ESP32 開發闆上标有 EN 的按鈕)時,它将被擦除。

要将資料儲存在RTC存儲器上,您隻需添加RTC_DATA_ATTR在變量定義之前。該示例儲存啟動計數變量。此變量将計算 ESP32 從深度睡眠中醒來的次數。

喚醒原因

然後,代碼定義print_wakeup_reason()函數,列印 ESP32 從睡眠狀态喚醒的原因。

void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason){
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}
           

設定()

在setup()是您應該放置代碼的位置。在深度睡眠中,素描永遠不會到達loop()陳述。是以,你需要把所有的草圖都寫在setup().

此示例首先以波特率為 115200 初始化串行通信。

然後,啟動計數變量在每次重新啟動時都會增加一個,并且該數字将列印在串行螢幕中。

++bootCount;
Serial.println("Boot number: " + String(bootCount));
           

然後,代碼調用print_wakeup_reason()函數,但您可以調用任何要執行所需任務的函數。例如,您可能希望每天喚醒一次 ESP32,以便從傳感器讀取值。

接下來,代碼使用以下函數定義喚醒源:

此函數接受以微秒為機關的睡眠時間作為參數,如前所述。

在我們的例子中,我們有以下内容:

然後,在執行所有任務後,esp 通過調用以下函數進入睡眠狀态:

循環()

這loop()部分為空,因為 ESP32 将在到達代碼的這一部分之前進入休眠狀态。是以,您需要将所有草圖寫在setup().

将示例草圖上傳到 ESP32。確定選擇了正确的主機闆和 COM 端口。

測試計時器喚醒

以波特率為115200打開串行顯示器。

ESP32定時器睡眠模式

每隔 5 秒,ESP 喚醒,在串行螢幕上列印一條消息,然後再次進入深度睡眠狀态。

每次 ESP 喚醒啟動計數變量增加。它還會列印喚醒原因,如下圖所示。

但是,請注意,如果按下 ESP32 開發闆上的 EN 按鈕,它會再次将引導計數重置為 1。

您可以修改提供的示例,而不是列印消息,您可以讓 ESP 執行任何其他任務。計時器喚醒功能可用于使用 ESP32 執行定期任務,例如日常任務,而不會消耗太多電量。