본문 바로가기

ESP32

ESP32 웨이크업 소스를 사용한 Deep Sleep

반응형

 

ESP32 웨이크업 소스를 사용한 Deep Sleep

 

이 문서는 Arduino IDE를 사용한 ESP32 딥 슬립 모드에 대한 완전한 가이드입니다. ESP32를 딥 슬립 모드로 전환하는 방법을 보여주고 타이머 웨이크업, 터치 웨이크업, 외부 웨이크업 등 다양한 웨이크업 모드를 살펴보겠습니다. 이 가이드는 코드, 코드 설명, 회로도를 사용한 실제 예를 제공합니다.

 

 

ESP32 딥 슬립 및 웨이크업 소스

 

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

 

이 문서는 4개의 다른 부분으로 구성되어 있습니다.

 

1. 딥 슬립 모드 소개

2. 타이머 웨이크업

3. 터치 웨이크업

4. 외부 웨이크업

 

딥 슬립 모드 소개

ESP32는 다양한 전원 모드로 전환할 수 있습니다.

 

  • 활성 모드 Active mode
  • 모뎀 슬립 모드 Modem Sleep mode
  • 라이트 슬립 모드 Light Sleep mode
  • 딥 슬립 모드 Deep Sleep mode
  • 최대 절전 모드 Hibernation mode

 

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

 

전력 소비 esp32

 

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

 

esp32 다양한 절전 모드

 

그리고 여기에 활성 모드에서의 전력 소비를 비교하는 표 10이 있습니다.

 

활성 모드에서의 esp32 전력 소비

 

왜 딥 슬립 모드인가?

 

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

 

 

ESP32를 딥 슬립 모드로 전환하면 전력 소비가 줄어들고 배터리가 더 오래 지속됩니다.

 

ESP32를 딥 슬립 모드로 전환하면 작동 중에 더 많은 전력을 소모하는 활동을 중단하고 흥미로운 일이 발생하면 프로세서를 깨울 수 있을 만큼의 활동만 남겨둡니다.

 

딥 슬립 모드에서는 CPU나 Wi-Fi 활동이 발생하지 않지만 초저전력(ULP) 코프로세서는 계속 전원을 켤 수 있습니다.

 

ESP32가 딥 슬립 모드에 있는 동안 RTC 메모리도 계속 켜져 있으므로 ULP 코프로세서에 대한 프로그램을 작성하여 RTC 메모리에 저장하여 주변 장치, 내부 타이머 및 내부 센서에 액세스할 수 있습니다.

 

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

 

RTC_GPIO 핀

 

딥 슬립 동안 일부 ESP32 핀은 ULP 코프로세서에서 사용할 수 있습니다. 즉, RTC_GPIO 핀과 터치 핀입니다. ESP32 데이터시트에는 RTC_GPIO 핀을 식별하는 표가 있습니다. 이 표는 아래 첨부 자료의 14페이지에서 찾을 수 있습니다.

 

esp32_datasheet_en.pdf
0.99MB

 

 

이 표를 참조로 사용하거나 다음 핀아웃을 살펴보고 다른 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를 열고 파일 > 예제 > ESP32 딥 슬립으로 가서 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 1000000ULL /* 마이크로초에서 초로 변환하는 계수 */

#define TIME_TO_SLEEP 5 /* ESP32가 절전 모드로 전환되는 시간(초) */

 

이 예제에서는 마이크로초에서 초로 변환하는 계수를 사용하므로 TIME_TO_SLEEP 변수에서 절전 모드를 초 단위로 설정할 수 있습니다. 이 경우, 이 예제는 ESP32를 5초 동안 딥 슬립 모드로 전환합니다.

 

RTC 메모리에 데이터 저장

 

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

 

RTC 메모리에 데이터를 저장하려면 변수 정의 앞에 RTC_DATA_ATTR을 추가하기만 하면 됩니다. 이 예제는 RTC 메모리에 bootCount 변수를 저장합니다. 이 변수는 ESP32가 딥 슬립에서 깨어난 횟수를 계산합니다.

 

