สร้างระบบ Smart Home ด้วย ESP32, MQTT และ Node-RED

เรียนรู้วิธีสร้างระบบอัตโนมัติสำหรับบ้านอัจฉริยะด้วย ESP32 เชื่อมต่อ MQTT Broker และควบคุมผ่าน Node-RED Dashboard พร้อมโค้ดตัวอย่างและคำอธิบายภาษาไทย

📅 11 มีนาคม 2026⏱️ 15 นาที🎯 ระดับกลาง

แนะนำ

MQTT (Message Queuing Telemetry Transport) เป็นโปรโตคอลการสื่อสารแบบ Publish/Subscribe ที่เบาเพียงและเหมาะสำหรับอุปกรณ์ IoT ที่มีทรัพยากรจำกัด เมื่อรวมกับ Node-RED ซึ่งเป็นเครื่องมือสร้าง Flow แบบ Visual Programming คุณจะสามารถสร้างระบบ Smart Home ที่ยืดหยุ่นและทรงพลังได้อย่างง่ายดาย

ในบทความนี้ คุณจะได้เรียนรู้วิธีการเชื่อมต่อ ESP32 เข้ากับ MQTT Broker ส่งข้อมูลเซ็นเซอร์และควบคุม Relay ผ่าน Node-RED Dashboard พร้อมตัวอย่างโค้ดและการตั้งค่าที่สมบูรณ์

ข้อกำหนดเบื้องต้น

Hardware ที่ต้องใช้

  • ESP32 Development Board (ตัวไหนก็ได้)
  • Relay Module 1-4 ช่อง
  • DHT22 Temperature & Humidity Sensor (หรือ DHT11)
  • Jumper Wires (สายไฟเชื่อมต่อ)
  • Breadboard (ไม่บังคับ)
  • LED และ Resistor 330Ω (สำหรับทดสอบ)

Software ที่ต้องใช้

  • Arduino IDE หรือ PlatformIO
  • MQTT Broker (แนะนำ Mosquitto หรือ HiveMQ Cloud)
  • Node-RED (ติดตั้งบน Raspberry Pi หรือ Docker)
  • Library: PubSubClient สำหรับ Arduino
  • Library: DHT สำหรับอ่านค่าเซ็นเซอร์

หมายเหตุ: หากคุณยังไม่มี MQTT Broker สามารถใช้บริการฟรีจาก HiveMQ Cloud หรือ EMQX Cloud ได้

พื้นฐาน MQTT ที่ควรรู้

MQTT ทำงานด้วยรูปแบบ Publish/Subscribe ซึ่งแตกต่างจาก HTTP Request/Response ทั่วไป:

Publisher

อุปกรณ์ที่ส่งข้อมูล (เช่น ESP32 ที่อ่านค่าเซ็นเซอร์)

Subscriber

อุปกรณ์ที่รับข้อมูล (เช่น Node-RED หรือ ESP32 อื่น)

Broker

เซิร์ฟเวอร์กลางที่คัดกรองและส่งต่อข้อความ

Topic

ชื่อหัวข้อที่ใช้จัดหมวดหมู่ข้อความ (เช่น home/livingroom/temp)

Topic Structure แนะนำ

home/livingroom/temperature
home/livingroom/humidity
home/livingroom/relay1
home/livingroom/relay2

การต่อวงจร Hardware

การต่อ DHT22 Sensor

DHT22 PinESP32 Pin
VCC3.3V
DataGPIO 4
GNDGND

การต่อ Relay Module

Relay PinESP32 Pin
VCC5V (หรือ VIN)
IN1GPIO 12
IN2 (ถ้ามี)GPIO 14
GNDGND

คำเตือน: Relay ใช้ไฟ 5V ในขณะที่ ESP32 ใช้ 3.3V ตรวจสอบให้แน่ใจว่า Relay Module ของคุณรองรับ 3.3V Logic หรือไม่ หรือใช้ Level Shifter

โค้ด ESP32 สำหรับ MQTT

นี่คือโค้ดสมบูรณ์สำหรับ ESP32 ที่เชื่อมต่อ MQTT อ่านค่า DHT22 และควบคุม Relay:

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

// WiFi Credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// MQTT Configuration
const char* mqtt_server = "broker.hivemq.com";  // หรือ IP ของ MQTT Broker ของคุณ
const int mqtt_port = 1883;

// Topics
const char* temp_topic = "home/livingroom/temperature";
const char* hum_topic = "home/livingroom/humidity";
const char* relay1_topic = "home/livingroom/relay1";
const char* relay2_topic = "home/livingroom/relay2";

// Pin Definitions
#define DHTPIN 4
#define DHTTYPE DHT22
#define RELAY1_PIN 12
#define RELAY2_PIN 14

DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);

