กลับหน้าหลัก
views
วิธีต่อ MQTT กับ ESP32 ให้เสถียรและประหยัดแบตเตอรี่ สำหรับโปรเจกต์ IoT จริง
Last updated on

วิธีต่อ MQTT กับ ESP32 ให้เสถียรและประหยัดแบตเตอรี่ สำหรับโปรเจกต์ IoT จริง


เตรียมของให้พร้อม!

โปรเจคนี้ต้องใช้: เซ็นเซอร์วัดแสง LUX Sensor Light Meter Interface I2C IIC VEML7700 TSL2591 Arduino ESP32

🛒 สั่งซื้อที่ Shopee

บทนำ: ทำไม MQTT บน ESP32 ถึงมีปัญหาบ่อย

เวลาทำโปรเจกต์ IoT ที่ใช้แบตเตอรี่ คนส่วนใหญ่เจอปัญหาเดียวกันคือ ESP32 ต่อ MQTT ได้แค่ 2-3 วันก็หมดแล้ว หรือไม่ก็ MQTT หลุดบ่อยจนระบบทำงานไม่ได้ นี่ไม่ใช่เพราะ ESP32 แย่ แต่เป็นเพราะวิธีใช้งานที่ไม่เหมาะสม

บทความนี้จะอธิบาย วิธีต่อ MQTT กับ ESP32 ให้เสถียรและประหยัดแบตเตอรี่จริงๆ โดยผมจะเล่าจากประสบการณ์ที่ใช้งานจริงในหลายโปรเจกต์ ไม่ใช่ copy จาก docs แล้วมาต่อกัน

[image: ผลเปรียบเทียบการใช้พลังงานของ ESP32 ระหว่างโหมดต่างๆ]

อุปกรณ์และซอฟต์แวร์ที่ต้องเตรียม

ก่อนเริ่มต้น เตรียมอุปกรณ์ดังนี้:

  • บอร์ด ESP32 (แนะนำ ESP32-WROOM หรือ ESP32-C3 สำหรับประหยัดไฟ)
  • แหล่งจ่ายไฟ (ถ้าใช้แบตเตอรี่ แนะนำ 18650 LiPo หรือ LiFePO4)
  • MQTT Broker (Mosquitto บน server, หรือใช้ cloud service อย่าง HiveMQ Cloud ก็ได้)
  • Arduino IDE หรือ PlatformIO
  • ไลบรารี PubSubClient สำหรับ MQTT

ถ้าใครยังไม่คุ้นกับ ESP32 แนะนำอ่านบทความ ESP32 คืออะไร? เจาะลึกบอร์ด IoT ยอดนิยมที่แรงกว่า Arduino ก่อนนะครับ

การตั้งค่า MQTT Broker สำหรับ ESP32

ก่อนเขียนโค้ดบน ESP32 ต้องตั้งค่า broker ให้รองรับการเชื่อมต่อแบบประหยัดพลังงานก่อน

# mosquitto.conf สำหรับ IoT ประหยัดไฟ
max_keepalive 300
persistent_client_expiration 2h
max_connections 500

จุดสำคัญคือ max_keepalive ห้ามตั้งต่ำเกินไป ถ้าตั้ง 60 วินาที ESP32 ที่ sleep 10 นาทีจะถูกตัดทุกครั้ง แนะนำ 300 วินาทีขึ้นไป และ persistent_client_expiration ให้เผื่อไว้นานกว่า cycle ส่งข้อมูลสูงสุด 2-3 เท่า

[image: หน้าจอ config Mosquitto broker สำหรับ IoT]

โค้ด MQTT พื้นฐานบน ESP32 ที่ใช้งานได้จริง

#include <WiFi.h>
#include <PubSubClient.h>

// ตั้งค่า WiFi
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// ตั้งค่า MQTT
const char* mqtt_server = "192.168.1.100";
const int mqtt_port = 1883;
const char* mqtt_client_id = "esp32_sensor_01";  // ต้องคงที่!
const char* mqtt_user = "mqtt_user";
const char* mqtt_pass = "mqtt_pass";

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  int retry = 0;
  while (WiFi.status() != WL_CONNECTED && retry < 20) {
    delay(500);
    retry++;
  }
  
  if (WiFi.status() != WL_CONNECTED) {
    ESP.restart();  // ถ้าต่อไม่ได้ restart ใหม่ดีกว่ารอ
  }
}

void reconnect_mqtt() {
  while (!client.connected()) {
    if (client.connect(mqtt_client_id, mqtt_user, mqtt_pass, 
                       "esp32/offline", 1, true, "disconnected")) {
      client.publish("esp32/online", "connected");
    } else {
      delay(2000);  // รอก่อน retry
    }
  }
}

void setup() {
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  reconnect_mqtt();
}

void loop() {
  if (!client.connected()) {
    reconnect_mqtt();
  }
  client.loop();
}

สิ่งที่ต้องสังเกต:

  • ใช้ client_id คงที่เสมอ เพื่อให้ broker จำ session ได้
  • ถ้าต่อ WiFi ไม่ได้ใน 20 วินาที ให้ restart แทนที่จะรอต่อไป เพราะจะทำให้ drain แบตเตอรี่เร็วมาก
  • ส่ง “online” กับ “offline” topic ด้วย เพื่อตรวจสอบสถานะได้ง่าย