RTC_DATA_ATTR int bootCount = 0;

 

웨이크업 이유

 

그런 다음 코드는 딥 슬립에서 웨이크업을 일으킨 소스를 인쇄하는 print_wakeup_reason() 함수를 정의합니다.

 

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;
  }
}

 

setup()

 

setup()에 코드를 넣어야 합니다. esp_deep_sleep_start() 함수를 호출하기 전에 모든 명령어를 작성해야 합니다.

 

 

이 예제는 115200의 보드율로 직렬 통신을 초기화하는 것으로 시작합니다.

 

Serial.begin(115200);

 

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

 

++bootCount;

Serial.println("부팅 번호: " + 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);

 

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

 

esp_deep_sleep_start()

 

esp_deep_sleep_start() 함수를 호출하자마자 ESP32는 절전 모드로 전환되고 이 함수 이후에 작성된 코드는 실행되지 않습니다. 절전 모드에서 깨어나면 처음부터 코드를 실행합니다.

 

loop()

 

loop() 섹션은 ESP32가 코드의 이 부분에 도달하기 전에 절전 모드로 전환되기 때문에 비어 있습니다. 따라서 esp_deep_sleep_start() 함수를 호출하기 전에 setup()에 모든 작업을 작성해야 합니다.

 

타이머 웨이크업 테스트

 

예제 스케치를 ESP32에 업로드합니다. 올바른 보드와 COM 포트를 선택했는지 확인하세요. 시리얼 모니터를 115200의 전송 속도로 엽니다.

 

5초마다 ESP32가 깨어나 시리얼 모니터에 메시지를 인쇄한 후 다시 깊은 절전 모드로 전환됩니다.

 

ESP32가 깨어날 때마다 bootCount 변수가 증가합니다. 또한 아래 그림과 같이 깨어난 이유를 인쇄합니다.

 

ESP32 타이머 깨우기 데모

 

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

 

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

 

터치 깨우기

 

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

 

 

터치 웨이크업

 

터치 웨이크업 활성화

 

터치핀을 사용하여 ESP32를 웨이크업하도록 활성화하는 것은 간단합니다. Arduino IDE에서 다음 함수를 사용해야 합니다. 터치핀과 터치 임계값을 인수로 전달합니다.

 

touchSleepWakeUpEnable(TOUCH_PIN, THRESHOLD);

 

코드

 

라이브러리의 예제를 사용하여 이것이 어떻게 작동하는지 살펴보겠습니다. Arduino IDE를 열고 파일 > 예제 > ESP32 딥 슬립으로 이동하여 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 <cherukupallip@gmail.com>
*/

#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
}

 

임계값 설정

 

먼저 해야 할 일은 터치핀에 대한 임계값을 설정하는 것입니다.

 

#define THRESHOLD 40 // 값이 클수록 감도가 높아집니다

 

. 터치핀을 터치하면 터치핀에서 읽은 값이 감소합니다. 임계값은 터치핀에서 읽은 값이 40 미만일 때 ESP32가 웨이크업됨을 의미합니다. 원하는 감도에 따라 해당 값을 조정할 수 있습니다.

 

중요: 그러나 ESP32-S2 또는 ESP32-S3 모델을 사용하는 경우 약간 다르게 작동합니다.

 

그래서 코드에 다른 섹션이 있어서 해당 보드에 대해 다른 임계값을 정의합니다. 이 경우 값이 낮을수록 민감도가 높아집니다.

 

#if CONFIG_IDF_TARGET_ESP32
#define THRESHOLD 40 // 값이 클수록 민감도가 높아집니다.
#else // ESP32-S2 및 ESP32-S3 + 다른 칩의 기본값(조정됨)
#define THRESHOLD 5000 // 값이 낮을수록 민감도가 높아집니다.
#endif

 

