ESP32

ESP32 Deep Sleep with Arduino IDE and Wake Up Sources

기하 2021. 8. 16. 06:15

이 기사는 Arduino IDE를 사용한 ESP32 딥 슬립 모드에 대한 완전한 가이드입니다. ESP32를 깊은 절전 모드로 전환하는 방법과 이를 깨우기 위한 다양한 모드( 타이머 깨우기 , 터치 깨우기  외부 깨우기)를 살펴보겠습니다 . 이 가이드는 코드, 코드 설명 및 회로도와 함께 실제 예제를 제공합니다.

관련 콘텐츠: ESP8266 Arduino IDE를 사용한 딥 슬립

이 기사는 4개의 다른 부분으로 나뉩니다:

  1. 숙면 모드 소개
  2. 타이머 깨우기
  3. 터치 깨우기
  4. 외부 깨우기

숙면 모드 소개

ESP32는 서로 다른 전원 모드 간에 전환할 수 있습니다.

  • 활성 모드
  • 모뎀 절전 모드
  • 라이트 슬립 모드
  • 딥 슬립 모드
  • 최대 절전 모드

ESP32 Espressif 데이터시트의 다음 표에서 5가지 모드를 비교할 수 있습니다.

 

ESP32 Espressif 데이터 시트는 또한 다른 전원 모드의 소비 전력을 비교하는 표를 제공합니다.

그리고 다음 은 활성 모드에서 전력 소비를 비교하기 위한 표 10입니다 .

왜 딥슬립 모드인가?

ESP32를 배터리로 활성 모드로 실행하는 것은 배터리의 전력이 매우 빨리 소모되기 때문에 이상적이지 않습니다.

 

ESP32를 최대 절전 모드로 설정하면 전력 소비가 줄어들고 배터리가 더 오래 지속됩니다.

ESP32를 최대 절전 모드로 설정한다는 것은 작동하는 동안 더 많은 전력을 소비하는 활동을 차단하는 것을 의미하지만 흥미로운 일이 발생했을 때 프로세서를 깨울 만큼 충분한 활동만 남겨둡니다.

깊은 절전 모드에서는 CPU 또는 Wi-Fi 활동이 발생하지 않지만 ULP(초저전력) 보조 프로세서의 전원은 계속 켤 수 있습니다.

ESP32가 딥 슬립 모드에 있는 동안 RTC 메모리도 전원이 켜진 상태로 유지되므로 ULP 보조 프로세서용 프로그램을 작성하고 RTC 메모리에 저장하여 주변 장치, 내부 타이머 및 내부 센서에 액세스할 수 있습니다.

이 작동 모드는 최소한의 전력 소비를 유지하면서 외부 이벤트, 타이머 또는 둘 다에 의해 메인 CPU를 깨워야 하는 경우에 유용합니다.

RTC_GPIO 핀

딥 슬립 동안 ESP32 핀 중 일부는 ULP 보조 프로세서, 즉 RTC_GPIO 핀 및 터치 핀에서 사용할 수 있습니다. ESP32 데이터 시트는 RTC_GPIO 핀을 식별하는 표를 제공합니다. 당신은 그 테이블을 찾을 수 있습니다 여기에 7 페이지에서.

해당 표를 참조로 사용하거나 다음 핀아웃을 살펴보고 다른 RTC_GPIO 핀을 찾을 수 있습니다. RTC_GPIO 핀은 주황색 직사각형 상자로 강조 표시됩니다.

 

또한 읽기와 같은 수 있습니다 ESP32 핀아웃 참조 : 어떤 GPIO 핀을 당신은 사용해야합니까?

깨우기 소스

ESP32를 최대 절전 모드로 전환한 후 여러 가지 방법으로 절전 모드를 해제할 수 있습니다.

  1. 당신이 사용할 수있는 타이머를 시간의 미리 정의 된 기간을 사용하여 ESP32을 깨어;
  2. 터치 핀을 사용할 수 있습니다 .
  3. 외부 깨우기의 두 가지 가능성을 사용할 수 있습니다 . 하나의 외부 깨우기 또는 여러 다른 외부 깨우기를 사용할 수 있습니다.
  4. ULP 보조 프로세서  사용하여 절전 모드를 해제할 수 있습니다. 이는 이 가이드에서 다루지 않습니다.

