เนื้อหาในบทความ
MQTT คืออะไร?
MQTT (Message Queuing Telemetry Transport) คือโปรโตคอลสื่อสารแบบ Lightweight ที่ออกแบบมาสำหรับ IoT devices โดยเฉพาะ ทำงานบน TCP/IP และใช้รูปแบบ Publish/Subscribe ในการส่งข้อมูล
MQTT เป็นที่นิยมเพราะ:
- 🚀 เบาและรวดเร็ว - ใช้ bandwidth น้อยมาก
- 📡 Real-time - ส่งข้อมูลได้ทันทีทันใด
- 🔌 Support QoS - รับประกันการส่งข้อมูล (Quality of Service)
- 🌐 Easy Integration - เชื่อมต่อกับ Cloud และ Local Server ได้ง่าย
- 💡 Low Power - เหมาะกับอุปกรณ์ที่ใช้แบตเตอรี่
💡 ตัวอย่างการใช้งาน: ส่งค่าอุณหภูมิจาก ESP32 ไปยัง Server, ควบคุมหลอดไฟผ่านมือถือ, รับแจ้งเตือนจากเซ็นเซอร์, เชื่อมต่อกับ CynoIoT Platform
หลักการทำงานของ MQTT
ส่วนประกอบหลัก
📡 MQTT Broker
Server ที่ทำหน้าที่เป็นตัวกลางรับและส่งข้อมูลระหว่าง devices
📤 Publisher
Device ที่ส่งข้อมูล (เช่น ESP32 ส่งค่าอุณหภูมิ)
📥 Subscriber
Device ที่รับข้อมูล (เช่น มือถือ, Web Dashboard)
Topic และ Message
Topic คือ "ช่องทาง" ที่ใช้ส่งข้อมูล เหมือน "หมวดหมู่" ที่ devices ใช้รู้ว่าจะส่ง/รับข้อมูลเรื่องอะไร
ตัวอย่าง Topic:
home/livingroom/temperature- อุณหภูมิห้องนั่งเล่นhome/bedroom/light- ไฟห้องนอนsensor/#- ทุกเซ็นเซอร์ (Wildcard)
Quality of Service (QoS)
| ระดับ | ชื่อ | คำอธิบาย |
|---|---|---|
| 0 | At most once | ส่งไปเลย ไม่รอ ACK (เร็วสุด) |
| 1 | At least once | รับประกันส่งถึง (มีซ้ำได้) |
| 2 | Exactly once | รับประกันส่งครั้งเดียว (ช้าสุด) |
* สำหรับ IoT ส่วนใหญ่ใช้ QoS 0 หรือ 1 เพียงพอ
อุปกรณ์ที่ต้องการ
Hardware
- ESP32 Development Board (NodeMCU, Wemos, หรือ Generic)
- USB Cable สำหรับ programming
- (Optional) DHT11/DHT22 Sensor สำหรับทดสอบ
- (Optional) Relay Module สำหรับควบคุมไฟ
Software
- Arduino IDE (version 1.8.x หรือ 2.x)
- MQTT Broker (ใช้ฟรีจาก HiveMQ, EMQX หรือ Local Server)
- MQTT Client สำหรับทดสอบ (MQTT Explorer, MQTT.fx)
🔧 Tip: สำหรับการทดสอบ สามารถใช้ Public MQTT Broker ฟรีได้ เช่น:
broker.hivemq.com(Port 1883)test.mosquitto.org(Port 1883)broker.emqx.io(Port 1883)
ติดตั้ง Library
วิธีที่ 1: ติดตั้งผ่าน Arduino IDE Library Manager
- เปิด Arduino IDE
- ไปที่ Sketch → Include Library → Manage Libraries
- ค้นหา "PubSubClient"
- กด Install เวอร์ชันล่าสุด
วิธีที่ 2: ติดตั้งผ่าน Terminal
# สำหรับ Arduino IDE 2.x
# จะติดตั้งอัตโนมัติเมื่อ include ในโค้ดตรวจสอบการติดตั้ง
สร้างไฟล์ใหม่แล้วลอง include library:
#include <WiFi.h>
#include <PubSubClient.h>
void setup() {
// ถ้าไม่มี error แปลว่าติดตั้งสำเร็จ
}
void loop() {
}Publish/Subscribe พื้นฐาน
ตัวอย่างที่ 1: Hello MQTT
โค้ดนี้เชื่อมต่อ ESP32 กับ MQTT Broker และส่งข้อความ "Hello from ESP32" ทุก 5 วินาที
#include <WiFi.h>
#include <PubSubClient.h>
// ===== WiFi Credentials =====
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// ===== MQTT Broker Settings =====
const char* mqtt_server = "broker.hivemq.com"; // หรือ IP ของ broker คุณเอง
const int mqtt_port = 1883;
// ===== Topics =====
const char* mqtt_topic = "cynoiot/esp32/test";
// ===== Objects =====
WiFiClient espClient;
PubSubClient client(espClient);
// ===== Variables =====
unsigned long lastMsg = 0;
const long interval = 5000; // ส่งทุก 5 วินาที
// ===== WiFi Setup =====
void setup_wifi() {
delay(10);
Serial.println("\nเชื่อมต่อ WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi เชื่อมต่อสำเร็จ!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
// ===== MQTT Callback =====
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("มีข้อความมาจาก topic: ");
Serial.print(topic);
Serial.print(". ข้อความ: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// ประมวลผลข้อความที่ได้รับ
if (String(topic) == mqtt_topic) {
if (messageTemp == "on") {
Serial.println("เปิดอุปกรณ์!");
// digitalWrite(ledPin, HIGH);
} else if (messageTemp == "off") {
Serial.println("ปิดอุปกรณ์!");
// digitalWrite(ledPin, LOW);
}
}
}
// ===== Reconnect to MQTT =====
void reconnect() {
// ลองเชื่อมต่อจนกว่าจะสำเร็จ
while (!client.connected()) {
Serial.print("กำลังเชื่อมต่อ MQTT...");
// สร้าง Client ID แบบสุ่ม
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
// พยายามเชื่อมต่อ
if (client.connect(clientId.c_str())) {
Serial.println("เชื่อมต่อสำเร็จ!");
// Subscribe topic
client.subscribe(mqtt_topic);
Serial.print("Subscribe topic: ");
Serial.println(mqtt_topic);
} else {
Serial.print("เชื่อมต่อไม่สำเร็จ, rc=");
Serial.print(client.state());
Serial.println(" ลองใหม่ใน 5 วินาที");
delay(5000);
}
}
}
// ===== Setup =====
void setup() {
Serial.begin(115200);
// เชื่อมต่อ WiFi
setup_wifi();
// ตั้งค่า MQTT
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
// ===== Loop =====
void loop() {
// ตรวจสอบการเชื่อมต่อ MQTT
if (!client.connected()) {
reconnect();
}
client.loop(); // ต้องมีเพื่อให้ callback ทำงาน
// ส่งข้อความทุก 5 วินาที
unsigned long now = millis();
if (now - lastMsg > interval) {
lastMsg = now;
// สร้างข้อความ
String msg = "Hello from ESP32! Uptime: " + String(millis() / 1000) + "s";
// ส่งข้อความ
Serial.println("ส่งข้อความ: " + msg);
client.publish(mqtt_topic, msg.c_str());
}
}💡 ทดสอบด้วย MQTT Explorer:
- ดาวน์โหลด MQTT Explorer
- เชื่อมต่อไปที่
broker.hivemq.com:1883 - Subscribe topic:
cynoiot/esp32/test - ดูข้อความที่ ESP32 ส่งมา!
ตัวอย่างที่ 2: ส่งค่าเซ็นเซอร์อุณหภูมิ
ในตัวอย่างนี้ เราจะใช้ DHT11/DHT22 วัดอุณหภูมิและความชื้น แล้วส่งค่าไปยัง MQTT Broker
วิธีต่อสาย DHT11/22
- VCC: 3.3V หรือ 5V (ตามรุ่น)
- Data: GPIO 4 (หรือขาอื่นที่ต้องการ)
- GND: GND
* ให้ต่อตัวต้านทาน 10kΩ ระหว่าง VCC และ Data (Pull-up)
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// ===== WiFi & MQTT =====
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* mqtt_server = "broker.hivemq.com";
// ===== DHT Sensor =====
#define DHTPIN 4 // GPIO 4
#define DHTTYPE DHT11 // DHT11 หรือ DHT22
DHT dht(DHTPIN, DHTTYPE);
// ===== Topics =====
const char* temp_topic = "cynoiot/sensor/temperature";
const char* hum_topic = "cynoiot/sensor/humidity";
// ===== Objects =====
WiFiClient espClient;
PubSubClient client(espClient);
// ===== Variables =====
unsigned long lastSensorRead = 0;
const long sensorInterval = 10000; // อ่านทุก 10 วินาที
void setup_wifi() {
delay(10);
Serial.println("\nเชื่อมต่อ WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi เชื่อมต่อสำเร็จ!");
}
void reconnect() {
while (!client.connected()) {
Serial.print("เชื่อมต่อ MQTT...");
String clientId = "ESP32-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("สำเร็จ!");
} else {
Serial.print("ล้มเหลว, rc=");
Serial.println(client.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
// เริ่มใช้งาน DHT
dht.begin();
// เชื่อมต่อ WiFi
setup_wifi();
// ตั้งค่า MQTT
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// อ่านเซ็นเซอร์ทุก 10 วินาที
unsigned long now = millis();
if (now - lastSensorRead > sensorInterval) {
lastSensorRead = now;
// อ่านค่าอุณหภูมิ (เซลเซียส)
float temperature = dht.readTemperature();
// อ่านค่าความชื้น (%)
float humidity = dht.readHumidity();
// ตรวจสอบว่าอ่านได้หรือไม่
if (isnan(temperature) || isnan(humidity)) {
Serial.println("อ่านค่าจาก DHT ไม่สำเร็จ!");
return;
}
// แปลงค่าเป็น String
char tempStr[8];
char humStr[8];
dtostrf(temperature, 1, 2, tempStr); // ทศนิยม 2 ตำแหน่ง
dtostrf(humidity, 1, 2, humStr);
// ส่งค่าไปยัง MQTT
client.publish(temp_topic, tempStr);
client.publish(hum_topic, humStr);
// แสดงผลใน Serial Monitor
Serial.print("อุณหภูมิ: ");
Serial.print(temperature);
Serial.print("°C | ความชื้น: ");
Serial.print(humidity);
Serial.println("%");
}
}🎯 ข้อดีของการใช้ JSON:
แทนที่จะส่งค่าแยกกัน 2 topics สามารถส่งเป็น JSON ใน topic เดียวได้:
{"temp": 28.5, "hum": 65.2}ตัวอย่างที่ 3: ควบคุม Relay ผ่าน MQTT
ตัวอย่างนี้รับคำสั่งจาก MQTT เพื่อเปิด/ปิด Relay (เช่น ไฟ, ปั๊มน้ำ)
วิธีต่อสาย Relay Module
- VCC: 5V (หรือ 3.3V ตามรุ่น)
- IN: GPIO 2 (หรือขาอื่น)
- GND: GND
#include <WiFi.h>
#include <PubSubClient.h>
// ===== WiFi & MQTT =====
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* mqtt_server = "broker.hivemq.com";
// ===== Relay =====
#define RELAY_PIN 2 // GPIO 2
const char* relay_topic = "cynoiot/relay/1";
// ===== State =====
bool relayState = false;
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
// ... เหมือนตัวอย่างที่แล้ว ...
}
// ===== MQTT Callback - รับคำสั่ง =====
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("มีข้อความจาก ");
Serial.println(topic);
// แปลง payload เป็น string
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("คำสั่ง: ");
Serial.println(message);
// ตรวจสอบคำสั่ง
if (message == "ON" || message == "on" || message == "1") {
digitalWrite(RELAY_PIN, HIGH); // เปิด Relay
relayState = true;
Serial.println("เปิด Relay!");
// ส่งสถานะกลับ
client.publish(relay_topic, "ON");
}
else if (message == "OFF" || message == "off" || message == "0") {
digitalWrite(RELAY_PIN, LOW); // ปิด Relay
relayState = false;
Serial.println("ปิด Relay!");
// ส่งสถานะกลับ
client.publish(relay_topic, "OFF");
}
}
void reconnect() {
// ... เหมือนตัวอย่างที่แล้ว ...
}
void setup() {
Serial.begin(115200);
// ตั้งค่า Relay pin
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // เริ่มต้นปิด
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback); // ตั้งค่า callback
}
void loop() {
if (!client.connected()) {
reconnect();
// Subscribe topic หลังเชื่อมต่อสำเร็จ
client.subscribe(relay_topic);
Serial.println("Subscribe: " + String(relay_topic));
}
client.loop();
}🎮 ทดสอบควบคุม:
เปิด MQTT Explorer → ไปที่ topic cynoiot/relay/1 → พิมพ์ ON หรือ OFF → Relay จะทำงาน!
เชื่อมต่อกับ CynoIoT Platform
CynoIoT รองรับ MQTT protocol สำหรับเชื่อมต่ออุปกรณ์ IoT เข้าสู่แพลตฟอร์ม
ขั้นตอนการเชื่อมต่อ
1. สร้าง Device บน CynoIoT
- Login ที่ cynoiot.com
- ไปที่ Device Management → Add Device
- เลือก Protocol: MQTT
- คัดลอก MQTT Credentials (Host, Port, Username, Password)
2. อัปเดตโค้ด ESP32
// แทนที่ค่าเหล่านี้ด้วยค่าจาก CynoIoT
const char* mqtt_server = "mqtt.cynoiot.com"; // จาก CynoIoT
const int mqtt_port = 1883; // จาก CynoIoT
const char* mqtt_user = "YOUR_DEVICE_USERNAME"; // จาก CynoIoT
const char* mqtt_pass = "YOUR_DEVICE_PASSWORD"; // จาก CynoIoT
// ใน reconnect():
if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
// ...
}3. ใช้ Topic ตามที่ CynoIoT กำหนด
CynoIoT ใช้รูปแบบ topic เฉพาะ:
- ขึ้นข้อมูล:
device/{device_id}/telemetry - รับคำสั่ง:
device/{device_id}/command
📚 อ่านเพิ่มเติม:
แก้ปัญหาที่พบบ่อย
❓ ปัญหา: เชื่อมต่อ MQTT ไม่ได้ (Connection Failed)
สาเหตุที่เป็นไปได้:
- WiFi ยังไม่เชื่อมต่อ
- MQTT Broker address ผิด
- Port ผิด (ควรใช้ 1883 สำหรับ non-TLS, 8883 สำหรับ TLS)
- Firewall บน router บล็อก port
วิธีแก้: ตรวจสอบ WiFi status, ลอง ping broker, ใช้ MQTT Explorer ทดสอบ
❓ ปัญหา: ส่งข้อมูลแล้วไม่ปรากฏบน MQTT Explorer
สาเหตุ:
- Subscribe topic ผิด (case-sensitive)
- ต้อง Subscribe ก่อน Publish ครั้งแรก
- Client ID ซ้ำกับ device อื่น (Broker จะ kick ตัวเก่า)
วิธีแก้: ตรวจสอบตัวสะกด topic, ใช้ Client ID แบบสุ่ม, Subscribe topic ให้ตรง
❓ ปัญหา: Callback ไม่ทำงาน
สาเหตุ:
- ลืมเรียก
client.setCallback() - ลืมเรียก
client.loop()ใน loop() - ยังไม่ได้ Subscribe topic
วิธีแก้: เพิ่ม client.setCallback(callback) ใน setup(), ต้องมี client.loop() ทุกรอบ
❓ ปัญหา: ESP32 รีสตาร์ทบ่อย (Watchdog Reset)
สาเหตุ:
- โค้ดใน loop() ใช้เวลานานเกินไป (block)
- MQTT connection หลุดแล้ว reconnect ไม่หยุด
วิธีแก้: ใช้ millis() แทน delay(), ใส่ timeout ใน reconnect
สรุป
MQTT คือโปรโตคอลที่เหมาะกับ IoT projects มากๆ เพราะเบา รวดเร็ว และง่ายต่อการใช้งาน ด้วย ESP32 และ Library PubSubClient คุณสามารถสร้างระบบ IoT ที่ส่งและรับข้อมูลแบบ Real-time ได้ในไม่กี่นาที
สิ่งที่ได้เรียนรู้:
- ✅ หลักการทำงานของ MQTT (Publisher, Subscriber, Broker)
- ✅ การติดตั้งและใช้งาน PubSubClient Library
- ✅ การส่งค่าเซ็นเซอร์ไปยัง MQTT Broker
- ✅ การรับคำสั่งจาก MQTT เพื่อควบคุม Relay
- ✅ การเชื่อมต่อ ESP32 เข้ากับ CynoIoT Platform
ถัดไป
- ลองใช้ MQTT over TLS สำหรับความปลอดภัยยิ่งขึ้น
- สร้าง Dashboard ดูข้อมูลจาก ESP32 แบบ Real-time
- เรียนรู้เกี่ยวกับ JSON Payload สำหรับส่งข้อมูลหลายค่าพร้อมกัน
- ดู Deep Sleep Guide สำหรับประหยัดพลังงาน
🚀 เริ่มต้นใช้งาน CynoIoT
พร้อมจะเชื่อมต่อ ESP32 ของคุณเข้าสู่ Cloud Platform แล้วหรือยัง? CynoIoT ช่วยให้คุณจัดการอุปกรณ์ IoT ได้ง่ายๆ