터치 핀을 웨이크업 소스로 설정

 

터치 핀을 웨이크업 소스로 설정하려면 touchSleepWakeUpEnable() 함수를 사용하면 됩니다. 이 함수는 터치 핀과 보드를 웨이크업할 임계값을 인수로 받습니다.

 

이 예제에서는 GPIO 15(T3)와 GPIO 27(T7)을 동일한 임계값을 가진 웨이크업 소스로 설정합니다.

 

#if CONFIG_IDF_TARGET_ESP32
  // Setup sleep wakeup on Touch Pad 3 + 7 (GPIO15 + GPIO 27)
  touchSleepWakeUpEnable(T3, THRESHOLD);
  touchSleepWakeUpEnable(T7, THRESHOLD);

 

 

ESP32-S2 또는 S3 모델을 사용하는 경우 이 예제에서는 GPIO 3(T3)에서 웨이크업만 정의합니다. 터치 핀 번호는 사용하는 보드 모델에 따라 다를 수 있습니다.

 

#else // ESP32-S2 + ESP32-S3
  // Setup sleep wakeup on Touch Pad 3 (GPIO3)
  touchSleepWakeUpEnable(T3, THRESHOLD);

 

마지막으로 esp_deep_sleep_start()를 호출하여 ESP32를 딥 슬립 모드로 전환합니다.

 

esp_deep_sleep_start();

 

이는 터치 핀을 웨이크업 소스로 설정하는 일반적인 지침입니다. 이제 코드의 다른 섹션을 살펴보겠습니다.

 

setup()

 

ESP32가 슬립에서 깨어나면 esp_deep_sleep_start() 함수를 찾을 때까지 처음부터 코드를 실행합니다.

 

이 특정 예에서는 ESP32가 깨어난 횟수를 알 수 있도록 각 슬립 사이클 사이에 증가할 bootCount라는 제어 변수가 있습니다.

 

// 부팅 번호를 증가시키고 재부팅할 때마다 출력
++bootCount;
Serial.println("Boot number: " + String(bootCount));

 

또한 코드에서 앞서 정의한 print_wakeup_reason() 및 print_wakeup_touchpad() 함수를 호출하여 웨이크업 이유와 웨이크업을 발생시킨 핀을 출력합니다.

 

// ESP32 및 터치패드의 웨이크업 이유도 출력

print_wakeup_reason();

print_wakeup_touchpad();

 

회로 배선

 

이 예제를 테스트하려면 아래 회로도에 표시된 대로 GPIO 15에 케이블을 연결합니다.

 

터치 웨이크업 신호 회로 배선

 

ESP32-S2 또는 ESP32-S3 모델을 사용하는 경우 터치 핀의 위치를 ​​확인하세요.

 

예제 테스트

 

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

 

ESP32가 딥 슬립 모드로 전환됩니다.

 

터치 핀 3에 연결된 전선을 터치하면 깨울 수 있습니다.

 

 

ESP32 터치 센서 핀 Arduino IDE

 

핀을 터치하면 ESP32가 직렬 모니터에 부팅 번호, 깨우기 원인, 어느 터치 감지 GPIO가 깨우기를 일으켰는지 표시합니다.

 

ESP32 터치 핀을 깨우기 소스로 테스트하기 직렬 모니터 데모

 

외부 깨우기

 

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

 

외부 깨우기

 

 

외부 깨우기(ext0)

 

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

 

ext0 깨우기 소스 옵션은 RTC GPIO를 사용하여 깨웁니다. 따라서 이 웨이크업 소스가 요청되면 RTC 주변 장치는 딥 슬립 동안 계속 켜집니다.

 

이 웨이크업 소스를 사용하려면 다음 함수를 사용합니다.

 

esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)

 

이 함수는 첫 번째 인수로 사용하려는 핀을 수락합니다. 이 형식은 GPIO_NUM_X이며, 여기서 X는 해당 핀의 GPIO 번호를 나타냅니다.

 