깊은 수면 스케치 작성하기

ESP32를 최대 절전 모드로 전환한 다음 깨우기 위한 스케치를 작성하려면 다음을 염두에 두어야 합니다.

  1. 먼저 깨우기 소스를 구성해야 합니다. 이것은 ESP32를 깨울 항목을 구성한다는 것을 의미합니다. 하나를 사용하거나 둘 이상의 깨우기 소스를 결합할 수 있습니다.
  2. 최대 절전 모드에서 종료하거나 유지할 주변 장치를 결정할 수 있습니다. 그러나 기본적으로 ESP32는 사용자가 정의한 깨우기 소스에 필요하지 않은 주변 장치의 전원을 자동으로 끕니다.
  3. 마지막으로, 당신은 esp_deep_sleep_start() ESP32를 깊은 절전 모드로 전환하는 기능.

타이머 깨우기

ESP32는 깊은 절전 모드로 들어간 다음 미리 정의된 시간에 깨울 수 있습니다. 이 기능은 낮은 전력 소비를 유지하면서 타임 스탬프 또는 일일 작업이 필요한 프로젝트를 실행하는 경우에 특히 유용합니다.

ESP32 RTC 컨트롤러에는 미리 정의된 시간 후에 ESP32를 깨우는 데 사용할 수 있는 내장 타이머가 있습니다.

타이머 깨우기 활성화

미리 정의된 시간 후에 ESP32를 활성화하는 것은 매우 간단합니다. Arduino IDE에서 다음 함수에서 절전 시간을 마이크로초 단위로 지정하기만 하면 됩니다.

 

esp_sleep_enable_timer_wakeup(time_in_us)

암호

라이브러리의 예제를 사용하여 이것이 어떻게 작동하는지 봅시다. Arduino IDE를 열고 File > Examples > ESP32 > Deep Sleep으로 이동 하여 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 <cherukupallip@gmail.com> */ #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 }

원시 코드 보기

이 코드를 살펴보겠습니다. 첫 번째 주석은 타이머 웨이크업과 함께 깊은 수면 중에 전원이 꺼지는 것을 설명합니다.

 

이 모드에서 CPU, 대부분의 RAM, 클럭되는 모든 디지털 주변 장치 APB_CLK에서 전원이 꺼져 있습니다. 의 유일한 부분 여전히 전원을 켤 수 있는 칩: RTC 컨트롤러, RTC 주변 장치 및 RTC 메모리

타이머 깨우기를 사용할 때 전원이 켜질 부품은 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) */

이 예에서는 마이크로초에서 초로의 변환 계수를 사용하므로 수면 시간을 설정할 수 있습니다. 수면 시간초 단위의 변수. 이 경우 예제는 ESP32를 5초 동안 깊은 절전 모드로 전환합니다.

RTC 메모리에 데이터 저장

ESP32를 사용하면 RTC 메모리에 데이터를 저장할 수 있습니다. ESP32에는 RTC 고속 메모리라고 하는 RTC 부분에 8kB SRAM이 있습니다. 여기에 저장된 데이터는 딥 슬립 중에도 지워지지 않습니다. 그러나 재설정 버튼(ESP32 보드에서 EN으로 표시된 버튼)을 누르면 지워집니다.

RTC 메모리에 데이터를 저장하려면 다음을 추가하기만 하면 됩니다. RTC_DATA_ATTR변수 정의 전에. 예제는 다음을 저장합니다.부팅 횟수RTC 메모리의 변수. 이 변수는 ESP32가 깊은 잠에서 깨어난 횟수를 계산합니다.

RTC_DATA_ATTR int bootCount = 0;

기상 이유

그런 다음 코드는 다음을 정의합니다. 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; } }

 

설정()

에서 설정()코드를 넣어야 하는 곳입니다. 깊은 잠 속에서 스케치는 결코 닿지 않는다고리()성명. 그래서, 당신은 모든 스케치를 작성해야합니다설정().

이 예제는 115200의 전송 속도에서 직렬 통신을 초기화하는 것으로 시작합니다.

Serial.begin(115200);

