📑 เนื้อหาในบทความ
🚀 บทนำ
การทำโปรเจกต์ IoT แบบใช้แบตเตอรี่ (Battery-Powered) เป็นความท้าทายที่สำคัญ โดยเฉพาะเมื่อต้องการให้อุปกรณ์ทำงานได้นานหลายเดือนหรือหลายปี ESP32 มีคุณสมบัติ Deep Sleep Mode ที่ช่วยประหยัดพลังงานได้อย่างมหาศาล โดยลดการใช้พลังงานลงเหลือเพียงไม่กี่ไมโครแอมป์
ในบทความนี้ คุณจะได้เรียนรู้:
- Deep Sleep คืออะไรและทำงานอย่างไร
- โหมดพลังงานต่างๆ ของ ESP32
- วิธีเข้า Deep Sleep และตื่นขึ้นมา
- การใช้ RTC Memory เก็บข้อมูลขณะหลับ
- เคล็ดลับประหยัดพลังงานเพิ่มเติม
💤 Deep Sleep คืออะไร?
Deep Sleep Mode คือโหมดประหยัดพลังงานที่สุดของ ESP32 โดยจะปิดการทำงานของ CPU และอุปกรณ์ส่วนใหญ่ เหลือเพียง RTC (Real-Time Clock) และหน่วยความจำบางส่วนที่ทำงานต่อ
⚡ ข้อมูลสำคัญ:
- Active Mode: ~240 mA (WiFi + Bluetooth)
- Light Sleep: ~0.8 mA - 15 mA
- Deep Sleep: ~10 µA (ไมโครแอมป์!)
- Hibernation: ~2.5 µA (ต่ำสุด)
ด้วยการลดการใช้พลังงานลงเหลือเพียง 10 µA แบตเตอรี่ 2000mAh สามารถทำให้ ESP32 ทำงานได้นานกว่า 22 ปี (ในทางทฤษฎี) แต่ในความเป็นจริงแล้วขึ้นอยู่กับรูปแบบการใช้งาน
🔋 โหมดพลังงานของ ESP32
ESP32 มี 5 โหมดพลังงานหลักที่คุณควรรู้จัก:
1. Active Mode (โหมดปกติ)
CPU ทำงานเต็มสปีด WiFi/Bluetooth เปิดอยู่ ใช้พลังงาน ~240 mA
2. Modem Sleep
CPU ทำงาน แต่ WiFi/Bluetooth หลับ ใช้พลังงาน ~20-30 mA
3. Light Sleep
CPU หลับ แต่สามารถตื่นด้วย interrupt ได้ ใช้พลังงาน ~0.8-15 mA
4. Deep Sleep (โหมดหลับลึก)
CPU และ WiFi หลับสนิท ตื่นด้วย Timer/External Wakeup ใช้พลังงาน ~10 µA ⭐
5. Hibernation (โหมดจำศีล)
ปิดทุกอย่างยกเว้น RTC memory ใช้พลังงาน ~2.5 µA (ต่ำสุด)
💻 การใช้งาน Deep Sleep พื้นฐาน
มาเริ่มต้นด้วยตัวอย่างการใช้งาน Deep Sleep แบบง่ายที่สุด โดยจะให้ ESP32 เข้า Deep Sleep เป็นเวลา 10 วินาที แล้วตื่นขึ้นมาทำงาน แล้วกลับเข้า Deep Sleep อีกครั้ง
#include <WiFi.h>
// ตั้งค่าเวลานับถอยหลังก่อนเข้า Deep Sleep (หน่วย: ไมโครวินาที)
// 1 วินาที = 1,000,000 ไมโครวินาที
#define uS_TO_S_FACTOR 1000000
// เวลาที่จะนอน (10 วินาที)
#define TIME_TO_SLEEP 10
RTC_DATA_ATTR int bootCount = 0; // ตัวแปรเก็บใน RTC Memory
void setup() {
Serial.begin(115200);
// เพิ่มจำนวนครั้งที่บูต
bootCount++;
Serial.println("Boot number: " + String(bootCount));
// พิมพ์ข้อมูลการตื่น
print_wakeup_reason();
// ทำงานของคุณที่นี่ (อ่านเซ็นเซอร์ ส่งข้อมูล ฯลฯ)
Serial.println("กำลังทำงาน...");
delay(2000); // จำลองการทำงาน 2 วินาที
Serial.println("เสร็จสิ้น! เข้า Deep Sleep");
// ตั้งค่า Timer เพื่อตื่น
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
// เข้า Deep Sleep
Serial.println("เข้า Deep Sleep แล้ว...");
esp_deep_sleep_start();
}
void loop() {
// ไม่มีอะไรที่นี่ เพราะ Deep 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_TIMER:
Serial.println("ตื่นด้วย Timer");
break;
case ESP_SLEEP_WAKEUP_EXT0:
Serial.println("ตื่นด้วย External Wakeup (EXT0)");
break;
case ESP_SLEEP_WAKEUP_EXT1:
Serial.println("ตื่นด้วย External Wakeup (EXT1)");
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD:
Serial.println("ตื่นด้วย Touchpad");
break;
default:
Serial.println("ไม่ได้ตื่นจาก Deep Sleep (เป็นการบูตครั้งแรก)");
break;
}
}💡 หมายเหตุ: เมื่อ ESP32 ตื่นจาก Deep Sleep จะเริ่มต้นที่ฟังก์ชัน setup() ใหม่เสมอ ไม่ได้กลับไปที่ loop()
⏰ Wake Up Sources (วิธีการตื่น)
ESP32 มีหลายวิธีในการตื่นจาก Deep Sleep:
1. Timer Wakeup (ตื่นด้วยตั้งเวลา)
วิธีที่พบบ่อยที่สุด ตั้งเวลาให้ตื่นเมื่อถึงเวลาที่กำหนด
// ตื่นทุกๆ 10 วินาที
esp_sleep_enable_timer_wakeup(10 * 1000000); // หน่วย: ไมโครวินาที
// ตื่นทุกๆ 1 นาที
esp_sleep_enable_timer_wakeup(60 * 1000000);
// ตื่นทุกๆ 1 ชั่วโมง
esp_sleep_enable_timer_wakeup(3600 * 1000000);2. EXT0 Wakeup (ตื่นด้วย GPIO Pin)
ใช้ขา GPIO หนึ่งเพื่อตื่นเมื่อมีสัญญาณ HIGH หรือ LOW
// ตั้งค่าให้ขา GPIO 4 ตื่นเมื่อเป็น HIGH
#define BUTTON_PIN GPIO_NUM_4
esp_sleep_enable_ext0_wakeup(BUTTON_PIN, 1); // 1 = HIGH, 0 = LOW
// เข้า Deep Sleep
esp_deep_sleep_start();3. EXT1 Wakeup (ตื่นด้วยหลาย GPIO)
ใช้หลายขา GPIO พร้อมกัน เหมาะสำหรับปุ่มหลายปุ่ม
// ตั้งค่าให้ขา GPIO 4, 5, 6 สามารถตื่นได้
#define BUTTON1_PIN GPIO_NUM_4
#define BUTTON2_PIN GPIO_NUM_5
#define BUTTON3_PIN GPIO_NUM_6
uint64_t wakeup_pin_mask = (1ULL << BUTTON1_PIN) |
(1ULL << BUTTON2_PIN) |
(1ULL << BUTTON3_PIN);
esp_sleep_enable_ext1_wakeup(wakeup_pin_mask, ESP_EXT1_WAKEUP_ANY_HIGH);
// เข้า Deep Sleep
esp_deep_sleep_start();4. Touchpad Wakeup (ตื่นด้วยการสัมผัส)
ใช้ขา Touch ของ ESP32 เพื่อตื่นเมื่อสัมผัส
// ตั้งค่าให้ขา Touch 0 (GPIO 4) สามารถตื่นได้
esp_sleep_enable_touchpad_wakeup();
// เข้า Deep Sleep
esp_deep_sleep_start();💾 RTC Memory (หน่วยความจำล้ำคลื่น)
RTC Memory คือหน่วยความจำพิเศษที่ไม่ถูกรีเซ็ตเมื่อเข้า Deep Sleep ทำให้คุณสามารถเก็บข้อมูลไว้ข้ามรอบการหลับได้
📊 ข้อมูล RTC Memory:
- ขนาด: ~8 KB
- ไม่หายเมื่อ Deep Sleep
- ใช้
RTC_DATA_ATTRประกาศตัวแปร - เหมาะเก็บ: boot count, sensor data history, settings
ตัวอย่างการใช้ RTC Memory
// ประกาศตัวแปรใน RTC Memory
RTC_DATA_ATTR int bootCount = 0; // นับจำนวนการบูต
RTC_DATA_ATTR float totalTemp = 0; // ผลรวมอุณหภูมิ
RTC_DATA_ATTR int readingCount = 0; // จำนวนครั้งที่อ่าน
RTC_DATA_ATTR struct {
float minTemp;
float maxTemp;
time_t lastUpdate;
} sensorHistory;
void setup() {
Serial.begin(115200);
// ตัวแปรเหล่านี้จะยังคงค่าไว้หลังจากตื่นจาก Deep Sleep
bootCount++;
Serial.println("Boot count: " + String(bootCount));
Serial.println("Total temp: " + String(totalTemp));
// อ่านเซ็นเซอร์
float currentTemp = readTemperature();
totalTemp += currentTemp;
readingCount++;
// อัปเดตประวัติ
if (currentTemp > sensorHistory.maxTemp || bootCount == 1) {
sensorHistory.maxTemp = currentTemp;
}
if (currentTemp < sensorHistory.minTemp || bootCount == 1) {
sensorHistory.minTemp = currentTemp;
}
sensorHistory.lastUpdate = time(NULL);
// ส่งข้อมูลไป CynoIoT (ถ้าต้องการ)
// sendDataToCynoIoT(currentTemp);
// เข้า Deep Sleep 10 วินาที
esp_sleep_enable_timer_wakeup(10 * 1000000);
esp_deep_sleep_start();
}🔬 Ultra Low Power Tips
นอกจาก Deep Sleep แล้ว ยังมีเทคนิคเพิ่มเติมเพื่อลดการใช้พลังงาน:
1. ปิด WiFi/Bluetooth ทันทีที่ใช้งานเสร็จ
// เชื่อมต่อ WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
// ส่งข้อมูล
sendData();
// ปิด WiFi ทันที!
WiFi.mode(WIFI_OFF);
btStop(); // ปิด Bluetooth ด้วย2. ลดความถี่ CPU
// ลดความถี่ CPU เหลือ 80MHz (จาก 240MHz)
setCpuFrequencyMhz(80);
// หรือใช้ 160MHz เพื่อความสมดุล
setCpuFrequencyMhz(160);3. ใช้ Hibernation แทน Deep Sleep
// Hibernation ใช้พลังงานต่ำกว่า (2.5 µA)
// แต่ RTC RAM จะหายไป
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
esp_deep_sleep_start();4. ปิด LED บนบอร์ด
LED บนบอร์ดใช้พลังงาน ~10-20 mA ถอนออกหรือปิดผ่านโค้ด
// ปิด LED บนขา GPIO 2 (สำหรับ ESP32 DevKit)
#define LED_PIN 2
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // ปิด LED5. ใช้ Voltage Regulator ที่มีประสิทธิภาพสูง
ใช้ LDO Regulator หรือ Buck Converter ที่มีประสิทธิภาพสูง (>90%) เพื่อลดการสูญเสียพลังงาน
📏 การวัดประสิทธิภาพ
เพื่อคำนวณอายุการใช้งานแบตเตอรี่ คุณต้องวัดกระแสเฉลี่ยที่ใช้จริง
สูตรคำนวณอายุแบตเตอรี่
อายุการใช้งาน (ชั่วโมง) = (แบตเตอรี่ mAh ÷ กระแสเฉลี่ย mA) × 0.7
× 0.7 คือ factor ความปลอดภัย (เผื่ออุณหภูมิ ความเสื่อมของแบตเตอรี่)
ตัวอย่างการคำนวณ
สถานการณ์:
- แบตเตอรี่: 2000 mAh (Li-ion 18650)
- Active: 5 วินาที @ 150 mA
- Deep Sleep: 55 วินาที @ 0.01 mA
กระแสเฉลี่ย: (150mA × 5s + 0.01mA × 55s) ÷ 60s = 12.5 mA
อายุการใช้งาน: (2000 ÷ 12.5) × 0.7 = 112 ชั่วโมง (~4.6 วัน)
💡 เคล็ดลับ: ถ้าต้องการให้ทำงานหลายเดือน ต้องลดเวลา Active หรือเพิ่มช่วงเวลา Sleep เช่น อ่านเซ็นเซอร์ทุกๆ 10 นาทีแทน 1 นาที
✨ เคล็ดลับและ Best Practices
✅ ทำควรทำ
- ปิด WiFi/Bluetooth ทันทีหลังใช้งาน
- ใช้ RTC Memory เก็บข้อมูลสำคัญ
- ตั้งค่า sleep time ให้เหมาะสมกับ use case
- ทดสอบกระแสด้วย multimeter จริง
- เพิ่ม error handling สำหรับการเชื่อมต่อ
- ใช้ Hibernation ถ้าไม่ต้องการ RTC Memory
❌ หลีกเลี่ยง
- ไม่ปิด WiFi (ใช้พลังงาน ~50mA ต่อเนื่อง)
- ใช้ delay() นานเกินไปใน Active mode
- ไม่ได้ปิด LED/อุปกรณ์เสริม
- ใช้ Serial.print() มากเกินไป
- ไม่ได้ทดสอบกระแสจริง
- ใช้แบตเตอรี่ขนาดเล็กเกินไป
🎯 Use Case แนะนำ:
• Weather Station: อ่านทุก 5-15 นาที (อายุแบต 6-12 เดือน)
• Smart Agriculture: อ่านทุก 1-6 ชั่วโมง (อายุแบต 1-2 ปี)
• Asset Tracking: ส่งตำแหน่งทุก 10-30 นาที (อายุแบต 3-6 เดือน)
• Home Automation: อ่านปุ่มทุกครั้งที่กด (event-driven)
🎉 สรุป
Deep Sleep Mode บน ESP32 เป็นฟีเจอร์ที่ทรงพลังสำหรับโปรเจกต์ IoT แบบแบตเตอรี่ โดยสามารถลดการใช้พลังงานจาก ~240 mA เหลือเพียง ~10 µA
สิ่งสำคัญที่ต้องจำ:
- ปิด WiFi/Bluetooth ทันทีที่ใช้งานเสร็จ
- ใช้ RTC Memory เก็บข้อมูลข้ามรอบ Sleep
- เลือก Wakeup Source ให้เหมาะกับ Use Case
- ทดสอบกระแสจริงด้วย Multimeter
- ใช้ Hibernation ถ้าต้องการประหยัดสูงสุด
ด้วยการประยุกต์ใช้ Deep Sleep อย่างถูกต้อง คุณสามารถสร้างโปรเจกต์ IoT ที่ทำงานด้วยแบตเตอรี่ได้นานเป็นเดือนหรือเป็นปี โดยไม่ต้องกังวลเรื่องการชาร์จไฟบ่อยๆ