Pille veya güneş paneliyle çalışan uzak IoT sensör istasyonlarında, tarımsal takip cihazlarında ve giyilebilir teknolojilerde cihazın aylarca veya yıllarca tek bir pille çalışabilmesi gerekir. ESP32 aktif çalışırken (Wi-Fi açıkken) ~150-240 mA akım tüketir; bu durum standart bir 18650 lityum pili 10-15 saatte bitirir. Bu senaryolarda ESP-IDF deep sleep kullanımı (Derin Uyku) mimarisi; CPU çekirdeklerini, Wi-Fi/Bluetooth radyosunu ve çevre birimlerini tamamen kapatarak akım tüketimini 10 ila 15 mikroampere (µA) kadar düşürür.
Bu rehberde; ESP32 güç modlarını, Deep Sleep uyandırma kaynaklarını (Zamanlayıcı, Harici GPIO butonları), uyku sırasında silinmeyen RTC FAST/SLOW bellek yönetimini ve temiz uyandırma döngülerini adım adım inşa edeceğiz.
ESP32 Güç Tüketim Modları Karşılaştırması
| Güç Modu | Aktif Bileşenler | Tipik Akım Tüketimi | Pil Ömrü (2500 mAh Pil) |
|---|---|---|---|
| Aktif (Active / Wi-Fi) | CPU (240MHz), Wi-Fi, BT, RAM | ~160 – 240 mA | ~12 – 15 Saat |
| Modem Sleep | CPU (Aktif), Wi-Fi (Kapalı/DORMANT) | ~20 – 30 mA | ~3 – 4 Gün |
| Light Sleep | RAM korunur, CPU askıya alınır | ~0.8 mA (800 µA) | ~4 Ay |
| Deep Sleep | Yalnızca RTC Denetleyicisi & RTC RAM | ~10 – 15 µA | ~5 – 10 YIL! |
Deep Sleep modunda ana CPU ve standart SRAM belleği tamamen kapanır. Çip uyandığında sanki RESET butonuna basılmış gibi app_main fonksiyonunun en başından başlar.
RTC Belleği: Uyku Sırasında Verileri Korumak (RTCDATAATTR)
Normal global değişkenler Deep Sleep sırasında RAM kapandığı için sıfırlanır. Ancak RTCDATAATTR özniteliği ile tanımlanan değişkenler 8 KB’lık özel RTC Fast Memory içine yerleşir ve uyku boyunca değerlerini korur:
#include <stdio.h>
#include "esp_sleep.h"
#include "esp_log.h"
// Bu değişken uykuya dalıp uyandığında sıfırlanmaz!
static RTC_DATA_ATTR int boot_count = 0;
1. Zamanlayıcı ile Periyodik Uyandırma (espsleepenabletimerwakeup)
En popüler senaryo: Cihaz her 10 dakikada bir uyanır, sensörü okur, Wi-Fi ile veriyi buluta iletir ve hemen tekrar uykuya dalar:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_sleep.h"
#include "esp_log.h"
#define WAKEUP_TIME_SEC 10 // 10 saniye sonra uyan
static const char *TAG = "DEEP_SLEEP";
static RTC_DATA_ATTR int boot_count = 0;
void app_main(void) {
boot_count++;
ESP_LOGI(TAG, "ESP32 Başlatıldı! Toplam Açılış Sayısı: %d", boot_count);
// Uyandırma nedenini denetle
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_TIMER:
ESP_LOGI(TAG, "Zamanlayıcı (Timer) tarafından uyandırıldı.");
break;
case ESP_SLEEP_WAKEUP_EXT0:
ESP_LOGI(TAG, "Harici GPIO butonu (ext0) tarafından uyandırıldı.");
break;
default:
ESP_LOGI(TAG, "İlk açılış veya donanımsal reset.");
break;
}
// --- BURADA SENSÖR OKUMA VE BULUTA GÖNDERME İŞLEMİ YAPILIR ---
ESP_LOGI(TAG, "Sensör verileri okundu ve gönderildi. Uykuya geçiliyor...");
// Zamanlayıcı uyandırmasını mikro-saniye cinsinden etkinleştir (1 saniye = 1,000,000 µs)
esp_sleep_enable_timer_wakeup(WAKEUP_TIME_SEC * 1000000ULL);
// Derin uykuya gir!
esp_deep_sleep_start();
}
2. Harici Buton / Kesme ile Uyandırma (ext0 ve ext1)
Sadece bir kapı sensörü açıldığında veya kullanıcı bir butona bastığında ESP32’yi uyandırmak için:
ext0 Modu (Tek Bir RTC GPIO Pini)
Sadece RTC pinleri (GPIO0, GPIO2, GPIO4, GPIO12 – GPIO15, GPIO25 – GPIO27, GPIO32 – GPIO39) kullanılabilir:
// GPIO33 pini HIGH (3.3V) seviyesine çıktığında uyandır
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
ext1 Modu (Birden Fazla GPIO Pini ve Mantıksal OR / AND)
Birden fazla butondan herhangi biri basıldığında uyanması için:
// GPIO32 veya GPIO33 pinlerinden herhangi biri basıldığında uyan
uint64_t mask = (1ULL << GPIO_NUM_32) | (1ULL << GPIO_NUM_33);
esp_sleep_enable_ext1_wakeup(mask, ESP_EXT1_WAKEUP_ANY_HIGH);
Pil Ömrünü Maksimize Eden Kritik İpuçları
- Geliştirme Kartı Tuzakları (DevKit LDO & USB-UART): Standart ESP32 NodeMCU kartlarında yer alan CP2102/CH340 USB çipleri ve AMS1117 voltaj regülatörleri, ESP32 uykuda olsa dahi sürekli 10-15 mA boşa akım harcar! Gerçek pilli projelerde düşük sızıntılı LDO (örn: ME6211 veya MCP1700, ~2 µA boşta akım) ve harici UART kullanın.
- Wi-Fi Bağlantısını Hızlı Tutun: Wi-Fi rehberimizde incelediğimiz gibi statik IP veya Wi-Fi kanalını önbelleğe almak (Fast Connect), DHCP bekleme süresini 4 saniyeden 300 ms’ye düşürür.
- GPIO Hatlarını Yüzer (Floating) Bırakmayın: Uykudayken boştaki pinlerin parazit kapıp akım çekmesini önlemek için
rtcgpioisolate()ile pinleri izole edin.
Özet
espdeepsleepstart() çağrısı, IoT projelerinizi priz bağımlılığından kurtarır. RTCDATA_ATTR ile durum bilgilerini koruyabilir, zamanlayıcı veya buton uyandırmalarıyla cihazınızı yıllarca tek pille çalıştırabilirsiniz.