그런 다음, 부팅 횟수 변수는 재부팅할 때마다 1씩 증가하고 그 숫자가 직렬 모니터에 인쇄됩니다.

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

그런 다음 코드는 print_wakeup_reason()함수이지만 원하는 작업을 수행하기 위해 원하는 함수를 호출할 수 있습니다. 예를 들어 센서에서 값을 읽기 위해 하루에 한 번 ESP32를 깨우고 싶을 수 있습니다.

다음으로 코드는 다음 함수를 사용하여 깨우기 소스를 정의합니다.

esp_sleep_enable_timer_wakeup(time_in_us)

이 함수는 이전에 본 것처럼 마이크로초 단위의 절전 시간을 인수로 받아들입니다.

우리의 경우 다음이 있습니다.

esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

그런 다음 모든 작업이 수행된 후 esp는 다음 함수를 호출하여 절전 모드로 전환됩니다.

esp_deep_sleep_start()

루프()

NS 고리()ESP32가 코드의 이 부분에 도달하기 전에 절전 모드로 전환되기 때문에 섹션이 비어 있습니다. 따라서 모든 스케치를설정().

ESP32에 예제 스케치를 업로드합니다. 올바른 보드와 COM 포트를 선택했는지 확인하십시오.

타이머 깨우기 테스트

115200의 전송 속도로 직렬 모니터를 엽니다.

 

5초마다 ESP는 깨어나서 직렬 모니터에 메시지를 인쇄하고 다시 깊은 절전 모드로 들어갑니다.

ESP가 깨어날 때마다 부팅 횟수변수가 증가합니다. 아래 그림과 같이 wake up 이유도 출력합니다.

그러나 ESP32 보드의 EN 버튼을 누르면 부팅 카운트가 다시 1로 재설정됩니다.

제공된 예제를 수정할 수 있으며 메시지를 인쇄하는 대신 ESP가 다른 작업을 수행하도록 할 수 있습니다. 타이머 깨우기는 많은 전력을 소모하지 않고 일상적인 작업과 같이 ESP32로 주기적 작업을 수행하는 데 유용합니다.

터치 깨우기

터치 핀을 사용하여 ESP32를 깊은 절전 모드에서 깨울 수 있습니다. 이 섹션에서는 Arduino IDE를 사용하여 이를 수행하는 방법을 보여줍니다.

 

터치 깨우기 활성화

터치핀을 사용하여 ESP32를 활성화하는 것은 간단합니다. Arduino IDE에서 다음 기능을 사용해야 합니다.

esp_sleep_enable_touchpad_wakeup()

암호

라이브러리의 예제를 사용하여 이것이 어떻게 작동하는지 봅시다. Arduino IDE를 열고 File   Examples   ESP32   Deep Sleep 으로 이동 하여 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 This code is under Public Domain License. Author: Pranav Cherukupalli <cherukupallip@gmail.com> */ #define Threshold 40 /* Greater the value, more the sensitivity */ 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(); 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; } } void callback(){ //placeholder callback function } 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(); //Setup interrupt on Touch Pad 3 (GPIO15) touchAttachInterrupt(T3, callback, Threshold); //Configure Touchpad as wakeup source esp_sleep_enable_touchpad_wakeup(); //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 }

 

원시 코드 보기

임계값 설정

가장 먼저 해야 할 일은 터치 핀의 임계값을 설정하는 것입니다. 이 경우 우리는한계점 프로젝트에 따라 임계값을 변경해야 할 수도 있습니다.

#define Threshold 40

터치 감지 GPIO를 터치하면 센서가 읽는 값이 감소합니다. 따라서 터치가 감지될 때 발생하는 임계값을 설정할 수 있습니다.

여기에 설정된 임계값은 터치 감지 GPIO에서 읽은 값이 40 미만일 때 ESP32가 깨어나야 함을 의미합니다. 원하는 감도에 따라 해당 값을 조정할 수 있습니다.

인터럽트 연결

터치 감지 핀에 인터럽트를 연결해야 합니다. 지정된 GPIO에서 터치가 감지되면 콜백 함수가 실행됩니다. 예를 들어 다음 줄을 살펴보십시오.

//Setup interrupt on Touch Pad 3 (GPIO15) touchAttachInterrupt(T3, callback, Threshold);

