บทความ: ESP32 Deep Sleep ประหยัดพลังงานสำหรับโปรเจกต์ IoT แบบแบตเตอรี่

เรียนรู้วิธีการใช้งาน Deep Sleep Mode บน ESP32 เพื่อประหยัดพลังงานและทำให้โปรเจกต์ IoT ของคุณทำงานด้วยแบตเตอรี่ได้นานขึ้นหลายเท่า พร้อมโค้ดตัวอย่างและคำอธิบายภาษาไทย

28 มีนาคม 2026 15 นาที ระดับกลาง

🚀 บทนำ

การทำโปรเจกต์ 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);  // ปิด LED

5. ใช้ 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 ที่ทำงานด้วยแบตเตอรี่ได้นานเป็นเดือนหรือเป็นปี โดยไม่ต้องกังวลเรื่องการชาร์จไฟบ่อยๆ