ESP32 Deep Sleep với Arduino IDE
Trong bài viết này, chúng ta sẽ tìm hiểu chế độ ngủ sâu của ESP32 với Arduino IDE. Chúng ta sẽ tìm cách để cho ESP32 vào deep sleep và xem xét các cách khác nhau để đánh thức nó như:
- Timer Wakeup
- Touch Wakeup
- External Wakeup

Giới thiệu chế độ ngủ sâu – Deep Sleep
ESP32 có thể chuyển đổi giữa các chế độ hoạt động khác nhau:
- Chế độ hoạt động bình thường
- Chế độ ngủ Modem
- Chế độ ngủ nhẹ
- Chế độ ngủ sâu
- Chế độ ngủ đông
Bạn có thể so sánh năm chế độ khác nhau theo bảng dưới đây

Với mỗi chế độ hoạt động sẽ có những thành phần khác nhau bên trong ESP32 hoạt động và mức tiêu thụ điện năng khác nhau.

Và dưới đây là bảng so sánh mức tiêu thụ điện năng của từng chế độ RF

Tại sao chúng ta cần chế độ ngủ sâu?
Khi ESP32 của bạn chạy ở chế độ hoạt động bình thường với pin, năng lượng từ pin sẽ tiêu hao rất nhanh và nhanh chóng cạn kiệt năng lượng.

Nếu bạn để ESP32 của mình ở chế độ ngủ sâu, nó sẽ giảm mức tiêu thụ năng lượng và pin của bạn sẽ được giữ lâu hơn.
Khi ESP32 của bạn ở chế độ ngủ sâu có nghĩa là nó sẽ cắt giảm các hoạt động tiêu thụ nhiều năng lượng so với khi nó hoạt động bình thường. Trong chế độ này, ESP32 hoạt động vừa đủ để đánh thức bộ xử lý khi có điều gì đó xảy ra.
Trong chế độ ngủ sâu, tất cả các hoạt động CPU và Wi-Fi đều không diễn ra. Tuy nhiên, bộ xử lý Ultra Low Power (ULP) vẫn có thể được cấp điện để có thể hoạt động.
Mặc dù ESP32 ở chế độ ngủ sâu, bộ nhớ RTC cũng vẫn được cấp nguồn, vì vậy chúng ta có thể viết chương trình cho bộ xử lý ULP và lưu trữ nó trong bộ nhớ RTC để truy cập các thiết bị ngoại vi, bộ hẹn giờ bên trong và cảm biến nội bộ.
Chế độ hoạt động này sẽ rất hữu ích nếu bạn cần đánh thức CPU chính bởi một sự kiện bên ngoài, bộ hẹn giờ hoặc cả hai, trong khi vẫn duy trì mức tiêu thụ năng lượng tối thiểu.
RTC_GPIO PIN
Trong khi ngủ sâu, một số chân ESP32 có thể được sử dụng bởi bộ xử lý ULP, các chân này gọi là RTC_GPIO và các chân cảm ứng.
Bạn có thể xác định vị trí các chân RTC_GPIO theo hình bên dưới

Các cách để đánh thức ESP32
Sau khi đưa ESP32 vào chế độ ngủ sâu, có một số phương pháp để có thể đánh thức nó lên:
- Bạn có thể sử dụng bộ hẹn giờ, đánh thức bằng thời gian được xác định trước;
- Bạn có thể sử dụng Touch trên RTC_GPIO
- Bạn có thể sử dụng External Wakeup
- Bạn có thể sử dụng lõi ULP đánh thức
Trước khi đặt ESP32 vào chế độ ngủ sâu
Trước khi bạn đặt ESP32 của bạn vào chế độ ngủ sâu, bạn cần phải nhớ rằng:
- Đầu tiên, bạn cần cấu hình các nguồn thức dậy. Điều này có nghĩa là cấu hình những gì sẽ đánh thức ESP32. Bạn có thể sử dụng một hoặc kết hợp nhiều hơn một nguồn thức dậy.
- Bạn có thể quyết định những gì thiết bị ngoại vi nào sẽ được tắt hoặc tiếp tục trong khi ngủ sâu.Tuy nhiên, theo mặc định, ESP32 tự động cung cấp năng lượng cho các thiết bị ngoại vi không cần thiết với nguồn thức dậy mà bạn xác định.
- Cuối cùng, khi bạn gọi câu lệnh ESP_DEEP_SLEEP_START (), ESP32 của bạn sẽ lập tức tiến vào chế độ ngủ sâu.
Hẹn giờ thức dậy
ESP32 có thể chuyển sang chế độ ngủ sâu, và sau đó thức dậy vào các khoảng thời gian được xác định trước. Tính năng này đặc biệt hữu ích nếu bạn đang chạy các dự án yêu cầu thời gian làm việc ngắn hoặc nhiệm vụ hàng ngày, trong khi vẫn duy trì mức tiêu thụ năng lượng thấp.