T3에서 값을 읽을 때(GPIO 15) 에 설정된 값보다 낮습니다. 한계점 변수, ESP32가 깨어나고 콜백 기능이 실행됩니다.

NS 콜백() 기능은 ESP32가 깨어 있는 경우에만 실행됩니다.

  • ESP32가 잠자기 상태이고 T3를 터치하면 ESP가 깨어납니다. 콜백() 터치 핀을 눌렀다 떼기만 하면 기능이 실행되지 않습니다.
  • ESP32가 깨어 있고 T3를 터치하면 콜백 기능이 실행됩니다. 따라서 실행하려는 경우콜백() ESP32를 깨울 때 기능이 실행될 때까지 잠시 동안 해당 핀을 누르고 있어야 합니다.

이 경우 콜백() 함수가 비어 있습니다.

void callback(){ //placeholder callback function }

다른 터치 핀을 사용하여 ESP32를 깨우려면 해당 핀에 인터럽트를 연결하기만 하면 됩니다.

 

다음으로 다음을 사용해야 합니다. esp_sleep_enable_touchpad_wakeup() 터치 핀을 깨우기 소스로 설정하는 기능입니다.

//Configure Touchpad as wakeup source esp_sleep_enable_touchpad_wakeup()

개략도

이 예를 테스트하려면 케이블을 GPIO 15, 아래 회로도와 같이.

(이 회로도는 30개의 GPIO가 있는 ESP32 DEVKIT V1 모듈 버전을 사용합니다. 다른 모델을 사용하는 경우 사용 중인 보드의 핀 배치를 확인하십시오.)

예제 테스트

코드를 ESP32에 업로드하고 115200의 전송 속도로 직렬 모니터를 엽니다.

 

ESP32는 깊은 절전 모드로 들어갑니다.

Touch Pin 3에 연결된 선을 터치하여 깨울 수 있습니다.

핀을 터치하면 ESP32가 직렬 모니터에 부팅 번호, 깨우기 원인 및 GPIO 터치가 감지된 위치를 표시합니다.

 

외부 깨우기

타이머와 터치 핀 외에도 버튼을 누르는 것처럼 핀의 신호 값을 토글하여 ESP32를 깊은 절전 모드에서 깨울 수도 있습니다. 이것을 외부 깨우기라고 합니다. 외부 깨우기의 두 가지 가능성이 있습니다: ext0 및 ext1.

외부 깨우기(ext0)

이 깨우기 ​​소스를 사용하면 핀을 사용하여 ESP32를 깨울 수 있습니다.

 

ext0 웨이크업 소스 옵션은 RTC GPIO를 사용하여 웨이크업합니다. 따라서 이 깨우기 ​​소스가 요청되면 RTC 주변 장치는 깊은 잠자기 동안 계속 켜져 있습니다.

이 깨우기 ​​소스를 사용하려면 다음 기능을 사용합니다.

esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)

이 함수는 사용하려는 핀을 이 형식의 첫 번째 인수로 받아들입니다. 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 > 딥 슬립 > 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 <cherukupallip@gmail.com> */ #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 }

원시 코드 보기

이 예는 트리거할 때 ESP32를 깨웁니다. GPIO 33높은. 코드 예제는 ext0과 ext1의 두 가지 방법을 모두 사용하는 방법을 보여줍니다. 코드를 그대로 업로드하면 ext0을 사용하게 됩니다. ext1을 사용할 함수가 주석 처리되어 있습니다. 두 가지 방법의 작동 방식과 사용 방법을 보여드리겠습니다.

이 코드는 이 기사의 이전 코드와 매우 유사합니다. 에서설정(), 직렬 통신을 초기화하여 시작합니다.

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

그런 다음 1을 증가시킵니다. 부팅 횟수 변수를 입력하고 직렬 모니터에서 해당 변수를 인쇄합니다.

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

다음으로 다음을 사용하여 깨우기 이유를 인쇄합니다. print_wakeup_reason() 앞서 정의한 함수.

 

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

그런 다음 깨우기 소스를 활성화해야 합니다. 우리는 각각의 깨우기 소스, ext0 및 ext1을 개별적으로 테스트할 것입니다.

내선0

이 예에서 ESP32는 GPIO 33 높음으로 트리거됩니다.

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