// ตัวแปรสำหรับเก็บค่าเซ็นเซอร์
float lastTemp = 0;
float lastHum = 0;
unsigned long lastSensorTime = 0;
const long sensorInterval = 5000;  // อ่านค่าทุก 5 วินาที

// เชื่อมต่อ WiFi
void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

// Callback เมื่อได้รับ MQTT message
void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("]: ");
  
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    messageTemp += (char)message[i];
  }
  Serial.println(messageTemp);

  // ควบคุม Relay 1
  if (String(topic) == relay1_topic) {
    if (messageTemp == "ON") {
      digitalWrite(RELAY1_PIN, HIGH);
      Serial.println("Relay 1 turned ON");
    } else if (messageTemp == "OFF") {
      digitalWrite(RELAY1_PIN, LOW);
      Serial.println("Relay 1 turned OFF");
    }
  }
  
  // ควบคุม Relay 2
  if (String(topic) == relay2_topic) {
    if (messageTemp == "ON") {
      digitalWrite(RELAY2_PIN, HIGH);
      Serial.println("Relay 2 turned ON");
    } else if (messageTemp == "OFF") {
      digitalWrite(RELAY2_PIN, LOW);
      Serial.println("Relay 2 turned OFF");
    }
  }
}

// เชื่อมต่อ MQTT Broker ใหม่
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // สร้าง Client ID แบบสุ่ม
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      
      // Subscribe หัวข้อที่ต้องการรับ
      client.subscribe(relay1_topic);
      client.subscribe(relay2_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

// อ่านค่าเซ็นเซอร์และส่งข้อมูล
void readAndSendSensorData() {
  unsigned long currentTime = millis();
  
  if (currentTime - lastSensorTime >= sensorInterval) {
    lastSensorTime = currentTime;
    
    // อ่านค่าอุณหภูมิและความชื้น
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    
    // ตรวจสอบว่าอ่านค่าได้หรือไม่
    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    
    // แปลงค่าเป็น String
    char tempStr[8];
    char humStr[8];
    dtostrf(t, 2, 2, tempStr);
    dtostrf(h, 2, 2, humStr);
    
    // ส่งข้อมูลไปยัง MQTT
    client.publish(temp_topic, tempStr);
    client.publish(hum_topic, humStr);
    
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.print("°C, Humidity: ");
    Serial.print(h);
    Serial.println("%");
  }
}

void setup() {
  Serial.begin(115200);
  
  // ตั้งค่า Pin
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(RELAY2_PIN, OUTPUT);
  
  // ปิด Relay เริ่มต้น
  digitalWrite(RELAY1_PIN, LOW);
  digitalWrite(RELAY2_PIN, LOW);
  
  // เริ่มต้นเซ็นเซอร์
  dht.begin();
  
  // เชื่อมต่อ WiFi
  setup_wifi();
  
  // ตั้งค่า MQTT
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  // ตรวจสอบการเชื่อมต่อ MQTT
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  // อ่านและส่งข้อมูลเซ็นเซอร์
  readAndSendSensorData();
}

เคล็ดลับ: อย่าลืมเปลี่ยน YOUR_WIFI_SSID และ YOUR_WIFI_PASSWORD เป็นค่าของคุณ และแก้ไข MQTT Broker Address หากใช้บริการอื่น

การติดตั้งและตั้งค่า Node-RED

ติดตั้ง Node-RED บน Raspberry Pi

# อัปเดตระบบ
sudo apt update && sudo apt upgrade -y

# ติดตั้ง Node.js
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# ติดตั้ง Node-RED
sudo npm install -g --unsafe-perm node-red

# ติดตั้ง Node-RED เพื่อเริ่มต้นอัตโนมัติ
sudo systemctl enable nodered.service
sudo systemctl start nodered.service

# ตรวจสอบสถานะ
sudo systemctl status nodered.service

หลังจากติดตั้งเสร็จ เข้าถึง Node-RED ผ่าน http://<IP_ADDRESS>:1880

ติดตั้ง Node-RED Dashboard

# เข้าไปที่ directory ของ Node-RED
cd ~/.node-red

# ติดตั้ง Dashboard
npm install node-red-dashboard

# รีสตาร์ท Node-RED
sudo systemctl restart nodered.service

สร้าง Flow ใน Node-RED

ส่วนที่ 1: รับข้อมูลจาก ESP32

  1. ลาก MQTT In node มาวาง
  2. ดับเบิลคลิกและตั้งค่า:
    • Connection: เพิ่มการเชื่อมต่อ MQTT Broker ใหม่
    • Topic: home/livingroom/temperature
    • Output: String
  3. ลาก Gauge node จาก Dashboard มาวาง
  4. ตั้งค่า Gauge สำหรับแสดงผลอุณหภูมิ
  5. เชื่อมต่อ MQTT In → Gauge

ส่วนที่ 2: ควบคุม Relay

  1. ลาก Switch node จาก Dashboard มาวาง
  2. ตั้งค่า:
    • Name: Relay 1
    • Topic: home/livingroom/relay1
    • Output: "ON" / "OFF"
  3. ลาก MQTT Out node มาวาง
  4. ตั้งค่า Topic เป็น home/livingroom/relay1
  5. เชื่อมต่อ Switch → MQTT Out

ส่วนที่ 3: แสดงผลใน Dashboard

  1. คลิกที่ไอคอน Dashboard ด้านขวาบน
  2. สร้าง Tab ใหม่ชื่อ "Living Room"
  3. สร้าง Group และลาก Widget ต่างๆ มาจัดวาง:
    • Gauge สำหรับ Temperature
    • Gauge สำหรับ Humidity
    • Switch สำหรับ Relay 1
    • Switch สำหรับ Relay 2
    • Chart สำหรับแสดงกราฟย้อนหลัง

การทดสอบระบบ

ตรวจสอบการเชื่อมต่อ MQTT

  1. อัปโหลดโค้ดไปยัง ESP32
  2. เปิด Serial Monitor (115200 baud)
  3. ตรวจสอบว่า ESP32 เชื่อมต่อ WiFi และ MQTT สำเร็จหรือไม่
  4. ดูใน Serial Monitor ว่ามีข้อความ "Temperature: XX°C, Humidity: XX%" แสดงหรือไม่

ทดสอบใน Node-RED

  1. ไปที่ http://<RASPBERRY_PI_IP>:1880/ui
  2. ดูว่ามีค่าอุณหภูมิและความชื้นแสดงผลหรือไม่
  3. กดปุ่ม Switch เพื่อควบคุม Relay
  4. ฟังเสียง "คลิก" จาก Relay และดู Serial Monitor

ยินดีด้วย! ตอนนี้คุณมีระบบ Smart Home ขั้นพื้นฐานที่ทำงานได้แล้ว

เทคนิคขั้นสูง

1. บันทึกข้อมูลลง Database

ใช้ InfluxDB หรือ SQLite เพื่อบันทึกข้อมูลเซ็นเซอร์ย้อนหลัง:

# ติดตั้ง InfluxDB
sudo apt install influxdb influxdb-client

# ติดตั้ง node-red-contrib-influxdb ใน Node-RED
cd ~/.node-red
npm install node-red-contrib-influxdb

2. รับการแจ้งเตือนด้วย Telegram

ส่งการแจ้งเตือนเมื่ออุณหภูมิสูงเกินกำหนด:

  • สร้าง Telegram Bot ผ่าน @BotFather
  • ติดตั้ง node-red-contrib-telegrambot
  • สร้าง Flow: MQTT In → Function (ตรวจสอบค่า) → Telegram Out

3. ควบคุมด้วย Voice Command

ใช้ Google Assistant หรือ Alexa ผ่าน IFTTT หรือ Home Assistant เพื่อควบคุม Relay ด้วยเสียง

การแก้ปัญหา

ปัญหา: ESP32 เชื่อมต่อ MQTT ไม่ได้

สาเหตุ: IP ผิด, Port ผิด, หรือ Firewall บล็อก

วิธีแก้: ตรวจสอบ MQTT Broker Address และ Port, ปิด Firewall ชั่วคราวเพื่อทดสอบ

ปัญหา: ค่าเซ็นเซอร์อ่านไม่ได้

สาเหตุ: DHT22 เสีย, ต่อสายผิด, หรือ Pin ผิด

วิธีแก้: ตรวจสอบการต่อสาย, เปลี่ยน DHT22, ลองเพิ่ม Resistor 10K ระหว่าง VCC และ Data

ปัญหา: Relay ไม่ทำงาน

สาเหตุ: Pin ผิด, Relay ต้องการ 5V แต่ ESP32 ให้ 3.3V

วิธีแก้: ใช้ External 5V Power Supply, ตรวจสอบ Pin IN, ลองใช้ Transistor

ปัญหา: Node-RED Dashboard ไม่แสดงผล

สาเหตุ: MQTT Subscribe ผิด, Node ไม่ได้ deploy

วิธีแก้: กด Deploy ใหม่, ตรวจสอบ Topic ให้ตรงกัน, ดู Debug messages

สรุป

ในบทความนี้ คุณได้เรียนรู้วิธีสร้างระบบ Smart Home ขั้นพื้นฐานด้วย ESP32, MQTT และ Node-RED ตั้งแต่การต่อวงจร เขียนโค้ด ติดตั้ง Node-RED ไปจนถึงการสร้าง Dashboard คุณสามารถขยายระบบนี้ได้โดยการเพิ่มเซ็นเซอร์ประเภทต่างๆ, บันทึกข้อมูลลง Database, หรือเชื่อมต่อกับระบบ Automation อื่นๆ

บทความที่เกี่ยวข้อง