我是靠谱客的博主 文静石头,最近开发中收集的这篇文章主要介绍esp32睡眠模式——外部唤醒,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

外部唤醒

除了计时器和触摸引脚之外,我们还可以通过切换引脚上的信号值(如按下按钮)将 ESP32 从深度睡眠中唤醒。这称为外部唤醒。外部唤醒有两种可能性:ext0 和 ext1。

img

外部唤醒 (ext0)

此唤醒源允许您使用引脚来唤醒 ESP32。

ext0 唤醒源选项使用 RTC GPIO 进行唤醒。因此,如果需要此唤醒源,则RTC外围设备将在深度睡眠期间保持打开状态。

若要使用此唤醒源,请使用以下函数:

esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)

此函数接受要使用的 pin 作为第一个参数,采用此格式GPIO_NUM_X,其中 X 表示该引脚的 GPIO 编号。

第二个论点,水平,可以是 1 或 0。这表示将触发唤醒的 GPIO 的状态。

**注意:**使用此唤醒源,您只能使用作为 RTC GPIO 的引脚。

外部唤醒 (ext1)

此唤醒源允许您使用多个 RTC GPIO。您可以使用两种不同的逻辑函数:

  • 如果您选择的任何引脚为高电平,请唤醒 ESP32;
  • 如果您选择的所有引脚都为低电平,请唤醒 ESP32。

此唤醒源由 RTC 控制器实现。因此,在此模式下,可以关闭RTC外设和RTC存储器的电源。

若要使用此唤醒源,请使用以下函数:

esp_sleep_enable_ext1_wakeup(bitmask, mode)

此函数接受两个参数:

  • 将导致唤醒的 GPIO 编号的位掩码;
  • 模式:唤醒 ESP32 的逻辑。它可以是:
    • ESP_EXT1_WAKEUP_ALL_LOW:当所有 GPIO 都变低时醒来;
    • ESP_EXT1_WAKEUP_ANY_HIGH:如果任何 GPIO 升高,请唤醒。

**注意:**使用此唤醒源,您只能使用作为 RTC GPIO 的引脚。

法典

让我们来探索 ESP32 库附带的示例。转到 ESP32 >深度睡眠>外部唤醒>文件>示例

/*
深度睡眠与外部唤醒
=====================================
此代码显示如何将深度睡眠与
外部触发器作为唤醒源以及如何
将数据存储在 RTC 内存中,以便在重新启动时使用
此代码属于公共领域许可证。
硬件连接
======================
按钮至 GPIO 33,下拉 10K 欧姆
电阻器
注意:
======
只有RTC IO可以用作外部唤醒的源
源。它们是引脚:0,2,4,12-15,25-27,32-39。
作者:
普拉纳夫切鲁库帕利<cherukupallip@gmail.com>
*/

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex启用GPIO 33.

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
/*
打印 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;//由外部信号使用RTC_IO引起的唤醒
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;//使用RTC_CNTL的外部信号引起的唤醒
    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: %dn",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打印 ESP32 的唤醒原因
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
      /*
首先配置唤醒源
我们将 ESP32 设置为唤醒外部触发器。
ESP32 有两种类型,ext0 和 ext1。
ext0 使用RTC_IO来唤醒,因此需要 RTC 外设
在 ext1 使用 RTC 控制器时打开,因此不需要
要打开的外围设备。
请注意,使用内部上拉/下拉也需要
要打开的 RTC 外围设备。
  */
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
    
  //Go to sleep now
    
   //如果您要使用 ext1,则可以像这样使用它
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //立即入睡
  Serial.println("Going to sleep now");
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

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

查看原始代码

此示例在触发时唤醒 ESP32GPIO 33到高。该代码示例演示如何使用这两种方法:ext0 和 ext1。如果按原样上传代码,则将使用 ext0。注释了要使用 ext1 的函数。我们将向您展示这两种方法的工作原理以及如何使用它们。

此代码与本文前面的代码非常相似。在setup(),首先初始化串行通信:

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

