ESP32是最流行的基于Wi-Fi的微控制器模块之一,它是许多便携式IoT应用程序中的流行选择。它是一个功能强大的控制器,支持双核编程,还具有内置的蓝牙低功耗(BLE)支持,使其成为便携式应用程序(如iBeacon设备,GPS跟踪器等)的不错选择。但是,在此类电池供电的应用程序中,主要问题是备用电池。可以通过对微控制器单元进行更智能的控制来增加这种备用电池,就像在理想情况下可以在睡眠模式下为ESP32编程 以增加设备的备用电池一样。
在本项目中,我们将检查正常工作模式和深度睡眠模式下广泛流行的Wi-Fi和支持蓝牙的微控制器ESP32的当前功耗。此外,我们将测试差异并检查如何将ESP32置于深度睡眠模式。您还可以查看有关如何最大程度地降低微控制器功耗的文章,以获取其他技巧,这些技巧可以使您的设计更加节能。此外,如果您对其他微控制器的睡眠模式感兴趣,可以选择Arduino睡眠模式和ESP8266 NodeMCU睡眠模式。
要求
为此,我们将使用Espressif的基于ESP32的Devkit V4.0,该USB 4.0具有USB至UART桥接以及其他ESP32引脚排列,以便于连接。编程将使用Arduino IDE完成。如果您是全新手,请在继续之前阅读链接的文章,以了解如何使用Arduino入门ESP32。
该项目的要求如下:
- 按下按钮将进入深度睡眠模式。
- 按下另一个按钮,它将从深度睡眠模式中唤醒。
- 要检测ESP32的状态,LED会以1000毫秒的开启时间闪烁。在睡眠模式下,它将关闭。
因此,需要其他组件-
- LED-1个
- 按钮式(触觉开关)-2个
- 4.7k电阻器-2个
- 680R电阻器-1个
- 面包板
- 连接线
- 5V适配器或电源设备
- 微型USB电缆
- 在PC或笔记本电脑中具有ESP32编程接口的Arduino IDE。
ESP32睡眠模式电路图
ESP32通过按钮进入睡眠的原理图如下所示。
原理图非常简单。它有两个按钮。睡眠按钮将使ESP32进入深度睡眠模式,并使用另一个开关将ESP32从睡眠模式唤醒。两个按钮都连接在PIN 16和PIN 33中。按下时两个按钮均配置为低电平有效,因此会产生一个额外的上拉电阻。但是,要检测ESP 32是处于睡眠模式还是正常工作状态模式,请将LED连接到IO引脚4。
ESP32的睡眠模式概述
ESP32有许多不同的电源模式,即活动模式,调制解调器睡眠模式,轻度睡眠模式,深度睡眠模式和休眠模式。
在正常工作状态下,ESP32会在主动模式下运行。在ESP32主动模式期间,CPU,WiFi / BT硬件,RTC内存和RTC外围设备,ULP协处理器均被激活并根据工作负载工作。但是,在不同的电源模式下,一个或多个外围设备将关闭。要检查不同的电源模式操作,请遵循下表-
硬件 |
主动模式 |
调制解调器睡眠模式 |
浅睡眠模式 |
深度睡眠模式 |
冬眠 |
中央处理器 |
上 |
上 |
暂停 |
关 |
关 |
WiFi /蓝牙 |
上 |
关 |
关 |
关 |
关 |
RTC和RTC外围设备 |
上 |
上 |
上 |
上 |
关 |
ULP-Co处理器 |
上 |
上 |
上 |
开关 |
关 |
如上表所示,在ESP32深度睡眠模式下,通常称为ULP传感器监控的模式-CPU,WiFi / BT,RTC存储器和外围设备,ULP协处理器均已关闭。仅打开RTC内存和RTC外设。
在唤醒情况下,需要通过唤醒源通知ESP32,它将ESP32从深度睡眠模式唤醒。但是,由于RTC外设已打开,ESP32可以通过启用RTC的GPIO唤醒。还有其他选择。它可以通过外部唤醒中断引脚或使用计时器唤醒ESP32来唤醒。在此项目中,我们在引脚33上使用ext0唤醒。
将ESP32编程为深度睡眠模式
完整程序可在此页面底部找到。它是为Arduino IDE编写的,因此可以轻松地适应您的要求。代码说明如下。
在代码的开头,
//创建一个PushButton变量 PushBnt pushBtn = {GPIO_NUM_16,0,false}; //定义LED引脚 uint8_t led_pin = GPIO_NUM_4; //定义唤醒引脚 uint8_takeUp_pin = GPIO_NUM_33;
以上三行定义了唤醒引脚,LED引脚和睡眠模式引脚。
void setup(){ //将您的安装代码放在此处,以运行一次: //将串行端口设置为115200 Serial.begin(115200); 延迟(1000); //通过内部PullUp pinMode(pushBtn.pin,INPUT_PULLUP); 将按钮按钮设置为输入 //在下降模式下使用pushButton引脚设置中断处理程序 attachInterrupt(pushBtn.pin,isr_handle,FALLING); //将Led引脚设置为输出 pinMode(led_pin,OUTPUT); //创建一个任务,该任务将在具有优先级1并在核心0上执行的blinkLed()函数中执行 xTaskCreate( blinkLed,/ * Task函数。* / “ blinkLed”,/ *任务名称。* / 1024 * 2 ,/ *任务的堆栈大小* / NULL,/ *任务的参数* / 5,/ *任务的优先级* / &taskBlinkled); / *跟踪已创建任务的任务句柄* / delay(500); //将引脚33配置为ext0唤醒源,逻辑电平低 esp_sleep_enable_ext0_wakeup((gpio_num_t)wakeUp_pin,0); }
在上面,通过代码片段将中断设置为下降模式
attachInterrupt(pushBtn.pin,isr_handle,FALLING);
因此,无论何时按下开关,逻辑电平都会从逻辑1(3.3V)变为逻辑0(0V)。按钮引脚的电压将下降,ESP32将识别出已按下开关。还创建了一个使LED闪烁的任务。
xTaskCreate( blinkLed,/ *任务功能。* / “ blinkLed”,/ *任务名称。* / 1024 * 2,/ *任务堆栈大小* / NULL,/ *任务参数* / 5,5,/ *优先级任务* / &taskBlinkled); / *跟踪已创建任务的任务句柄* / delay(500);
引脚33还使用以下代码段配置为标识为ext0的外部唤醒源。
esp_sleep_enable_ext0_wakeup((gpio_num_t)wakeUp_pin,0);
接下来,在while循环中-
void loop(){ //将您的主代码放在此处,以便重复运行: if(pushBtn.pressed){ Serial.printf(“ PushButton(%d)Pressed \ n”,pushBtn.pin); Serial.printf(“挂起'blinkLed'任务\ n”); //暂停blinkLed Task vTaskSuspend(taskBlinkled); digitalWrite(led_pin,LOW); Serial.printf(“正在睡觉….. \ n”,pushBtn.pin); pushBtn.pressed = false; //立即入睡 esp_deep_sleep_start(); } esp_sleep_wakeup_cause_takeupReason; wakeupReason = esp_sleep_get_wakeup_cause(); switch(wakeupReason) { case ESP_SLEEP_WAKEUP_EXT0:Serial.println(“使用外部信号ext0进行从睡眠中唤醒”);打破; case ESP_SLEEP_WAKEUP_EXT1:Serial.println(“使用外部信号ext1从睡眠中唤醒”);打破; case ESP_SLEEP_WAKEUP_TIMER:Serial.println(“使用计时器信号从睡眠中唤醒”);打破; case ESP_SLEEP_WAKEUP_TOUCHPAD:Serial.println(“使用触摸板信号从睡眠中唤醒”);打破; case ESP_SLEEP_WAKEUP_ULP:Serial.println(“使用ULP信号从睡眠中唤醒”);打破; 默认值:break; Serial.printf(“恢复'blinkLed'任务\ n”); //重新启动blinkLed Task vTaskResume(taskBlinkled); } }
while循环不断检查是否按下了睡眠按钮。如果按下该按钮,它将停止或暂停LED闪烁任务,并运行esp深度睡眠启动功能-
esp_deep_sleep_start();
在这种情况下,如果按下ext0外部中断按钮,它将立即从深度睡眠模式中唤醒,并继续执行LED闪烁任务。
最后,在下面的代码片段中可以看到LED闪烁功能,它将使LED闪烁1000毫秒。
void blinkLed(void * param){ while(1){ static uint32_t pin_val = 0; //切换引脚值 pin_val ^ = 1; digitalWrite(led_pin,pin_val); Serial.printf(“ Led -----------------%s \ n”,pin_val?“ On”:“ Off”); / *只需每1000毫秒或1秒切换一次LED * / vTaskDelay(1000 / portTICK_PERIOD_MS); } taskBlinkled = NULL; vTaskDelete(NULL); }
在深度睡眠模式下测试ESP32
该电路在面包板上构建,Metravi XB版万用表用于测量电流。在活动模式下,电路汲取的电流几乎为58 mA,但在深度睡眠模式下,电流几乎为4.10 mA。下图显示了ESP32活动模式的电流消耗-
在深度睡眠模式下,记录的电流消耗降至3.95mA左右,下图显示了ESP32深度睡眠模式的电流消耗-
但是,在深度睡眠模式下,ESP32的电流消耗几乎为150 uA。但是此ESP32 Devkit板记录的电流消耗几乎为4.10 mA。这是由于CP2102和线性稳压器。这两个连接到5V电源线。电源线中还连接了一个电源LED,该LED消耗近2mA的电流。
因此,可以很容易地识别出ESP32在深度睡眠模式条件下消耗的能量非常低,这对于电池供电的操作非常有用。有关其工作原理的更多信息,请查看下面的视频链接。如果您有任何疑问,请将其留在下面的评论部分,或将我们的论坛用于其他技术问题。