두 번째 인수인 level은 1 또는 0일 수 있습니다. 이는 웨이크업을 트리거하는 GPIO의 상태를 나타냅니다.

 

참고: 이 웨이크업 소스에서는 RTC GPIO인 핀만 사용할 수 있습니다.

 

외부 웨이크업(ext1)

 

RTC 컨트롤러. 따라서 이 모드에서는 RTC 주변 장치와 RTC 메모리의 전원을 끌 수 있습니다.

 

이 웨이크업 소스를 사용하려면 다음 함수를 사용합니다.

 

esp_sleep_enable_ext1_wakeup_io(bitmask, mode);

 

이 함수는 두 개의 인수를 허용합니다.

 

웨이크업을 발생시키는 GPIO 번호의 비트마스크;

모드: ESP32를 웨이크업하는 로직입니다. 다음과 같습니다.

  • ESP_EXT1_WAKEUP_ALL_LOW: 모든 GPIO가 낮아지면 웨이크업합니다.
  • ESP_EXT1_WAKEUP_ANY_HIGH: GPIO 중 하나가 높아지면 웨이크업합니다.

 

ESP32-S2, ESP32-S3, ESP32-C6 또는 ESP32-H2를 사용하는 경우 사용 가능한 모드는 다음과 같습니다.

 

  • ESP_EXT1_WAKEUP_ANY_LOW: 선택한 GPIO 중 하나가 낮아지면 웨이크업합니다.
  • ESP_EXT1_WAKEUP_ANY_HIGH: 선택한 GPIO 중 하나가 높아지면 웨이크업합니다.

 

참고: RTC GPIO인 핀만 사용할 수 있습니다.

 

ext1 딥 슬립 웨이크업 소스에 대한 모든 세부 정보는 Espressif 딥 슬립 문서를 참조하세요.

 

y는 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>
*/
#include "driver/rtc_io.h"

#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO)  // 2 ^ GPIO_NUMBER in hex
#define USE_EXT0_WAKEUP          1               // 1 = EXT0 wakeup, 0 = EXT1 wakeup
#define WAKEUP_GPIO              GPIO_NUM_33     // Only RTC IO are allowed - ESP32 Pin example
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 does not need
    peripherals to be powered on.
    Note that using internal pullups/pulldowns also requires
    RTC peripherals to be turned on.
  */
#if USE_EXT0_WAKEUP
  esp_sleep_enable_ext0_wakeup(WAKEUP_GPIO, 1);  //1 = High, 0 = Low
  // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
  // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
  // No need to keep that power domain explicitly, unlike EXT1.
  rtc_gpio_pullup_dis(WAKEUP_GPIO);
  rtc_gpio_pulldown_en(WAKEUP_GPIO);

#else  // EXT1 WAKEUP
  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup_io(BUTTON_PIN_BITMASK(WAKEUP_GPIO), ESP_EXT1_WAKEUP_ANY_HIGH);
  /*
    If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO
         during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will
         increase some power comsumption. However, if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH
         domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep.
  */
  rtc_gpio_pulldown_en(WAKEUP_GPIO);  // GPIO33 is tie to GND in order to wake up in HIGH
  rtc_gpio_pullup_dis(WAKEUP_GPIO);   // Disable PULL_UP in order to allow it to wakeup on HIGH
#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 is not going to be called
}

 

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

 

코드를 간단히 살펴보겠습니다.

 

RTC 메모리에 데이터 저장

 

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

 

RTC 메모리에 데이터를 저장하려면 변수 정의 앞에 RTC_DATA_ATTR을 추가하기만 하면 됩니다. 이 예에서는 RTC 메모리에 bootCount 변수를 저장합니다. 이 변수는 ESP32가 딥 슬립에서 깨어난 횟수를 계산합니다.

 

RTC_DATA_ATTR int bootCount = 0;

 

웨이크업 이유

그런 다음 코드는 ESP32가 슬립에서 깨어난 이유를 출력하는 print_wakeup_reason() 함수를 정의합니다.

 

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;
  }
}

 

 

setup()

 

setup()에서 직렬 통신을 초기화하는 것으로 시작합니다.

 

Serial.begin(115200);

delay(1000); // 직렬 모니터를 여는 데 시간을 들이세요

 

그런 다음 bootCount 변수에 1을 증가시키고 직렬 모니터에 해당 변수를 출력합니다.

 

++bootCount;

Serial.println("부팅 번호: " + String(bootCount));

 

다음으로, 앞서 정의한 print_wakeup_reason() 함수를 사용하여 웨이크업 이유를 출력합니다.

 

// ESP32의 웨이크업 이유 출력

print_wakeup_reason();

 

그 다음, 웨이크업 소스를 활성화해야 합니다. 각 웨이크업 소스인 ext0과 ext1을 개별적으로 테스트합니다.

 

ext0

 

이 예에서 ESP32는 GPIO 33이 하이로 트리거되면 웨이크업합니다.

 

esp_sleep_enable_ext0_wakeup(WAKEUP_GPIO, 1); // 1 = 하이, 0 = 로우

 

GPIO 33 대신 다른 RTC GPIO 핀을 사용할 수 있습니다. 코드 시작 부분에 있는 WAKEUP_GPIO 변수에 정의하기만 하면 됩니다.

 

#define WAKEUP_GPIO GPIO_NUM_33 // RTC IO만 허용

 

내부 풀업 및 풀다운 저항

 

다음 두 줄도 호출합니다.

 

rtc_gpio_pullup_dis(WAKEUP_GPIO);

rtc_gpio_pulldown_en(WAKEUP_GPIO);

 

rtc_gpio_pullup_dis() 함수는 웨이크업 GPIO에서 내부 풀업 저항을 비활성화합니다. 핀이 의도치 않게 높게 유지되지 않도록 합니다. 이는 풀업 저항이 핀을 높게 유지하여 의도치 않은 웨이크업을 일으킬 수 있기 때문에 중요합니다.

 

rtc_gpio_pulldown_en() 함수는 웨이크업 GPIO에서 내부 풀다운 저항을 활성화합니다. 유효한 웨이크업 신호(HIGH)가 수신될 때까지 핀이 낮게 유지되도록 합니다. 풀다운 저항으로 핀을 구성하면 딥 슬립 중에도 안정적으로 낮은 상태를 유지하도록 합니다. 이러한 안정성은 지정된 GPIO 핀이 esp_sleep_enable_ext0_wakeup(WAKEUP_GPIO, 1)에서 설정한 웨이크업 조건과 일치하는 외부 하이 신호를 수신할 때만 ESP32가 깨어나도록 보장합니다.

 

회로 배선

 

이 예제를 테스트하려면 다음 회로도에 따라 푸시 버튼을 ESP32에 배선합니다. 버튼은 풀다운 10KΩ 저항을 사용하여 GPIO 33에 연결됩니다.

 

GPIO 333에 연결된 ESP32 푸시 버튼

 

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

 

예제 테스트

 

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

 

푸시 버튼을 눌러 ESP32를 깨웁니다.

 

ESP32 Deep Sleep External Wake Up with Pushbutton

 

이 방법을 여러 번 시도하고 버튼을 누를 때마다 부팅 횟수가 증가하는지 확인하세요.

 

ESP32 테스트 exterbak 웨이크업

 

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

 

다른 버튼을 사용하여 모든 버튼이 ESP를 웨이크업하지만 다른 작업을 수행하려면 어떻게 해야 할까요?

 

ext1의 경우

 

ext1 웨이크업 소스를 사용하면 다른 GPIO를 사용하여 ESP32를 웨이크업하고 웨이크업을 발생시킨 GPIO에 따라 다른 작업을 수행할 수 있습니다.

 

