- Mengapa Deep Sleep? Perbandingan Daya & Umur Baterai
- Mode Daya ESP32 (Active, Modem, Light Sleep, Deep Sleep, Hibernate)
- Deep Sleep dengan Timer Wakeup
- Deep Sleep dengan GPIO Wakeup (Touch/Button)
- Deep Sleep dengan ULP Coprocessor
- Mengukur Konsumsi Daya (Multimeter & INA219)
- Mengirim Data Sebelum Tidur (WiFi Flush & MQTT Disconnect)
- Proyek: Sensor Suhu Battery-Powered 1 Tahun
- Quiz Pemahaman
1. Mengapa Deep Sleep? Perbandingan Daya & Umur Baterai
ESP32 adalah mikrokontroler yang sangat powerful dengan WiFi dan Bluetooth built-in, namun kemampuan tersebut datang dengan konsumsi daya yang relatif besar jika dibandingkan mikrokontroler sederhana seperti ATtiny85. Saat mode aktif penuh dengan WiFi aktif, ESP32 bisa mengonsumsi hingga 240 mA โ jumlah yang cukup untuk menghabiskan baterai AAA dalam waktu kurang dari dua hari.
Inilah mengapa ESP32 menyediakan fitur Deep Sleep: mode tidur ultra-rendah daya yang hanya mengonsumsi sekitar 5-10 ยตA. Selisihnya luar biasa โ hampir 50.000 kali lebih hemat daya dibanding mode aktif!
| Skenario | Konsumsi Daya | Umur Baterai 1000mAh |
|---|---|---|
| WiFi aktif (RX/TX) | 240 mA | ~4 jam |
| WiFi idle, aktif | 150 mA | ~6.7 jam |
| Modem Sleep (CPU on) | 20 mA | ~50 jam |
| Light Sleep | 0.8 mA | ~52 hari |
| Deep Sleep | 0.005 mA (5 ยตA) | ~22 tahun* |
| Hibernate | 0.0025 mA (2.5 ยตA) | ~45 tahun* |
*Umur baterai pada Deep Sleep dihitung secara teoretis tanpa memperhitungkan self-discharge baterai (sekitar 5-20% per tahun), arus bocor regulator tegangan, dan arus sensor yang terpasang. Umur baterai nyata biasanya 1-3 tahun untuk proyek IoT sederhana yang bangun setiap 5-15 menit sekali.
Bayangkan ESP32 seperti manusia. Mode aktif adalah saat berlari maraton (boros energi). Deep Sleep adalah tidur nyenyak di malam hari โ tubuh tetap hidup tapi konsumsi energi sangat minimal. Setiap kali terbangun, ESP32 perlu "pemanasan" sebentar sebelum bisa beraktivitas kembali.
2. Mode Daya ESP32
ESP32 memiliki lima mode operasi utama, masing-masing menawarkan keseimbangan berbeda antara fungsionalitas dan efisiensi daya. Memahami perbedaan masing-masing mode adalah kunci untuk merancang proyek IoT hemat daya yang efektif.
Konsumsi Daya (mA)
โ Active Mode (WiFi ON) โ 240 mA
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Active Mode (WiFi OFF) โ 24 mA
โโโโโโ
โ Modem Sleep โ 20 mA
โโโโโ
โ Light Sleep โ 0.8 mA
โ
โ Deep Sleep โ 0.005 mA (5 ยตA)
ยท
โ Hibernate โ 0.0025 mA (2.5 ยตA)
ยท
2.1 Active Mode (Mode Aktif)
Dalam mode aktif, kedua core CPU berjalan penuh. Modul WiFi dan/atau Bluetooth bisa aktif atau dimatikan. Mode ini cocok untuk perhitungan berat atau komunikasi real-time, tetapi paling boros daya. Gunakan hanya saat benar-benar diperlukan.
2.2 Modem Sleep
CPU tetap berjalan tetapi modul WiFi/Bluetooth dimatikan saat tidak digunakan. ESP32 akan mematikan modem secara otomatis saat tidak ada paket data yang ditransmisikan. Mode ini sangat berguna untuk aplikasi yang memproses data secara lokal tanpa komunikasi konstan.
2.3 Light Sleep
CPU berhenti sementara clock dimatikan, namun semua RAM tetap terisi. ESP32 bisa terbangun dari timer, GPIO, atau peripheral lainnya. Kekurangannya: waktu wake-up relatif cepat dan semua state tetap tersimpan, tetapi konsumsi daya masih terlalu tinggi untuk baterai kecil.
2.4 Deep Sleep
Mode yang paling banyak digunakan untuk proyek hemat daya. CPU, WiFi, Bluetooth, dan sebagian besar peripheral dimatikan. Yang tetap aktif hanyalah:
- RTC (Real-Time Clock) โ untuk timer wakeup
- RTC Memory โ hingga 8 KB data bisa disimpan
- ULP Coprocessor โ bisa menjalankan program sederhana
- GPIO wake pin โ untuk membangunkan dari tombol/touch
Saat masuk Deep Sleep, semua isi SRAM hilang. Program akan dimulai ulang dari awal (seperti reboot). Inilah sebabnya kita perlu menyimpan data penting di RTC Memory atau EEPROM/SPIFFS sebelum tidur.
2.5 Hibernate
Mode paling hemat daya. Hampir semua komponen dimatikan termasuk RTC. Hanya skema wake-up eksternal yang tetap aktif. ESP32 harus boot ulang dari awal setiap kali terbangun โ tidak ada RTC memory yang tersimpan. Cocok untuk skenario wake-up eksternal yang sangat jarang.
| Mode | CPU | WiFi/BT | RAM | Wake Source |
|---|---|---|---|---|
| Active | โ Running | โ Bisa ON/OFF | โ Full | - |
| Modem Sleep | โ Running | โ Dimatikan | โ Full | - |
| Light Sleep | โ Dijeda | โ Dimatikan | โ Full | Timer, GPIO, UART |
| Deep Sleep | โ Mati | โ Mati | โ ๏ธ RTC only | Timer, GPIO, Touch, ULP |
| Hibernate | โ Mati | โ Mati | โ Hilang | GPIO eksternal |
3. Deep Sleep dengan Timer Wakeup
Mode wakeup paling sederhana dan paling sering digunakan. ESP32 akan bangun secara otomatis setelah interval waktu tertentu yang ditentukan. Ini cocok untuk aplikasi seperti sensor lingkungan yang membaca data secara berkala.
Cara Kerja Timer Wakeup
Library ESP32 Arduino menyediakan fungsi bawaan yang sangat mudah digunakan:
flowchart TD
N0["ESP32 Tombol"]
N1["Pin 1"]
N0 --> N1
Langkah-langkah pengukuran:
- Putuskan kabel positif (+) dari baterai ke ESP32
- Hubungkan probe merah multimeter ke kabel dari baterai (+)
- Hubungkan probe hitam multimeter ke pin VIN ESP32
- Atur multimeter ke range yang sesuai (mulai dari 200mA, turunkan jika perlu)
- Pastikan kabel probe terpasang ke terminal COM dan mA (bukan 10A!)
6.2 Menggunakan Modul INA219
Modul INA219 adalah sensor arus/t tegangan I2C yang populer dan murah (sekitar Rp 15-25rb). Modul ini bisa mengukur tegangan bus (0-26V), arus (ยฑ3.2A), dan menghitung daya secara real-time โ cocok untuk monitoring konsumsi daya proyek IoT.
// Membaca konsumsi daya ESP32 menggunakan INA219
// BeebaneLabs - https://beebanelabs.pages.dev
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
void setup() {
Serial.begin(115200);
Serial.println("=== INA219 Power Monitor ===");
if (!ina219.begin()) {
Serial.println("ERROR: INA219 tidak terdeteksi!");
while (1) { delay(1000); }
}
Serial.println("INA219 siap!");
Serial.println();
}
void loop() {
// Baca tegangan bus (tegangan baterai)
float teganganBus = ina219.getBusVoltage_V();
// Baca tegangan shunt (untuk hitung arus)
float teganganShunt = ina219.getShuntVoltage_mV();
// Baca arus dalam mA
float arus = ina219.getCurrent_mA();
// Hitung daya dalam mW
float daya = ina219.getPower_mW();
// Tampilkan hasil
Serial.println("--- Pembacaan Daya ---");
Serial.print("Tegangan Bus : ");
Serial.print(teganganBus, 3);
Serial.println(" V");
Serial.print("Tegangan Shunt: ");
Serial.print(teganganShunt, 3);
Serial.println(" mV");
Serial.print("Arus : ");
Serial.print(arus, 1);
Serial.println(" mA");
Serial.print("Daya : ");
Serial.print(daya, 1);
Serial.println(" mW");
Serial.println();
delay(2000);
}
Untuk pengukuran Deep Sleep yang akurat, pastikan modul USB-to-serial (CH340/CP2102) dilepas atau dinonaktifkan karena modul tersebut bisa menarik arus 20-30 mA. Gunakan baterai langsung untuk pengukuran yang representatif terhadap kondisi operasi nyata.
7. Mengirim Data Sebelum Tidur (WiFi Flush & MQTT Disconnect)
Salah satu kesalahan paling umum dalam proyek Deep Sleep adalah masuk sleep tanpa memastikan semua data sudah terkirim. Jika ESP32 masuk Deep Sleep saat WiFi atau MQTT masih dalam proses pengiriman, data bisa hilang atau koneksi broker menjadi ghost connection.
Urutan Shutdown yang Benar
// Fungsi shutdown yang benar untuk WiFi & MQTT
// BeebaneLabs - https://beebanelabs.pages.dev
#include <WiFi.h>
#include <PubSubClient.h>
// Konfigurasi WiFi
const char* ssid = "WiFi_Indonesia";
const char* password = "password123";
// Konfigurasi MQTT
const char* mqttServer = "broker.hivemq.com";
const int mqttPort = 1883;
const char* mqttTopic = "iothub/sensor/suhu";
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
// --- Fungsi Terhubung WiFi ---
void sambungWifi() {
Serial.print("Menghubungkan WiFi");
WiFi.begin(ssid, password);
int percobaan = 0;
while (WiFi.status() != WL_CONNECTED && percobaan < 20) {
delay(500);
Serial.print(".");
percobaan++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi terhubung!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nGagal terhubung WiFi!");
}
}
// --- Fungsi Terhubung MQTT ---
void sambungMQTT() {
mqttClient.setServer(mqttServer, mqttPort);
int percobaan = 0;
while (!mqttClient.connected() && percobaan < 3) {
Serial.print("Menghubungkan MQTT...");
if (mqttClient.connect("ESP32DeepSleep")) {
Serial.println("OK!");
} else {
Serial.print("Gagal, rc=");
Serial.println(mqttClient.state());
delay(1000);
percobaan++;
}
}
}
// --- Fungsi Kirim Data ---
bool kirimData(float suhu, float kelembaban) {
if (!mqttClient.connected()) return false;
// Format data sebagai JSON
char payload[128];
snprintf(payload, sizeof(payload),
"{\"suhu\":%.1f,\"kelembaban\":%.1f,\"uptime\":%lu}",
suhu, kelembaban, millis());
// Kirim data
bool berhasil = mqttClient.publish(mqttTopic, payload);
if (berhasil) {
Serial.print("Data terkirim: ");
Serial.println(payload);
} else {
Serial.println("Gagal mengirim data!");
}
return berhasil;
}
// --- Fungsi Shutdown Aman ---
void shutdownAman() {
Serial.println("=== Memulai Shutdown ===");
// Langkah 1: Pastikan semua paket MQTT terkirim
Serial.println("[1/6] Flush MQTT...");
mqttClient.loop(); // Proses callback & pending
delay(500); // Tunggu TX buffer kosong
// Langkah 2: Putuskan MQTT
Serial.println("[2/6] Disconnect MQTT...");
if (mqttClient.connected()) {
mqttClient.disconnect();
delay(100);
}
// Langkah 3: Disconnect WiFi
Serial.println("[3/6] Disconnect WiFi...");
WiFi.disconnect(true);
delay(100);
// Langkah 4: Matikan modul WiFi
Serial.println("[4/6] WiFi OFF...");
WiFi.mode(WIFI_OFF);
delay(100);
// Langkah 5: Putuskan radio WiFi
Serial.println("[5/6] WiFi radio OFF...");
esp_wifi_disconnect();
delay(100);
// Langkah 6: Flush serial
Serial.println("[6/6] Serial flush...");
Serial.flush();
Serial.println("=== Shutdown Selesai ===");
delay(100);
}
Selalu panggil shutdownAman() sebelum esp_deep_sleep_start(). Tanpa fungsi ini, data yang dikirim via MQTT bisa hilang, atau WiFi connection bisa menjadi "ghost" yang memboroskan daya karena broker tetap mencoba mengirim data ke perangkat yang sudah tidur.
8. Proyek: Sensor Suhu Battery-Powered 1 Tahun
Sekarang kita akan menggabungkan semua konsep yang sudah dipelajari menjadi proyek nyata: sensor suhu yang bisa bertahan hampir setahun menggunakan satu baterai LiPo 18650 (3400mAh).
Spesifikasi Proyek
| Parameter | Nilai |
|---|---|
| Sensor | DHT22 / DS18B20 (akurat & hemat daya) |
| Interval pembacaan | 15 menit |
| Protokol kirim data | MQTT ke broker HiveMQ / Mosquitto |
| Baterai | LiPo 18650 โ 3.7V 3400mAh |
| Target umur baterai | Minimal 10 bulan |
| Metode hemat daya | Deep Sleep + Timer Wakeup |
Kalkulasi Daya
Untuk mencapai target 1 tahun, kita bisa menggunakan baterai ganda (2ร 18650 paralel = 6800mAh) atau interval 30 menit. Dengan 6800mAh dan interval 15 menit, baterai bertahan sekitar 338 hari โ cukup untuk mencapai target 1 tahun.
Kode Program Lengkap
// Sensor Suhu Battery-Powered 1 Tahun
// ESP32 Deep Sleep + MQTT + DHT22
// BeebaneLabs - https://beebanelabs.pages.dev
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// ===== KONFIGURASI =====
#define SLEEP_DURATION 900LL // 15 menit (dalam detik)
#define DHT_PIN 4 // GPIO4
#define DHT_TYPE DHT22 // Gunakan DHT22 untuk akurasi
#define LED_INDICATOR 2 // GPIO2 (LED internal)
#define BAT_ADC_PIN 34 // GPIO34 untuk baca tegangan baterai
#define BAT_VOLT_DIV 2.0 // Rasio voltage divider
// WiFi credentials
const char* WIFI_SSID = "WiFi_Indonesia";
const char* WIFI_PASS = "password123";
// MQTT credentials
const char* MQTT_SERVER = "broker.hivemq.com";
const int MQTT_PORT = 1883;
const char* MQTT_USER = "";
const char* MQTT_PASS_MQTT = "";
const char* MQTT_TOPIC = "iothub/suhu/esp32-01";
const char* MQTT_CLIENT = "ESP32-Suhu-01";
// ===== OBJEK GLOBAL =====
DHT dht(DHT_PIN, DHT_TYPE);
WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);
// ===== RTC MEMORY =====
RTC_DATA_ATTR int wakeCount = 0;
RTC_DATA_ATTR int errConnect = 0;
RTC_DATA_ATTR float lastSuhu = 0.0;
RTC_DATA_ATTR float lastHumidity = 0.0;
// ===== FUNGSI SETUP =====
void setup() {
Serial.begin(115200);
Serial.flush();
wakeCount++;
// LED indikator
pinMode(LED_INDICATOR, OUTPUT);
digitalWrite(LED_INDICATOR, HIGH);
Serial.println();
Serial.println("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ");
Serial.println("โ Sensor Suhu Battery-Powered 1 Tahun โ");
Serial.println("โ ESP32 Deep Sleep + MQTT โ");
Serial.println("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ");
Serial.print("Wake-up ke-: ");
Serial.println(wakeCount);
// Baca tegangan baterai
float teganganBaterai = bacaTeganganBaterai();
Serial.print("Tegangan baterai: ");
Serial.print(teganganBaterai, 2);
Serial.println(" V");
// Cek apakah baterai masih cukup (minimum 3.3V)
if (teganganBaterai < 3.3) {
Serial.println("PERINGATAN: Baterai lemah! Interval diperpanjang.");
// Jika baterai lemah, sleep lebih lama (30 menit)
sleepDanBangun(SLEEP_DURATION * 2);
}
// Baca sensor suhu
dht.begin();
delay(2000); // Tunggu sensor stabil
float suhu = dht.readTemperature();
float kelembaban = dht.readHumidity();
if (isnan(suhu) || isnan(kelembaban)) {
Serial.println("ERROR: Gagal baca sensor DHT22!");
// Gunakan data terakhir dari RTC memory
suhu = lastSuhu;
kelembaban = lastHumidity;
Serial.println("Menggunakan data terakhir dari RTC memory.");
} else {
Serial.print("Suhu : ");
Serial.print(suhu, 1);
Serial.println(" ยฐC");
Serial.print("Kelembaban: ");
Serial.print(kelembaban, 1);
Serial.println(" %");
lastSuhu = suhu;
lastHumidity = kelembaban;
}
// Kirim data via MQTT
if (suhu != 0.0 || kelembaban != 0.0) {
bool terkirim = kirimDataMQTT(suhu, kelembaban, teganganBaterai);
if (terkirim) {
Serial.println("Data berhasil dikirim!");
} else {
Serial.println("Gagal mengirim data.");
errConnect++;
}
}
// Shutdown dan masuk Deep Sleep
shutdownAman();
Serial.print("Tidur selama ");
Serial.print(SLEEP_DURATION);
Serial.println(" detik...");
sleepDanBangun(SLEEP_DURATION);
}
// ===== FUNGSI LOOP =====
void loop() {
// Tidak digunakan โ ESP32 selalu bangun dari setup()
}
// ===== FUNGSI-FUNGSI PEMBANTU =====
float bacaTeganganBaterai() {
// Baca ADC dan konversi ke tegangan
int adcValue = analogRead(BAT_ADC_PIN);
float tegangan = (adcValue / 4095.0) * 3.3 * BAT_VOLT_DIV;
return tegangan;
}
bool kirimDataMQTT(float suhu, float kelembaban, float tegangan) {
// Sambung WiFi
Serial.print("Menghubungkan WiFi...");
WiFi.begin(WIFI_SSID, WIFI_PASS);
int coba = 0;
while (WiFi.status() != WL_CONNECTED && coba < 20) {
delay(500);
Serial.print(".");
coba++;
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\nWiFi gagal!");
return false;
}
Serial.println(" OK!");
// Sambung MQTT
mqtt.setServer(MQTT_SERVER, MQTT_PORT);
coba = 0;
while (!mqtt.connected() && coba < 3) {
Serial.print("MQTT...");
if (mqtt.connect(MQTT_CLIENT, MQTT_USER, MQTT_PASS_MQTT)) {
Serial.println("OK!");
} else {
Serial.print("Gagal (");
Serial.print(mqtt.state());
Serial.println(")");
delay(1000);
coba++;
}
}
if (!mqtt.connected()) {
Serial.println("MQTT tidak terhubung!");
return false;
}
// Siapkan payload JSON
char payload[256];
snprintf(payload, sizeof(payload),
"{"
"\"device\":\"ESP32-01\","
"\"suhu\":%.1f,"
"\"kelembaban\":%.1f,"
"\"baterai\":%.2f,"
"\"wake\":%d,"
"\"uptime\":%lu"
"}",
suhu, kelembaban, tegangan, wakeCount, millis()
);
// Publish
bool hasil = mqtt.publish(MQTT_TOPIC, payload);
mqtt.loop();
delay(200);
return hasil;
}
void shutdownAman() {
Serial.println("Shutdown...");
mqtt.loop();
delay(500);
if (mqtt.connected()) mqtt.disconnect();
delay(100);
WiFi.disconnect(true);
delay(100);
WiFi.mode(WIFI_OFF);
delay(100);
Serial.flush();
digitalWrite(LED_INDICATOR, LOW);
delay(100);
}
void sleepDanBangun(long long detikTidur) {
esp_sleep_enable_timer_wakeup(detikTidur * 1000000ULL);
esp_deep_sleep_start();
}
Rangkaian Fisik
- Baterai lebih besar = umur lebih lama. Gunakan 2ร 18650 paralel untuk 6800mAh.
- Interval lebih lama = menghemat daya signifikan. 30 menit masih cukup untuk monitoring suhu ruangan.
- Gunakan DS18B20 sebagai alternatif DHT22 โ lebih hemat daya saat pembacaan.
- Matikan semua LED pada modul selain LED indikator sesaat.
- Hapus voltage regulator dan jalankan ESP32 langsung dari 3.7V LiPo (lihat datasheet untuk batas tegangan).
9. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang ESP32 Deep Sleep: