ESP32를 Deep Sleep Mode에서 터치 핀을 사용하여 깨우는 방법을 알아보겠습니다.
Touch Wake Up
Touch Wake Up 활성화
touchSleepWakeUpEnable(TOUCH_PIN, THRESHOLD);
코드
Arduino IDE를 열고, File > Examples > ESP32 Deep Sleep로 이동하여 TouchWakeUp 스케치를 엽니다.
#if CONFIG_IDF_TARGET_ESP32
#define THRESHOLD 40 /* 값이 클수록 민감도 증가 */
#else //ESP32-S2 및 ESP32-S3 + 다른 칩에 대한 기본값 (조정 필요)
#define THRESHOLD 5000 /* 값이 작을수록 민감도 증가 */
#endif
RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
/*
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;
}
}
/*
ESP32가 수면에서 깨어난 터치패드를 출력하는 메서드
*/
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); // Serial 모니터를 열기 위해 잠시 대기합니다.
// 부트 번호를 증가시키고 매 재부팅 시 출력합니다.
++bootCount;
Serial.println("Boot number: " + String(bootCount));
// ESP32의 웨이크업 원인과 터치패드도 출력합니다.
print_wakeup_reason();
print_wakeup_touchpad();
#if CONFIG_IDF_TARGET_ESP32
// 터치 패드 3 + 7 (GPIO15 + GPIO 27)에서 수면 웨이크업 설정
touchSleepWakeUpEnable(T3, THRESHOLD);
touchSleepWakeUpEnable(T7, THRESHOLD);
#else //ESP32-S2 + ESP32-S3
// 터치 패드 3 (GPIO3)에서 수면 웨이크업 설정
touchSleepWakeUpEnable(T3, THRESHOLD);
#endif
// 이제 잠에 들어갑니다.
Serial.println("Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop() {
// 이 함수는 호출되지 않습니다.
}
임계값 설정
터치 핀의 임계값을 설정합니다.
#if CONFIG_IDF_TARGET_ESP32
#define THRESHOLD 40 /* 값이 클수록 민감도 증가 */
#else //ESP32-S2 및 ESP32-S3 + 다른 칩에 대한 기본값 (조정 필요)
#define THRESHOLD 5000 /* 값이 작을수록 민감도 증가 */
#endif
터치 핀에서 읽은 값은 터치할 때 감소합니다. 임계값은 터치 핀에서 읽은 값이 40 이하일 때 ESP32가 깨어나도록 설정합니다.
원하는 민감도에 따라 이 값을 조정할 수 있습니다.
중요: ESP32-S2 또는 ESP32-S3 모델을 사용하는 경우, 방식이 약간 다르게 작동합니다. 그래서 코드에서 이 보드를 위한 다른 임계값을 정의하는 섹션이 있습니다. 이 경우, 값이 낮을수록 민감도가 증가합니다.
Wake Up 터치 핀 설정
터치 핀을 웨이크업 소스로 설정하려면, 터치 핀과 보드를 깨우는 임계값을 인수로 받아들이는 touchSleepWakeUpEnable() 함수를 사용할 수 있습니다.
#if CONFIG_IDF_TARGET_ESP32
// 터치 패드 3 + 7 (GPIO15 + GPIO 27)에서 수면 웨이크업 설정
touchSleepWakeUpEnable(T3, THRESHOLD);
touchSleepWakeUpEnable(T7, THRESHOLD);
#else //ESP32-S2 + ESP32-S3
// 터치 패드 3 (GPIO3)에서 수면 웨이크업 설정
touchSleepWakeUpEnable(T3, THRESHOLD);
#endif
GPIO 15 (T3)와 GPIO 27 (T7)을 동일한 임계값으로 웨이크업 소스로 설정합니다.
bootCount: RTC(Real-Time Clock) 메모리에 저장되는 부트 카운터로, ESP32가 재부팅될 때마다 증가합니다.
touchPin: 터치패드의 상태를 저장하는 변수입니다.
RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
웨이크업 원인 출력 함수:
esp_sleep_get_wakeup_cause() 함수를 호출하여 ESP32가 깨어난 원인을 가져옵니다.
switch 문을 사용하여 각 원인에 대해 적절한 메시지를 출력합니다. 예를 들어, 외부 신호, 타이머, 터치패드, ULP(ultra-low power) 프로그램 등으로 깨어날 수 있습니다.
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;
}
}
터치패드 웨이크업 상태 출력 함수:
esp_sleep_get_touchpad_wakeup_status()를 호출하여 터치패드의 상태를 확인합니다.
ESP32의 경우 switch 문을 사용하여 특정 GPIO 핀에서 감지된 터치를 출력합니다. 다른 ESP32 버전에서는 범위를 확인하여 터치 감지가 이루어졌는지 확인합니다.
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
}
초기화 함수:
Serial 통신을 시작하고, 1초 지연 후 Serial 모니터를 열기 위한 대기 시간을 설정합니다.
void setup() {
Serial.begin(115200);
delay(1000); // Serial 모니터를 열기 위해 잠시 대기합니다.
부트 카운트 증가:
부트 카운트를 증가시키고, 현재 부트 번호를 출력합니다.
++bootCount;
Serial.println("Boot number: " + String(bootCount));
웨이크업 원인 출력:
이전에 정의한 두 함수 호출을 통해 ESP32의 웨이크업 원인과 터치패드 상태를 출력합니다.
print_wakeup_reason();
print_wakeup_touchpad();
터치패드 웨이크업 설정:
ESP32의 경우 T3와 T7 터치패드에서 웨이크업을 허용하고, 다른 ESP32 버전에서는 T3에서만 웨이크업을 허용합니다. touchSleepWakeUpEnable 함수는 터치패드를 웨이크업 소스로 설정하는 함수입니다.
#if CONFIG_IDF_TARGET_ESP32
touchSleepWakeUpEnable(T3, THRESHOLD);
touchSleepWakeUpEnable(T7, THRESHOLD);
#else //ESP32-S2 + ESP32-S3
touchSleepWakeUpEnable(T3, THRESHOLD);
#endif
수면 모드 진입:
ESP32를 깊은 수면 모드로 전환합니다. 이 후의 출력은 실행되지 않으며, 마이크로컨트롤러가 수면에 들어갑니다.
Serial.println("Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
회로도
이 예제를 테스트하려면, GPIO 15에 케이블을 연결합니다. 아래의 회로도와 같이 연결합니다.
터치 웨이크업 신호 회로 배선
ESP32-S2 또는 ESP32-S3 모델을 사용하는 경우, 터치 핀의 위치를 확인하세요.
테스트
코드를 업로드한 후 Serial Monitor를 열고 보드가 수면 상태에 들어가고 다시 깨워질 때 Serial Monitor의 출력 결과를 확인하세요. 이 출력을 통해 웨이크업의 작동을 확인할 수 있습니다.
'ESP32 > ESP32' 카테고리의 다른 글
ESP32 Deep Sleep 구현하기 - 외부 웨이크업(External Wake Up) (0) | 2024.10.23 |
---|---|
ESP32 Deep Sleep 구현하기 - Timer Wake Up (1) | 2024.10.21 |
ESP32 인터럽트(Interrupt) 구현하기 - PIR(인체감지센서) (2) | 2024.10.17 |
ESP32 Timer 구현하기 - millis()함수 사용하기 (4) | 2024.10.16 |
ESP32 ADC - 아날로그 값 읽기 (0) | 2024.10.16 |