esp_sleep_enable_ext0_wakeup() 함수를 사용하는 대신 esp_sleep_enable_ext1_wakeup_io() 함수를 사용합니다.

 

esp_sleep_enable_ext1_wakeup_io(BUTTON_PIN_BITMASK(WAKEUP_GPIO), ESP_EXT1_WAKEUP_ANY_HIGH);

 

이 특정 예에서 코드의 해당 부분을 실행하려면 다음과 같이 코드 시작 부분에서 USE_EXT0_WAKEUP 변수를 0으로 설정해야 합니다.

 

#define USE_EXT0_WAKEUP 0 // 1 = EXT0 wakeup, 0 = EXT1 wakeup

 

esp_sleep_enable_ext1_wakeup_io() 함수

 

esp_sleep_enable_ext1_wakeup_io() 함수의 첫 번째 인수는 웨이크업 소스로 사용할 GPIO의 비트마스크이고 두 번째 인수는 ESP32를 웨이크업하는 로직을 정의합니다.

 

GPIO 비트마스크

 

GPIO 비트마스크를 정의하려면 코드 시작 부분에 정의된 BUTTON_PIN_BITMASK() 매크로를 사용할 수 있습니다.

 

#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO) // 2 ^ GPIO_NUMBER in hex BUTTON_PIN_BITMASK(GPIO)는 특정 GPIO에 대한 비트마스크를 만드는 매크로입니다. 함수는 아니지만 인수를 허용하고 값을 반환하여 다소 유사하게 동작합니다.

 

따라서 특정 GPIO에 대한 비트마스크를 반환하려면 다음과 같이 호출하면 됩니다.

 

BUTTON_PIN_BITMASK(WAKEUP_GPIO)

 

그러므로 esp_sleep_enable_ext1_wakeup_io()는 다음과 같습니다.

 

esp_sleep_enable_ext1_wakeup_io(BUTTON_PIN_BITMASK(WAKEUP_GPIO), ESP_EXT1_WAKEUP_ANY_HIGH);

 

여러 GPIO에 대한 비트마스크

 

BUTTON_PIN_BITMASK(GPIO) 매크로를 사용하여 여러 GPIO에 대한 비트마스크를 만들려면 비트 OR(|)을 사용하여 각 GPIO 핀에 대한 개별 비트마스크를 결합할 수 있습니다. 다음은 그 방법입니다.

 

GPIO 핀 2와 15에 대한 비트마스크를 만들고 싶다고 가정합니다. 다음과 같이 각 핀에 대한 개별 비트마스크를 결합하여 만들 수 있습니다.

 

uint64_t bitmask = BUTTON_PIN_BITMASK(GPIO_NUM_2) | BUTTON_PIN_BITMASK(GPIO_NUM_15);

 

다음에는 여러 GPIO를 웨이크업 소스로 사용하는 예를 살펴보겠습니다.

 

웨이크업 모드

 

esp_sleep_enable_ext1_wakeup_io() 함수의 두 번째 인수는 웨이크업 모드입니다. 이전에 살펴본 것처럼 옵션은 다음과 같습니다.

 

  • ESP_EXT1_WAKEUP_ALL_LOW: 모든 GPIO가 낮아지면 웨이크업합니다.
  • ESP_EXT1_WAKEUP_ANY_HIGH: GPIO 중 하나가 높아지면 웨이크업합니다.

 

ESP32-S2, ESP32-S3, ESP32-C6 또는 ESP32-H2를 사용하는 경우 사용 가능한 모드는 다음과 같습니다.

 

  • ESP_EXT1_WAKEUP_ANY_LOW: 선택한 GPIO 중 하나가 낮을 때 깨어남
  • ESP_EXT1_WAKEUP_ANY_HIGH: 선택한 GPIO 중 하나가 높을 때 깨어남

 