Bộ điều khiển RTC ESP32 có bộ đếm thời gian tích hợp mà bạn có thể sử dụng để đánh thức ESP32 sau một khoảng thời gian được xác định trước.
Bật hẹn giờ thức dậy
Việc cho phép ESP32 thức dậy sau một khoảng thời gian được xác định trước là rất đơn giản. Trong Arduino IDE, bạn chỉ cần chỉ định thời gian ngủ tính bằng micro giây trong chức năng sau:
ESP_SLEEP_ENABLE_TIMER_WAKEUP (Time_in_us)Code mẫu
Hãy cùng xem cách thức hoạt động của nó bằng cách sử dụng một ví dụ từ thư viện. Mở Arduino IDE của bạn và trỏ đến File > Examples > ESP32 > Deep Sleep và mở 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
}Kiểm tra Timer Wake Up
Bạn mở Serial Monitor với mức baudrate 115200.

Mỗi 5 giây, ESP sẽ tỉnh dậy, in một thông điệp trên cổng nối tiếp và sau đó lại đi vào chế độ ngủ sâu.
Mỗi khi ESP tỉnh dậy, biến bootCount sẽ tăng lên. Nó cũng in ra lý do tỉnh dậy như được thể hiện trong hình dưới đây.

Tuy nhiên, lưu ý rằng nếu bạn nhấn nút EN trên bo mạch ESP32, nó sẽ đặt lại boot count về 1.
Bạn có thể sửa đổi ví dụ đã cung cấp, và thay vì in một thông điệp, bạn có thể làm cho ESP của bạn thực hiện bất kỳ công việc nào khác. Tính năng đánh thức bằng hẹn giờ rất hữu ích để thực hiện các công việc định kỳ với ESP32, như các công việc hàng ngày, mà không tiêu tốn nhiều năng lượng.
Wake Up với cảm ứng chạm
Bạn có thể đánh thức ESP32 từ chế độ ngủ sâu bằng cách sử dụng các chân cảm ứng. Phần này sẽ hướng dẫn cách thực hiện điều đó bằng việc sử dụng Arduino IDE.