대신에 GPIO 33, 다른 RTC GPIO 핀을 사용할 수 있습니다.

개략도

이 예를 테스트하려면 다음 회로도에 따라 푸시버튼을 ESP32에 연결하십시오. 버튼이 연결되어 있습니다.GPIO 33 풀다운 10K Ohm 저항을 사용합니다.

(이 회로도는 30개의 GPIO가 있는 ESP32 DEVKIT V1 모듈 버전을 사용합니다. 다른 모델을 사용하는 경우 사용 중인 보드의 핀 배치를 확인하십시오.)

참고: RTC GPIO만 깨우기 소스로 사용할 수 있습니다. GPIO 33 대신 RTC GPIO 핀을 사용하여 버튼을 연결할 수도 있습니다.

예제 테스트

이 예제를 테스트해 보겠습니다. ESP32에 예제 코드를 업로드합니다. 올바른 보드와 COM 포트를 선택했는지 확인하십시오. 115200의 전송 속도로 직렬 모니터를 엽니다.

푸시버튼을 눌러 ESP32를 깨우십시오.

이것을 여러 번 시도하고 각 버튼을 누를 때마다 증가하는 부팅 횟수를 확인하십시오.

이 방법을 사용하면 예를 들어 특정 작업을 수행하기 위해 푸시 버튼을 사용하여 ESP32를 깨우는 데 유용합니다. 그러나 이 방법을 사용하면 하나의 GPIO만 깨우기 소스로 사용할 수 있습니다.

다른 버튼을 원하고 모든 버튼이 ESP를 깨우지만 다른 작업을 수행하려면 어떻게 해야 할까요? 이를 위해서는 ext1 메소드를 사용해야 합니다.

내선1

ext1을 사용하면 다른 버튼을 사용하여 ESP를 깨우고 누른 버튼에 따라 다른 작업을 수행할 수 있습니다.

를 사용하는 대신 esp_sleep_enable_ext0_wakeup() 기능, 당신은 esp_sleep_enable_ext1_wakeup()함수. 코드에서 해당 함수는 다음과 같이 주석 처리됩니다.

//If you were to use ext1, you would use it like //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 비트마스크를 얻으려면 다음 단계를 따르세요.

  1. 2^(GPIO_NUMBER)를 계산합니다. 결과를 십진수로 저장하십시오.
  2. Rapidtables.com/convert/number/decimal-to-hex.html  이동 하여 10진수를 16진수로 변환합니다.
  3. 에서 얻은 16진수를 바꿉니다. BUTTON_PIN_BITMASK 변하기 쉬운.

단일 GPIO용 마스크

GPIO 비트마스크를 가져오는 방법을 이해하기 위해 예제를 살펴보겠습니다. 라이브러리의 코드에서 버튼은GPIO 33. 마스크를 받으려면GPIO 33:

1. 2^33을 계산합니다. 당신은 가야  8589934592을 ;

2. 해당 숫자(8589934592)를 16진수로 변환합니다. 이 변환기  이동하여 다음 을 수행 할 수 있습니다 .

3. 16진수 번호를 BUTTON_PIN_BITMASK 변수이며 다음을 얻어야 합니다.

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

여러 GPIO용 마스크

사용하고 싶다면 GPIO 2 그리고 GPIO 15 깨우기 소스로 다음을 수행해야 합니다.

  1. 2^2 + 2^15를 계산합니다. 당신은 32772를 얻어야합니다
  2. 해당 숫자를 16진수로 변환합니다. 당신은 얻을 것이다: 8004
  3. 에서 해당 번호를 교체하십시오. BUTTON_PIN_BITMASK 다음과 같이:

#define BUTTON_PIN_BITMASK 0x8004

깨우기 소스로 사용되는 GPIO 식별

여러 핀을 사용하여 ESP32를 깨울 때 어떤 핀이 깨우기를 일으켰는지 아는 것이 유용합니다. 이를 위해 다음 기능을 사용할 수 있습니다.

esp_sleep_get_ext1_wakeup_status()

이 함수는 GPIO 수를 지수로 사용하여 밑이 2인 수를 반환합니다: 2^(GPIO). 따라서 GPIO를 십진수로 얻으려면 다음 계산을 수행해야 합니다.