우리의 특정 예에서는 ESP_EXT1_WAKEUP_ANY_HIGH를 사용합니다. 따라서 비트마스크의 GPIO 중 하나가 높을 때 ESP32가 깨어납니다.

 

ext0과 마찬가지로 풀업 내부 저항을 비활성화하고 풀다운 저항을 활성화하여 깨어남 GPIO의 판독 안정성을 보장합니다.

 

외부 깨어남 - 여러 GPIO

 

이제 다양한 버튼을 사용하여 ESP32를 깨우고 어떤 버튼이 깨어남을 일으켰는지 식별할 수 있어야 합니다. 이 예제에서는 GPIO 2와 GPIO 15를 웨이크업 소스로 사용합니다.

 

회로도

 

ESP32에 두 개의 버튼을 연결합니다. 이 예제에서는 GPIO 2와 GPIO 15를 사용하지만 버튼을 모든 RTC GPIO에 연결할 수 있습니다.

 

 

ESP32 두 개의 푸시 버튼을 사용하여 딥 슬립에서 웨이크업

 

여러 GPIO 코드 작성 - 외부 웨이크업

 

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

 

  • GPIO 15와 GPIO 2를 사용하기 위한 비트마스크를 만듭니다. 이 작업을 수행하는 방법은 이전에 보여드렸습니다.
  • ext1을 웨이크업 소스로 활성화합니다.
  • 웨이크업을 발생시킨 GPIO를 식별하는 함수를 만듭니다.

 

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

 

/*  
  Rui Santos & Sara Santos - Random Nerd Tutorials
  https://RandomNerdTutorials.com/learn-esp32-with-arduino-ide/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

#include "driver/rtc_io.h"

#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO)  // 2 ^ GPIO_NUMBER in hex
#define WAKEUP_GPIO_2              GPIO_NUM_2     // Only RTC IO are allowed - ESP32 Pin example
#define WAKEUP_GPIO_15              GPIO_NUM_15     // Only RTC IO are allowed - ESP32 Pin example

// Define bitmask for multiple GPIOs
uint64_t bitmask = BUTTON_PIN_BITMASK(WAKEUP_GPIO_2) | BUTTON_PIN_BITMASK(WAKEUP_GPIO_15);

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the GPIO that triggered the wakeup
*/
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);
}