Enable Touch Wake Up
Kích hoạt việc đánh thức ESP32 bằng cách sử dụng một chân cảm ứng. Trong Arduino IDE, bạn cần sử dụng hàm sau:
esp_sleep_enable_touchpad_wakeup()Code
Mở Arduino IDE và chọn File > Examples > ESP32 > Deep Sleep, sau đó mở TouchWakeUp.
/*
Deep Sleep with Touch Wake Up
This code displays how to use deep sleep with a touch as a wake up source and how to store data in RTC memory to use it over reboots
ESP32 can have multiple touch pads enabled as wakeup source
ESP32-S2 and ESP32-S3 supports only 1 touch pad as wakeup source enabled
This code is under Public Domain License. Author: Pranav Cherukupalli <[email protected]>
*/
#if CONFIG_IDF_TARGET_ESP32
#define THRESHOLD 40/* Greater the value, more the sensitivity */
#else //ESP32-S2 and ESP32-S3 + default for other chips (to be adjusted) */
#define THRESHOLD 5000/* Lower the value, more the sensitivity */
#endif
RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
/*
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;
}
}
/*
Method to print the touchpad by which ESP32
has been awaken from sleep
*/
void print_wakeup_touchpad(){
touchPin = esp_sleep_get_touchpad_wakeup_status();
#if CONFIG_IDF_TARGET_ESP32
switch(touchPin)
{
case 0 : Serial.println("Touch detected on GPIO 4"); break;
case 1 : Serial.println("Touch detected on GPIO 0"); break;
case 2 : Serial.println("Touch detected on GPIO 2"); break;
case 3 : Serial.println("Touch detected on GPIO 15"); break;
case 4 : Serial.println("Touch detected on GPIO 13"); break;
case 5 : Serial.println("Touch detected on GPIO 12"); break;
case 6 : Serial.println("Touch detected on GPIO 14"); break;
case 7 : Serial.println("Touch detected on GPIO 27"); break;
case 8 : Serial.println("Touch detected on GPIO 33"); break;
case 9 : Serial.println("Touch detected on GPIO 32"); break;
default : Serial.println("Wakeup not by touchpad"); break;
}
#else
if(touchPin < TOUCH_PAD_MAX)
{
Serial.printf("Touch detected on GPIO %d\n", touchPin);
}
else
{
Serial.println("Wakeup not by touchpad");
}
#endif
}
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 and touchpad too
print_wakeup_reason();
print_wakeup_touchpad();
#if CONFIG_IDF_TARGET_ESP32
//Setup sleep wakeup on Touch Pad 3 + 7 (GPIO15 + GPIO 27)
touchSleepWakeUpEnable(T3,THRESHOLD);
touchSleepWakeUpEnable(T7,THRESHOLD);
#else //ESP32-S2 + ESP32-S3
//Setup sleep wakeup on Touch Pad 3 (GPIO3)
touchSleepWakeUpEnable(T3,THRESHOLD);
#endif
//Go to sleep now
Serial.println("Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop(){
//This will never be reached
}Sơ đồ mạch điện

Kiểm tra hoạt động
Mở Serial Monitor với mức baudrate 115200.
Khi ESP32 chuyển sang chế độ ngủ sâu.
Bạn có thể đánh thức nó bằng cách chạm vào dây kết nối với chân cảm ứng 3.
Khi bạn chạm vào chân cảm ứng, ESP32 sẽ hiển thị trên Màn hình Nối tiếp: số lần khởi động, nguyên nhân đánh thức, và chân GPIO mà cảm ứng đã phát hiện.
External Wake Up
Ngoài việc sử dụng hẹn giờ và các chân cảm ứng, chúng ta cũng có thể đánh thức ESP32 từ chế độ ngủ sâu bằng cách thay đổi giá trị của một tín hiệu trên một chân, như việc nhấn một nút. Điều này được gọi là đánh thức từ bên ngoài. Bạn có hai khả năng đánh thức từ bên ngoài: ext0 và ext1.

External Wake Up (ext0)
Nguồn đánh thức này cho phép bạn sử dụng một chân để đánh thức ESP32.
Tùy chọn nguồn đánh thức ext0 sử dụng các GPIO RTC để đánh thức. Do đó, các bộ phận RTC sẽ được duy trì trong suốt thời gian ngủ sâu nếu nguồn đánh thức này được yêu cầu.
Để sử dụng nguồn đánh thức này, bạn sử dụng hàm sau:
esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)Hàm này chấp nhận như đối số đầu tiên là chân bạn muốn sử dụng, theo định dạng GPIO_NUM_X, trong đó X đại diện cho số GPIO của chân đó.
Đối số thứ hai, level, có thể là 1 hoặc 0. Điều này đại diện cho trạng thái của GPIO sẽ kích hoạt đánh thức.
Lưu ý: với nguồn đánh thức này, bạn chỉ có thể sử dụng các chân là RTC GPIOs.
External Wake Up (ext1)
Nguồn đánh thức này cho phép bạn sử dụng nhiều RTC GPIOs khác nhau. Bạn có thể sử dụng hai hàm logic khác nhau:
- Đánh thức ESP32 nếu bất kỳ chân nào bạn đã chọn là cao;
- Đánh thức ESP32 nếu tất cả các chân bạn đã chọn là thấp.
Nguồn đánh thức này được triển khai bởi bộ điều khiển RTC. Do đó, các bộ phận RTC và bộ nhớ RTC có thể được tắt nguồn trong chế độ này.
Để sử dụng nguồn đánh thức này, bạn sử dụng hàm sau:
esp_sleep_enable_ext1_wakeup(bitmask, mode)Hàm này chấp nhận hai đối số:
Một bitmask của các số GPIO sẽ gây ra đánh thức;
Chế độ: logic để đánh thức ESP32. Nó có thể là:
- ESP_EXT1_WAKEUP_ALL_LOW: đánh thức khi tất cả các GPIO đều thấp;
- ESP_EXT1_WAKEUP_ANY_HIGH: đánh thức nếu bất kỳ GPIO nào đều cao.
Lưu ý: với nguồn đánh thức này, bạn chỉ có thể sử dụng các chân là RTC GPIOs.
Code
Mở Arduino IDE, chọn File > Examples > ESP32 > Deep Sleep > ExternalWakeUp:
/* Deep Sleep with External Wake Up ===================================== This code displays how to use deep sleep with an external trigger as a wake up source and how to store data in RTC memory to use it over reboots This code is under Public Domain License. Hardware Connections ====================== Push Button to GPIO 33 pulled down with a 10K Ohm resistor NOTE: ====== Only RTC IO can be used as a source for external wake source. They are pins: 0,2,4,12-15,25-27,32-39. Author: Pranav Cherukupalli <[email protected]> */ #define BUTTON_PIN_BITMASK 0x200000000// 2^33 in hex 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 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. */ 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 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 }
Kiểm tra hoạt động
Sau khi upload code, bạn mở Serial Monitor với mức baudrate 115200.