[image: ภาพ Serial Monitor แสดงสถานะการเชื่อมต่อ MQTT ของ ESP32]

Deep Sleep: กุญแจสำคัญของการประหยัดแบตเตอรี่

ESP32 กินไฟประมาณ 80-120mA เวลาทำงาน แต่ Deep Sleep กินแค่ 10-15µA ถ้าใช้วัดข้อมูลทุก 10 นาที แล้ว sleep ที่เหลือ จะประหยัดได้มากกว่า 99%

#define uS_TO_S_FACTOR 1000000  // ไมโครวินาที to วินาที
#define TIME_TO_SLEEP  600      // sleep 10 นาที

void goToSleep() {
  // ส่ง offline ก่อน sleep
  client.publish("esp32/offline", "sleeping");
  client.disconnect();  // สำคัญมาก! ต้อง disconnect ก่อน
  delay(100);
  
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}

ข้อผิดพลาดที่พบบ่อย: หลายคนลืม client.disconnect() ก่อน deep sleep ทำให้ broker รอ timeout นานมาก และ ESP32 ก็ยังกินไฟในโหมด sleep อยู่

การตื่นขึ้นมา reconnect อย่างรวดเร็ว

void setup() {
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  reconnect_mqtt();
  
  // อ่านค่าเซ็นเซอร์และส่ง
  float temp = readTemperature();
  char payload[50];
  snprintf(payload, 50, "{\"temp\": %.2f, \"bat\": %d}", temp, getBattery());
  client.publish("sensor/data", payload);
  
  delay(100);
  goToSleep();
}

ถ้าใช้เซ็นเซอร์วัดแสงด้วย แนะนำ เซ็นเซอร์วัดแสง LUX Sensor VEML7700 หรือ TSL2591 ซึ่งใช้ I2C กับ ESP32 ได้เลย ให้ค่าที่แม่นยำและกินไฟน้อย

เทคนิคเพิ่มเติมสำหรับความเสถียร

1. WiFi Reconnect Handler

void WiFiEvent(WiFiEvent_t event) {
  switch(event) {
    case SYSTEM_EVENT_STA_DISCONNECTED:
      WiFi.reconnect();
      break;
  }
}

void setup() {
  WiFi.onEvent(WiFiEvent);
  // ...
}

2. Watchdog Timer

void loop() {
  if (!client.connected()) {
    reconnect_mqtt();
  }
  client.loop();
  
  // ถ้า loop ทำงานนานเกินไปโดยไม่มี response ให้ restart
  if (millis() - lastActivity > 60000) {
    ESP.restart();
  }
}

3. Keep Alive ที่เหมาะสม

client.setKeepAlive(120);  // 120 วินาที สำหรับ cycle 10 นาที

keep-alive ควรสั้นกว่า sleep time แต่ไม่สั้นเกินไปจนเปลืองพลังงาน ถ้า sleep 10 นาที ใช้ 120 วินาที (2 นาที) กำลังดี

[image: กราฟเปรียบเทียบการใช้ไฟระหว่าง ESP32 ที่ใช้ Deep Sleep กับไม่ใช้]

การใช้ Dashboard ตรวจสอบสถานะ

เมื่อตั้งค่า MQTT บน ESP32 เรียบร้อยแล้ว อยากดูข้อมูลแบบ real-time แนะนำตั้ง Dashboard ดูได้เลย มีบทความ คู่มือเริ่มต้น Dashboard กราฟเรียลไทม์ ที่อธิบายวิธีต่อ ESP32 กับ Dashboard แบบละเอียด

สำหรับคนที่อยากลองทำ weather station มีโปรเจกต์ตัวอย่าง WIoT-2 Weather Station ที่ใช้ MQTT กับ ESP32 อยู่แล้ว

สรุป

การทำให้ MQTT บน ESP32 เสถียรและประหยัดไฟไม่ใช่เรื่องยาก แค่ต้องรู้จัก:

  1. Disconnect ก่อน deep sleep - ทุกครั้ง
  2. ใช้ client ID คงที่ - เพื่อให้ broker จำ session
  3. ตั้ง keep-alive ให้เหมาะสม - สั้นกว่า sleep time
  4. Restart เมื่อ WiFi ต่อไม่ได้ - ไม่งอมิงีรอ
  5. ส่ง online/offline status - เพื่อตรวจสอบง่าย

ถ้าทำตามนี้ ESP32 ต่อแบตเตอรี่ LiFePO4 ขนาด 3000mAh ส่งข้อมูลทุก 10 นาที อยู่ได้ประมาณ 3-6 เดือน ไม่ใช่ 2-3 วันแล้ว

อยากทำโปรเจคแบบนี้?

รับทำโปรเจค Arduino / IoT จบงานไว ส่งงานครบ พร้อมสอน

หากต้องการ รับทำโปรเจคอาดูโน่ หรือระบบ IoT แบบเร่งด่วน สามารถดูรายละเอียดบริการได้ที่หน้าแรก

จ้างทำโปรเจคเลย

ความคิดเห็น

Verified user reviews

รีวิวและความคิดเห็นจากผู้ใช้จริง

ล็อกอินด้วยบัญชีบนเว็บนี้แล้วให้คะแนนหรือคอมเมนต์ได้เลย ระบบเก็บผ่าน Supabase ไม่ต้องใช้ GitHub แล้ว

กำลังโหลดรีวิว...