然后,您将一个递增到启动计数变量,然后在串行监视器中打印该变量。

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

接下来,使用print_wakeup_reason()前面定义的函数。

  //Print the wakeup reason for ESP32打印 ESP32 的唤醒原因
  print_wakeup_reason();

在此之后,您需要启用唤醒源。我们将分别测试每个唤醒源 ext0 和 ext1。

ext0

在此示例中,ESP32 在GPIO 33触发为高:

esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low

而不是GPIO 33,则可以使用任何其他 RTC GPIO 引脚。

图解的

要测试此示例,请按照下一个原理图将按钮连接到 ESP32。按钮已连接到GPIO 33使用下拉式 10K 欧姆电阻。
在这里插入图片描述

(此原理图使用 ESP32 DEVKIT V1 模块版本,具有 30 个 GPIO – 如果您使用的是其他型号,请检查所用主板的引脚排列。

**注意:**只有 RTC GPIO 可以用作唤醒源。除了 GPIO 33 之外,您还可以使用任何 RTC GPIO 引脚来连接按钮。

测试示例

让我们测试一下这个例子。将示例代码上传到 ESP32。确保选择了正确的主板和 COM 端口。以波特率为115200打开串行显示器。

img

按下按钮可唤醒 ESP32。

尝试多次,每次按下按钮时,都会看到启动计数增加。

使用此方法可用于使用按钮唤醒 ESP32,例如,执行特定任务。但是,使用此方法,您只能使用一个 GPIO 作为唤醒源。

如果您想要不同的按钮,它们都唤醒ESP,但执行不同的任务,该怎么办?为此,您需要使用 ext1 方法。

ext1

ext1 允许您使用不同的按钮唤醒 ESP,并根据您按下的按钮执行不同的任务。

而不是使用esp_sleep_enable_ext0_wakeup()函数,您可以使用esp_sleep_enable_ext1_wakeup()功能。在代码中,该函数被注释为:

   //如果您要使用 ext1,则可以像这样使用它
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

取消注释该函数,以便您拥有:

esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

该函数的第一个参数是将用作唤醒源的 GPIO 的位掩码,第二个参数定义了唤醒 ESP32 的逻辑。

在此示例中,我们使用变量BUTTON_PIN_BITMASK,这是在代码开头定义的:

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex

这只是将一个引脚定义为唤醒源,GPIO 33.您需要修改位掩码以将更多 GPIO 配置为唤醒源。

保留 GPIO 状态
还可以保留 GPIO 的状态,这对于保持打开 MOSFET 或将状态设置为外部器件非常有用。

if (ESP_SLEEP_WAKEUP_EXT0 == wakeup_reason) {
    Serial.println("Waked up from external GPIO!");
 
    gpio_hold_dis(GPIO_NUM_21);
    gpio_hold_dis(GPIO_NUM_19);
 
    gpio_deep_sleep_hold_dis();
}else{
    delay(1000);
    Serial.println();
    Serial.println("Start sleep!");
    delay(100);
 
    if (ESP_OK == gpio_hold_en(GPIO_NUM_21)){
        Serial.println("HOLD 21");
    }else{
        Serial.println("NO HOLD 21");
    }
    if (ESP_OK == gpio_hold_en(GPIO_NUM_19)){
            Serial.println("HOLD 19");
        }else{
            Serial.println("NO HOLD 19");
        }
 
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_15,LOW);
 
    gpio_deep_sleep_hold_en();
    //Go to sleep now
    Serial.println("Going to sleep now");
    esp_deep_sleep_start();
 
    delay(1);
}

如您所见,您可以强制使用 GPIO 的值,并且需要调用以允许再次更改它。gpio_hold_en gpio_hold_dis

若要在深度睡眠唤醒后启用值保留,必须向代码中添加一个函数。gpio_deep_sleep_hold_en()

最后

以上就是文静石头为你收集整理的esp32睡眠模式——外部唤醒的全部内容,希望文章能够帮你解决esp32睡眠模式——外部唤醒所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部