nhấn nút nhấn để đánh thức ESP32.

Số lần boot sẽ tăng sau mỗi lần nhấn

Sử dụng phương pháp này rất hữu ích để đánh thức ESP32 bằng cách sử dụng một nút nhấn, ví dụ, để thực hiện một nhiệm vụ cụ thể. Tuy nhiên, với phương pháp này, bạn chỉ có thể sử dụng một GPIO làm nguồn đánh thức.
Nếu bạn muốn có nhiều nút nhấn khác nhau, tất cả đều đánh thức ESP, nhưng thực hiện các nhiệm vụ khác nhau, bạn cần sử dụng phương pháp ext1.
ext1
Phương pháp ext1 cho phép bạn đánh thức ESP bằng cách sử dụng các nút nhấn khác nhau và thực hiện các nhiệm vụ khác nhau tùy thuộc vào nút bạn nhấn.
Thay vì sử dụng hàm esp_sleep_enable_ext0_wakeup(), bạn sử dụng hàm esp_sleep_enable_ext1_wakeup(). Trong mã, hàm đó được chú thích:
//If you were to use ext1, you would use it like
//esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);Uncomment hàm này, bạn sẽ có được:
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);Đối số đầu tiên của hàm là một bitmask của các GPIO mà bạn sẽ sử dụng làm nguồn đánh thức, và đối số thứ hai xác định logic để đánh thức ESP32.
Trong ví dụ này, chúng ta đang sử dụng biến BUTTON_PIN_BITMASK, đã được định nghĩa ở đầu mã nguồn:
#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hexCode đang xác định một chân làm nguồn đánh thức, GPIO 33. Bạn cần sửa đổi bitmask để cấu hình thêm GPIOs khác làm nguồn đánh thức.
GPIOs Bitmask
Để có được bitmask của các GPIO, bạn có thể tuân theo các bước sau:
- Tính toán 2 mũ GPIO_NUMBER. Lưu kết quả dưới dạng số thập phân.
- Điều hướng đến một trang chuyển đổi từ thập phân sang thập lục phân, chẳng hạn như rapidtables.com/convert/number/decimal-to-hex.html, và chuyển đổi số thập phân sang số thập lục phân.
- Thay thế số thập lục phân bạn nhận được vào biến BUTTON_PIN_BITMASK.
Mask for a single GPIO
Để bạn hiểu cách lấy bitmask của các GPIO, chúng ta sẽ đi qua một ví dụ. Trong mã từ thư viện, nút được kết nối với GPIO 33. Để lấy mask cho GPIO 33:
- Tính 2^33. Bạn sẽ nhận được 8589934592;
- Chuyển đổi số đó (8589934592) sang hệ thập lục phân. Bạn có thể sử dụng trang chuyển đổi sau:

3. Sao chép số hệ thập lục phân vào biến BUTTON_PIN_BITMASK, và bạn sẽ nhận được:
#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hexMask cho một số GPIOs
Nếu bạn muốn sử dụng GPIO 2 và GPIO 15 làm nguồn đánh thức, bạn nên thực hiện như sau:
- Tính 2^2 + 2^15. Bạn sẽ nhận được 32772
- Chuyển đổi số đó sang hệ thập lục phân. Bạn sẽ nhận được: 8004
Thay thế số đó trong BUTTON_PIN_BITMASK như sau:
#define BUTTON_PIN_BITMASK 0x8004Xác định GPIO để sử dụng làm nguồn đánh thức ESP32
Khi bạn sử dụng nhiều chân để đánh thức ESP32, việc biết chính xác chân nào đã gây ra sự đánh thức là rất hữu ích. Để làm điều đó, bạn có thể sử dụng hàm sau:
esp_sleep_get_ext1_wakeup_status()Hàm này trả về một số cơ số 2, với số GPIO làm số mũ: 2^(GPIO). Vì vậy, để lấy GPIO ở dạng thập phân, bạn cần thực hiện phép tính sau:
GPIO = log(RETURNED_VALUE)/log(2)External Wake Up – Nhiều GPIOs
Bây giờ, bạn nên có thể đánh thức ESP32 bằng cách sử dụng các nút nhấn khác nhau và xác định chính xác nút nào đã gây ra sự đánh thức. Trong ví dụ này, chúng ta sẽ sử dụng GPIO 2 và GPIO 15 làm nguồn đánh thức.
Sơ đồ mạch điện
Kết nối hai nút nhấn vào ESP32 của bạn. Trong ví dụ này, chúng ta sẽ sử dụng GPIO 2 và GPIO 15, nhưng bạn có thể kết nối nút nhấn của mình vào bất kỳ RTC GPIO nào và sửa lại code.

Code
You need to make some modifications to the example code we’ve used before:
- create a bitmask to use GPIO 15 and GPIO 2. We’ve shown you how to do this before;
- enable ext1 as a wake up source;
- use the esp_sleep_get_ext1_wakeup_status() function to get the GPIO that triggered wake up.
The next sketch has all those changes implemented.
/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots
This code is under Public Domain License.
Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor
NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.
Author:
Pranav Cherukupalli <[email protected]>
*/
#define BUTTON_PIN_BITMASK 0x8004// GPIOs 2 and 15
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;
}
}
/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
uint64_t GPIO_reason = esp_sleep_get_ext1_wakeup_status();
Serial.print("GPIO that triggered the wake up: GPIO ");
Serial.println((log(GPIO_reason))/log(2), 0);
}
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();
//Print the GPIO used to wake up
print_GPIO_wake_up();
/*
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.
*/
//esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_15,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
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
}
Kết luận
Trong bài viết này, chúng ta đã tìm hiểu cách để đặt ESP32 vào chế độ ngủ sâu và đánh thức bằng nhiều nguồn khác nhau:
Timer Wake Up
- Để kích hoạt đánh thức bằng hẹn giờ, bạn sử dụng hàm esp_sleep_enable_timer_wakeup(time_in_us);
- Sử dụng hàm esp_deep_sleep_start() để bắt đầu chế độ ngủ sâu.
Touch Wake Up
- Để sử dụng các chân cảm ứng làm nguồn đánh thức, trước hết, bạn cần gắn các ngắt vào các chân cảm ứng bằng cách sử dụng: touchAttachInterrupt(ChânCảmỨng, callback, Ngưỡng)
- Sau đó, bạn kích hoạt các chân cảm ứng làm nguồn đánh thức bằng cách sử dụng: esp_sleep_enable_touchpad_wakeup()
- Cuối cùng, bạn sử dụng hàm esp_deep_sleep_start() để đưa ESP32 vào chế độ ngủ sâu.
External Wake Up
- Bạn chỉ có thể sử dụng các RTC GPIO làm nguồn đánh thức bên ngoài;
- Bạn có thể sử dụng hai phương pháp khác nhau: ext0 và ext1;
- ext0 cho phép bạn đánh thức ESP32 bằng cách sử dụng một chân GPIO duy nhất;
- ext1 cho phép bạn đánh thức ESP32 bằng cách sử dụng nhiều chân GPIO.
Nguồn: Tại đây












