📑 เนื้อหาในบทความ
📊 ภาพรวมโปรเจกต์
โปรเจกต์นี้จะสอนให้คุณสร้างเซ็นเซอร์โหนด (Sensor Node) ด้วย ESP32 ที่สามารถทำงานด้วยแบตเตอรี่ได้นานหลายเดือน โดยใช้เทคนิค Deep Sleep Mode เพื่อลดการใช้พลังงานลงเหลือเพียงไม่กี่ไมโครแอมป์เมื่อไม่ได้ทำงาน
ทำไมต้อง Low Power Sensor Node?
- ✅ ติดตั้งได้ทุกที่โดยไม่ต้องมีสายไฟ
- ✅ ประหยัดค่าไฟฟ้า
- ✅ เหมาะกับโปรเจกต์ที่ต้องลงจริง เช่น วัดอุณหภูมิในสวน, ระบบเตือนน้ำท่วม
- ✅ ดูแลรักษาง่าย เปลี่ยนแบตเตอรี่ทีละนาน
สิ่งที่คุณจะได้เรียนรู้
- • เข้าใจการทำงานของ Deep Sleep Mode บน ESP32
- • คำนวณอัตราการใช้พลังงานและอายุการใช้งานแบตเตอรี่
- • เขียนโปรแกรมจัดการการตื่นจาก Deep Sleep ด้วย Timer
- • เลือกใช้เซ็นเซอร์ที่ประหยัดไฟ
- • ใช้ CynoIoT Platform รับข้อมูลจากเซ็นเซอร์โหนด
🔧 อุปกรณ์ที่ต้องใช้
📦 Hardware Components
- ESP32 Development Board- แนะนำ ESP32-WROOM-32 หรือ ESP32-WROVER~฿120-180
- DHT22 Temperature & Humidity Sensor- หรือ DHT11 เพื่อราคาประหยัดกว่า~฿50-80
- Li-Ion 18650 Battery (หรือ Li-Po)- แนะนำ 2000mAh ขึ้นไป~฿80-150
- 18650 Battery Holder- แบบ 1 หรือ 2 ก้อน~฿20-40
- TP4056 Li-Ion Charger Module- สำหรับชาร์จแบตเตอรี่~฿15-25
- Jumper Wires & Breadboard- สำหรับต่อวงจร~฿30-50
💰 งบประมาณรวม: ประมาณ ฿315-525
ราคาอาจแตกต่างตามร้านค้าและยี่ห้อสินค้า
💻 Software & Tools
- • Arduino IDE (version 1.8.x ขึ้นไป) หรือ PlatformIO
- • ESP32 Board Package (ติดตั้งผ่าน Board Manager)
- • DHT Sensor Library (Adafruit version)
- • CynoIoT Account (สมัครฟรีที่ cynoiot.com)
⚡ การต่อวงจร
การต่อวงจรสำหรับโปรเจกต์นี้ค่อนข้างง่าย เราจะเชื่อมต่อ DHT22 Sensor กับ ESP32 และใช้แบตเตอรี่ 18650 จ่ายไฟเข้า ESP32 โดยตรง (ผ่าน TP4056 Charger)
🔌 ตารางการเชื่อมต่อ (DHT22 → ESP32)
| DHT22 Pin | ESP32 Pin | หมายเหตุ |
|---|---|---|
| VCC | 3.3V | จ่ายไฟ 3.3V |
| DATA | GPIO 4 | ต่อร่วมกับ Resistor 10KΩ ไปที่ VCC |
| GND | GND | กราวด์ |
คำเตือนสำคัญ!
- • DHT22 ใช้ไฟ 3.3V-5V แต่ ESP32 ใช้ 3.3V เท่านั้น ดังนั้นต่อเข้า 3.3V Pin ของ ESP32
- • ต้องมี Pull-up Resistor 10KΩ ระหว่าง DATA และ VCC (DHT22 บางรุ่นมีในตัว)
- • อย่าต่อแบตเตอรี่โดยตรงเข้า USB/Power Pin ของ ESP32 ต้องผ่าน TP4056 เพื่อป้องกันไฟเกิน
🔌 วิธีต่อแบตเตอรี่ (18650 + TP4056 → ESP32)
- เสียบแบตเตอรี่ 18650 เข้า TP4056 Charger Module (ใส่ถูกทิศทาง: + เข้า +, - เข้า -)
- ต่อสายจาก TP4056: OUT+ → ESP32 VIN หรือ 5V Pin
- ต่อสายจาก TP4056: OUT- → ESP32 GND
- ต่อ USB เข้า TP4056 เพื่อชาร์จแบตเตอรี่ (ไฟ LED สีแดงจะติดขณะชาร์จ)
😴 เข้าใจ Deep Sleep Mode
Deep Sleep Mode คือโหมดประหยัดพลังงานขั้นสูงของ ESP32 โดยจะปิดการทำงานของ CPU และ WiFi แต่ยังคงเปิด RTC Memory และ RTC peripherals ไว้เพื่อให้สามารถตื่นจากการนอนได้
⚡ Active Mode (ปกติ)
- • ใช้กระแส: 150-240mA (WiFi ติด)
- • CPU ทำงานเต็มสปีด
- • WiFi/Bluetooth เปิดใช้งาน
- • เหมาะกับ: ส่งข้อมูล, ประมวลผล
💤 Deep Sleep Mode
- • ใช้กระแส: ~10µA (0.01mA)
- • CPU หยุดทำงาน
- • WiFi/Bluetooth ปิด
- • RTC Memory เก็บข้อมูลบางส่วน
📐 คำนวณอายุแบตเตอรี่ (ตัวอย่าง)
ถ้าใช้แบตเตอรี่ 18650 2000mAh และเซ็นเซอร์อ่านค่าทุก 10 นาที (144 ครั้ง/วัน):
- • Active time ต่อครั้ง: ~5 วินาที × 144 = 720 วินาที = 12 นาที/วัน
- • Active current: 200mA × 0.2 ชม. = 40mAh/วัน
- • Deep Sleep: 23.8 ชม. × 0.01mA = 0.24mAh/วัน
- • รวมทั้งหมด: ~40.24mAh/วัน
- • อายุแบตเตอรี่: 2000mAh ÷ 40.24 = ~49 วัน (1.6 เดือน!)
🔄 วงจรการทำงาน (Wake Cycle)
- ESP32 ตื่นจาก Deep Sleep ด้วย Timer
- เปิด WiFi และเชื่อมต่อ Access Point
- อ่านค่าจาก DHT22 Sensor
- ส่งข้อมูลไป CynoIoT Platform
- ตรวจสอบว่าสำเร็จหรือไม่
- กลับเข้า Deep Sleep อีกครั้ง
💻 โค้ดโปรแกรม
นี่คือโค้ด Arduino สำหรับ ESP32 Low Power Sensor Node ที่เชื่อมต่อกับ CynoIoT Platform:
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
#include "esp_deep_sleep.h"
// ===== WiFi Settings =====
const char* ssid = "YOUR_WIFI_SSID"; // แก้ไขชื่อ WiFi
const char* password = "YOUR_WIFI_PASSWORD"; // แก้ไขรหัสผ่าน WiFi
// ===== CynoIoT Settings =====
const char* cynoApiUrl = "https://api.cynoiot.com/v1/sensor/data"; // URL ของ CynoIoT API
const char* deviceToken = "YOUR_DEVICE_TOKEN"; // Device Token จาก CynoIoT
// ===== Sensor Settings =====
#define DHTPIN 4 // GPIO Pin ที่ต่อ DHT22
#define DHTTYPE DHT22 // รุ่นเซ็นเซอร์ (DHT11 หรือ DHT22)
DHT dht(DHTPIN, DHTTYPE);
// ===== Deep Sleep Settings =====
#define uS_TO_S_FACTOR 1000000 // แปลงไมโครวินาทีเป็นวินาที
#define TIME_TO_SLEEP 600 // นอน 600 วินาที (10 นาที) - แก้ไขตามต้องการ
// ===== Variables =====
unsigned long lastTime = 0;
const long interval = 30000; // 30 วินาทีสำหรับ timeout
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n\n=== ESP32 Low Power Sensor Node ===");
Serial.println("ตื่นจาก Deep Sleep หรือเริ่มต้นระบบ...");
// ตรวจสอบสาเหตุการตื่น (Wake 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_TOUCHPAD:
Serial.println("ตื่นเพราะ Touchpad");
break;
default:
Serial.println("ตื่นเพราะเริ่มต้นระบบ (ไม่ใช่ Deep Sleep)");
break;
}
// เริ่มต้นเซ็นเซอร์
dht.begin();
// เชื่อมต่อ WiFi
connectWiFi();
// อ่านค่าเซ็นเซอร์
readSensor();
// กลับเข้า Deep Sleep
enterDeepSleep();
}
void loop() {
// ไม่ต้องใช้ loop() เพราะเราใช้ Deep Sleep
delay(1000);
}
// ===== เชื่อมต่อ WiFi =====
void connectWiFi() {
Serial.println("กำลังเชื่อมต่อ WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED &&
millis() - startAttemptTime < 30000) { // Timeout 30 วินาที
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n✅ WiFi เชื่อมต่อสำเร็จ!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\n❌ ไม่สามารถเชื่อมต่อ WiFi ได้");
Serial.println("กำลังกลับเข้า Deep Sleep...");
enterDeepSleep();
}
}
// ===== อ่านค่าเซ็นเซอร์ =====
void readSensor() {
Serial.println("อ่านค่าจาก DHT22...");
// อ่านค่าอุณหภูมิและความชื้น
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// ตรวจสอบว่าอ่านค่าได้หรือไม่
if (isnan(temperature) || isnan(humidity)) {
Serial.println("❌ ไม่สามารถอ่านค่าจาก DHT22 ได้");
return;
}
// แสดงค่าที่อ่านได้
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.printf("อุณหภูมิ: %.2f °C\n", temperature);
Serial.printf("ความชื้น: %.2f %%\n", humidity);
Serial.printf("Heat Index: %.2f °C\n", dht.computeHeatIndex(temperature, humidity, false));
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
// ส่งข้อมูลไป CynoIoT
sendToCynoIoT(temperature, humidity);
}
// ===== ส่งข้อมูลไป CynoIoT =====
void sendToCynoIoT(float temp, float humi) {
Serial.println("ส่งข้อมูลไป CynoIoT Platform...");
if (WiFi.status() != WL_CONNECTED) {
Serial.println("❌ WiFi ไม่ได้เชื่อมต่ออยู่");
return;
}
HTTPClient http;
http.begin(cynoApiUrl);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " + String(deviceToken));
// สร้าง JSON payload
String payload = "{\"temperature\":" + String(temp) +
",\"humidity\":" + String(humi) +
",\"timestamp\":" + String(millis()) + "}";
Serial.print("Payload: ");
Serial.println(payload);
// ส่ง HTTP POST
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
if (httpResponseCode == 200 || httpResponseCode == 201) {
String response = http.getString();
Serial.println("✅ ส่งข้อมูลสำเร็จ!");
Serial.println("Response: " + response);
} else {
Serial.println("⚠️ ส่งข้อมูลไม่สำเร็จ");
}
} else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end();
}
// ===== เข้า Deep Sleep Mode =====
void enterDeepSleep() {
Serial.println("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println("กำลังเข้า Deep Sleep Mode...");
Serial.printf("จะตื่นอีกครั้งใน %d วินาที\n", TIME_TO_SLEEP);
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
// ปิด WiFi เพื่อประหยัดพลังงาน
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
delay(1000);
// เข้า Deep Sleep ด้วย Timer
esp_deep_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
esp_deep_sleep_start();
}📝 สิ่งที่ต้องแก้ไขในโค้ด
- •
ssid- ชื่อ WiFi ของคุณ - •
password- รหัสผ่าน WiFi - •
deviceToken- Device Token จาก CynoIoT Platform (ได้จากหน้า Dashboard) - •
TIME_TO_SLEEP- เวลานอนเป็นวินาที (ค่าเริ่มต้น: 600 = 10 นาที) - •
DHTPIN- ถ้าต่อที่ GPIO อื่น ให้แก้ตรงนี้
🔧 การติดตั้ง Libraries
ก่อนอัปโหลดโค้ด ติดตั้ง Libraries ที่จำเป็นใน Arduino IDE:
- เปิด Arduino IDE → Sketch → Include Library → Manage Libraries
- ค้นหา "DHT sensor library" โดย Adafruit → ติดตั้ง
- ค้นหา "Adafruit Unified Sensor" → ติดตั้ง
- ติดตั้ง ESP32 Board Package (ถ้ายังไม่ได้ติดตั้ง)
- File → Preferences → Additional Board Manager URLs:
- https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
⚡ เทคนิคประหยัดไฟเพิ่มเติม
นอกจาก Deep Sleep Mode แล้ว ยังมีเทคนิคอื่นๆ ที่ช่วยให้เซ็นเซอร์โหนดทำงานได้นานขึ้น:
1️⃣ ลดเวลาที่ใช้งาน WiFi
WiFi ใช้พลังงานมากที่สุด ลดเวลาเปิด WiFi ให้น้อยที่สุด:
// ปิด WiFi ทันทีที่ใช้เสร็จ
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
delay(100); // รอให้ปิดสมบูรณ์2️⃣ ลด WiFi TX Power
ลดกำลังส่งสัญญาณ WiFi ถ้าอยู่ใกล้ Access Point:
// ลดกำลังส่งสัญญาณ WiFi (0.25 - 0.5 เพียงพอสำหรับใกล้ๆ)
WiFi.setTxPower(WIFI_POWER_2dBm); // ต่ำสุด3️⃣ ปิด Peripherals ที่ไม่ใช้
ปิดส่วนประกอบที่ไม่จำเป็นเพื่อประหยัดไฟ:
// ปิด Bluetooth
btStop();
// ปิด ADC2 (ถ้าไม่ใช้)
adc_power_off();
// ปิด GPIO ที่ไม่ใช้
gpio_deep_sleep_hold_dis();4️⃣ เลือกเซ็นเซอร์ที่ประหยัดไฟ
เปรียบเทียบการใช้พลังงานของเซ็นเซอร์:
| เซ็นเซอร์ | กระแส (Active) | กระแส (Sleep) |
|---|---|---|
| DHT22 | 1-2.5mA | 0.1µA |
| DHT11 | 0.5-2.5mA | 0.1µA |
| BME280 | 0.6mA | 0.1µA |
5️⃣ ใช้แบตเตอรี่ขนาดใหญ่กว่า
เปลี่ยนจาก 18650 (2000-3000mAh) เป็น:
- • Li-Ion 18650 3500mAh → อายุ ~2.5 เดือน
- • Li-Po 5000mAh → อายุ ~4 เดือน
- • Solar Panel + Battery → ใช้ได้ตลอดกาล (ตามสภาพอากาศ)
🎯 สรุปเทคนิคทั้งหมด
ถ้าใช้ทุกเทคนิคร่วมกัน อาจทำให้เซ็นเซอร์โหนดทำงานได้ 3-6 เดือน บนแบตเตอรี่ 18650 เพียงก้อนเดียว!
🔧 การแก้ปัญหา
ปัญหา: ESP32 ไม่ยอมตื่นจาก Deep Sleep
สาเหตุ: Timer ตั้งค่าไม่ถูกต้อง, Hardware ขัดข้อง
วิธีแก้:
- ตรวจสอบว่าใช้
esp_deep_sleep_enable_timer_wakeup()ถูกต้อง - ลองเพิ่มเวลานอน (TIME_TO_SLEEP) ให้มากขึ้น
- ตรวจสอบว่าไม่ได้ใช้ Pin ที่ขัดข้องกับ Deep Sleep (GPIO 0, 2, 15, etc.)
- ลองใช้ตัวอย่างโค้ดจาก Espressif เปรียบเทียบ
ปัญหา: WiFi เชื่อมต่อไม่ได้หลังตื่น
สาเหตุ: WiFi ไม่ได้ถูกเริ่มต้นใหม่หลัง Deep Sleep
วิธีแก้:
// ใน setup() หรือก่อนเชื่อมต่อ WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);ปัญหา: DHT22 อ่านค่าไม่ได้ (NaN)
สาเหตุ: ต่อสายผิด, เซ็นเซอร์เสีย, ไม่มี Pull-up resistor
วิธีแก้:
- ตรวจสอบการเชื่อมต่อ VCC, DATA, GND
- ต้องมี Pull-up Resistor 10KΩ ระหว่าง DATA และ VCC
- รอ 2 วินาทีหลังเปิดไฟก่อนอ่านค่า:
delay(2000); - ลองเปลี่ยนเป็น DHT11 เพื่อทดสอบ
ปัญหา: แบตเตอรี่หมดเร็วเกินไป
สาเหตุ: Deep Sleep ไม่ทำงาน, อ่านค่าถี่เกินไป, ส่วนประกอบอื่นกินไฟ
วิธีแก้:
- ตรวจสอบ Serial Monitor ว่า ESP32 กลับเข้า Deep Sleep จริงไหม
- เพิ่มเวลานอน (เช่น อ่านทุก 30 นาทีแทน 10 นาที)
- ตรวจสอบว่าปิด WiFi ก่อนเข้า Deep Sleep แล้ว
- ลองวัดกระแสด้วย Multimeter ว่าอยู่ที่ ~10µA หรือไม่
ปัญหา: ส่งข้อมูลไป CynoIoT ไม่ได้
สาเหตุ: Device Token ผิด, URL ผิด, WiFi ไม่ได้เชื่อมต่อ
วิธีแก้:
- ตรวจสอบ Device Token ใน CynoIoT Dashboard
- ตรวจสอบว่า URL ถูกต้อง:
https://api.cynoiot.com/v1/sensor/data - ดู HTTP Response code ใน Serial Monitor
- ลองใช้ Postman หรือ curl ทดสอบ API แยก
🎉 สรุป
ในบทความนี้คุณได้เรียนรู้วิธีสร้างเซ็นเซอร์โหนด ESP32 ที่ประหยัดพลังงานด้วย Deep Sleep Mode สามารถทำงานด้วยแบตเตอรี่ได้นานหลายเดือน เหมาะสำหรับโปรเจกต์ IoT ที่ต้องการติดตั้งไว้ที่ไหนก็ได้โดยไม่ต้องเสียบปลั๊ก
✅ สิ่งที่คุณได้เรียนรู้
- ✅ เข้าใจการทำงานของ Deep Sleep Mode บน ESP32
- ✅ คำนวณอายุการใช้งานแบตเตอรี่สำหรับเซ็นเซอร์โหนด
- ✅ เขียนโปรแกรมจัดการ Deep Sleep ด้วย Timer
- ✅ เลือกใช้เซ็นเซอร์และอุปกรณ์ที่ประหยัดพลังงาน
- ✅ เชื่อมต่อเซ็นเซอร์โหนดเข้ากับ CynoIoT Platform
- ✅ ใช้เทคนิคประหยัดไฟเพิ่มเติมเพื่อยืดอายุแบตเตอรี่
🚀 ไอเดียต่อยอด
- • สวนอัจฉริยะ: เพิ่ม Soil Moisture Sensor เพื่อวัดความชื้นดิน
- • ระบบเตือนน้ำท่วม: เพิ่ม Water Level Sensor
- • Station วัดอากาศ: เพิ่ม BMP280 วัดความดันอากาศ
- • Smart Mailbox: เพิ่ม Reed Switch ตรวจจับจดหมาย
- • สัตว์เลี้ยงอัจฉริยะ: เพิ่ม PIR Sensor ตรวจจับการเคลื่อนไหว
- • Solar Powered: เพิ่ม Solar Panel + MPPT Charger ใช้ได้ตลอดกาล
📚 บทความที่เกี่ยวข้อง
หวังว่าบทความนี้จะเป็นประโยชน์! ถ้ามีคำถามหรือต้องการคำแนะนำเพิ่มเติม สามารถติดต่อได้ที่ CynoIoT Community หรือแสดงความคิดเห็นด้านล่างได้เลยครับ 🤙