GPIO = log(RETURNED_VALUE)/log(2)

외부 깨우기 – 다중 GPIO

이제 다른 버튼을 사용하여 ESP32를 깨우고 어떤 버튼이 깨우기를 일으켰는지 식별할 수 있어야 합니다. 이 예에서 우리는GPIO 2 그리고 GPIO 15 깨우기 소스로.

개략도

두 개의 버튼을 ESP32에 연결합니다. 이 예에서 우리가 사용하는GPIO 2 그리고 GPIO 15, 그러나 모든 RTC GPIO에 버튼을 연결할 수 있습니다.

 

암호

이전에 사용한 예제 코드를 약간 수정해야 합니다.

  • 사용할 비트마스크 생성 GPIO 15 그리고 GPIO 2. 이전에 이 작업을 수행하는 방법을 보여주었습니다.
  • 웨이크 업 소스로 ext1을 활성화합니다.
  • 사용 esp_sleep_get_ext1_wakeup_status() 깨우기를 트리거한 GPIO를 가져오는 함수입니다.

다음 스케치에는 이러한 모든 변경 사항이 구현되어 있습니다.

/* 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 <cherukupallip@gmail.com> */ #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 }

원시 코드 보기

코드 시작 부분에서 GPIO 마스크를 정의합니다.

#define BUTTON_PIN_BITMASK 0x8004 // GPIOs 2 and 15

깨우기를 일으킨 GPIO를 인쇄하는 함수를 만듭니다.

void print_GPIO_wake_up(){ int 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); }

마지막으로 ext1을 깨우기 소스로 활성화합니다.

esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

스케치 테스트

두 개의 버튼이 연결된 상태에서 GPIO 2 그리고 GPIO 15, ESP32에 제공된 코드를 업로드할 수 있습니다. 올바른 보드와 COM 포트를 선택했는지 확인하십시오.

ESP32는 현재 최대 절전 모드에 있습니다. 푸시 버튼을 눌러 깨울 수 있습니다.

직렬 모니터를 115200의 전송 속도로 엽니다. 푸시 버튼을 눌러 ESP32를 깨우십시오.

직렬 모니터에서 비슷한 것을 얻어야 합니다.

마무리

이 기사에서 우리는 ESP32와 함께 깊은 잠을 사용하는 방법과 그것을 깨우는 다양한 방법을 보여주었습니다. 타이머, 터치 핀 또는 GPIO 상태 변경을 사용하여 ESP32를 깨울 수 있습니다.

각 깨우기 소스에 대해 본 내용을 요약해 보겠습니다.

타이머 깨우기

  • 타이머 깨우기를 활성화하려면 esp_sleep_enable_timer_wakeup(time_in_us) 함수;
  • 사용 esp_deep_sleep_start() 깊은 수면을 시작하는 기능.

터치 깨우기

  • 터치 핀을 깨우기 소스로 사용하려면 먼저 다음을 사용하여 터치 핀에 인터럽트를 연결해야 합니다. touchAttachInterrupt(터치핀, 콜백, 임계값)
  • 그런 다음 다음을 사용하여 터치 핀을 깨우기 소스로 활성화합니다. esp_sleep_enable_touchpad_wakeup()
  • 마지막으로, 당신은 esp_deep_sleep_start() ESP32를 깊은 절전 모드로 전환하는 기능.

외부 깨우기

  • RTC GPIO는 외부 깨우기로만 사용할 수 있습니다.
  • 두 가지 다른 방법을 사용할 수 있습니다: ext0 및 ext1;
  • ext0을 사용하면 단일 GPIO 핀을 사용하여 ESP32를 깨울 수 있습니다.
  • ext1을 사용하면 여러 GPIO 핀을 사용하여 ESP32를 깨울 수 있습니다.

이 가이드가 유용했기를 바랍니다. ESP32에 대해 자세히 알아보려면 모든 ESP32 프로젝트  ESP32 과정 을 확인하세요 .

이것은 우리 과정에서 발췌한 것입니다: Arduino IDE로 ESP32 배우기 . ESP32가 마음에 들고 더 자세히 알고 싶다면 Arduino IDE로 ESP32 배우기 과정에 등록하는 것이 좋습니다  .