/*
  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");
      print_GPIO_wake_up();
      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();

  //Use ext1 as a wake-up source
  esp_sleep_enable_ext1_wakeup_io(bitmask, ESP_EXT1_WAKEUP_ANY_HIGH);
  // enable pull-down resistors and disable pull-up resistors
  rtc_gpio_pulldown_en(WAKEUP_GPIO_2);
  rtc_gpio_pullup_dis(WAKEUP_GPIO_2);
  rtc_gpio_pulldown_en(WAKEUP_GPIO_15);
  rtc_gpio_pullup_dis(WAKEUP_GPIO_15);

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

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

 

코드는 어떻게 작동합니까?

 

코드의 작동 방식을 간단히 살펴보겠습니다.

 

GPIO 비트마스크

 

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

 

#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO)  // 2 ^ GPIO_NUMBER in hex
#define WAKEUP_GPIO_2           GPIO_NUM_2       // Only RTC IO are allowed - 
#define WAKEUP_GPIO_15          GPIO_NUM_15      // Only RTC IO are allowed 

// Define bitmask for multiple GPIOs
uint64_t bitmask = BUTTON_PIN_BITMASK(WAKEUP_GPIO_2) | BUTTON_PIN_BITMASK(WAKEUP_GPIO_15);

 

웨이크업을 유발한 GPIO 식별

 

웨이크업을 유발한 GPIO를 출력하는 print_GPIO_wake_up()이라는 함수를 생성합니다.

 

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);
}

 

esp_sleep_get_ext1_wakeup_status() 함수는 웨이크업을 유발한 GPIO가 포함된 비트마스크를 반환합니다. GPIO 번호는 다음과 같이 얻을 수 있습니다.

 

log(GPIO_reason))/log(2)

 

Wake-Up 이유 인쇄

 

Wake-up 소스가 ext1일 때 wake-up을 발생시킨 GPIO를 인쇄하도록 print_wakeup_reason() 함수를 수정했습니다.

 

case ESP_SLEEP_WAKEUP_EXT1:
  Serial.println("Wakeup caused by external signal using RTC_CNTL");
  print_GPIO_wake_up();
  break;

 

ext1을 Wake-Up 소스로 활성화

 

GPIO 비트마스크와 wake-up 모드를 전달하여 ext1을 wake-up 소스로 활성화합니다.

 

esp_sleep_enable_ext1_wakeup_io(bitmask, ESP_EXT1_WAKEUP_ANY_HIGH);

 

내부 풀업 저항을 비활성화하고 wake-up 소스로 사용되는 GPIO에서 풀다운 저항을 활성화하는 것을 잊지 마세요.

 

rtc_gpio_pulldown_en(WAKEUP_GPIO_2);
rtc_gpio_pullup_dis(WAKEUP_GPIO_2);
rtc_gpio_pulldown_en(WAKEUP_GPIO_15);
rtc_gpio_pullup_dis(WAKEUP_GPIO_15);

 

딥 슬립 활성화

 

마지막으로 esp_deep_sleep_start()를 호출하여 ESP32를 딥 슬립 모드로 전환합니다.

 

esp_deep_sleep_start();

 

스케치 테스트

 

보드에 코드를 업로드한 후 ESP32는 딥 슬립 모드가 됩니다. 푸시 버튼을 눌러 깨울 수 있습니다.

 

ESP32 외부 웨이크업 여러 GPIO

 

115200의 보드 속도로 직렬 모니터를 엽니다. 푸시 버튼을 눌러 ESP32를 깨웁니다. 직렬 모니터에서 웨이크업 이유와 웨이크업을 유발한 GPIO를 볼 수 있습니다.

 

ESP32 외부 웨이크업 여러 GPIO

 

마무리

 

이 문서에서는 ESP32에서 딥 슬립을 사용하는 방법과 깨우는 다양한 방법을 보여드렸습니다. 타이머, 터치 핀 또는 GPIO 상태 변경을 사용하여 ESP32를 깨울 수 있습니다.

 

각 웨이크업 소스에 대해 알아본 내용을 요약해 보겠습니다.

 

타이머 웨이크업

 

  • 타이머 웨이크업을 활성화하려면 esp_sleep_enable_timer_wakeup(time_in_us) 함수를 사용합니다.
  • esp_deep_sleep_start() 함수를 사용하여 딥 슬립을 시작합니다.

 

터치 웨이크업

 

  • 터치 핀을 웨이크업 소스로 활성화하려면 touchSleepWakeUpEnable() 함수를 사용합니다.
  • 마지막으로 esp_deep_sleep_start() 함수를 사용하여 ESP32를 딥 슬립 모드로 전환합니다.

 

외부 웨이크업

 

  • RTC GPIO만 외부 웨이크업으로 사용할 수 있습니다.
  • ext0과 ext1의 두 가지 방법을 사용할 수 있습니다.
  • ext0을 사용하면 단일 GPIO 핀을 사용하여 ESP32를 웨이크업할 수 있습니다.
  • ext1을 사용하면 여러 GPIO 핀을 사용하여 ESP32를 웨이크업할 수 있습니다.

 

이 가이드가 도움이 되었기를 바랍니다. ESP32에 대해 더 알고 싶다면 모든 ESP32 프로젝트와 ESP32 eBook을 확인하세요.

 

이것은 저희 과정인 Arduino IDE로 ESP32 배우기에서 발췌한 것입니다. ESP32를 좋아하고 더 자세히 알고 싶다면 Arduino IDE로 ESP32 배우기 과정에 등록하는 것이 좋습니다. 

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^