概述
外部唤醒
除了计时器和触摸引脚之外,我们还可以通过切换引脚上的信号值(如按下按钮)将 ESP32 从深度睡眠中唤醒。这称为外部唤醒。外部唤醒有两种可能性:ext0 和 ext1。
外部唤醒 (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打开串行显示器。
按下按钮可唤醒 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睡眠模式——外部唤醒所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复