เนื้อหาในบทความ
🌐 ทำไมต้องสร้าง MQTT Broker เอง?
ในยุคที่ Cloud Services มีอยู่มากมาย การมี MQTT Broker ส่วนตัวของคุณเองมีข้อดีหลายประการ:
🔒 ความเป็นส่วนตัว
ข้อมูลของคุณไม่ต้องผ่านบริการภายนอก ควบคุมได้ 100%
⚡ ประสิทธิภาพ
ตอบสนองเร็วขึ้น เนื่องจากไม่ต้องส่งข้อมูลไป Internet
💰 ประหยัดค่าใช้จ่าย
ไม่มีค่าบริการรายเดือน ใช้ฮาร์ดแวร์ของคุณเอง
🎛️ การควบคุมเต็มรูปแบบ
ตั้งค่า QoS, Retain Messages, ACL ได้ตามต้องการ
📌 สำคัญ: บทความนี้เหมาะสำหรับผู้ที่มี ESP32 หลายตัว และต้องการรวบรวมข้อมูลในระบบเดียวโดยไม่ต้องพึ่งพา Cloud Services
📋 สิ่งที่ต้องเตรียม
ฮาร์ดแวร์:
- Server: Raspberry Pi (3B+/4/5) หรือ VPS ที่รัน Linux (Ubuntu/Debian)
- ESP32 Board: บอร์ด ESP32 ใดก็ได้สำหรับทดสอบ
- Network: Router ที่รองรับ Local Network
ซอฟต์แวร์:
- ระบบปฏิบัติการ Linux (Raspberry Pi OS / Ubuntu 20.04+)
- Arduino IDE หรือ PlatformIO
- MQTT Explorer หรือ MQTT.fx (สำหรับทดสอบ)
ทักษะ:
- พื้นฐาน Linux Command Line
- พื้นฐานการเขียนโปรแกรม ESP32
- ความเข้าใจพื้นฐานเกี่ยวกับ MQTT Protocol
🚀 การติดตั้ง Mosquitto Broker
Mosquitto (Eclipse Mosquitto) เป็น MQTT Broker โอเพนซอร์สที่นิยมที่สุด เบาเร็วและเสถียร เหมาะสำหรับการใช้งานจริง
สำหรับ Raspberry Pi (Debian/Ubuntu):
# อัปเดตระบบ
sudo apt update
# ติดตั้ง Mosquitto Broker และ Clients
sudo apt install -y mosquitto mosquitto-clients
# ติดตั้ง utilities เพิ่มเติม (optional)
sudo apt install -y mosquitto-devตรวจสอบการติดตั้ง:
# เช็คเวอร์ชัน
mosquitto --version
# เริ่มต้นบริการ
sudo systemctl start mosquitto
# ตั้งค่าให้เปิดบริการอัตโนมัติเมื่อบูตเครื่อง
sudo systemctl enable mosquitto
# เช็คสถานะบริการ
sudo systemctl status mosquitto✅ สำเร็จ! หากเห็น "active (running)" แปลว่า Mosquitto Broker ของคุณทำงานแล้วบนพอร์ต 1883 (default)
⚙️ การตั้งค่าพื้นฐาน
ไฟล์การตั้งค่าหลักของ Mosquitto อยู่ที่ /etc/mosquitto/mosquitto.conf
สร้างไฟล์ตั้งค่าใหม่:
# สำรองไฟล์เดิม
sudo cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.backup
# แก้ไขไฟล์ตั้งค่า
sudo nano /etc/mosquitto/mosquitto.confเนื้อหาไฟล์ mosquitto.conf:
# ตั้งค่าพื้นฐาน
# อนุญาตให้เชื่อมต่อแบบไม่มี authentication (เฉพาะทดสอบ)
listener 1883
allow_anonymous true
# เปิดใช้งาน persistence (บันทึก retained messages)
persistence true
persistence_location /var/lib/mosquitto/
# บันทึก log ลงไฟล์
log_dest file /var/log/mosquitto/mosquitto.log
# ระดับ log (debug, info, notice, warning, error)
log_type error
log_type warning
log_type notice
log_type informationหลังจากบันทึกไฟล์ ให้รีสตาร์ทบริการ:
# รีสตาร์ท Mosquitto
sudo systemctl restart mosquitto
# เช็ค log ว่าทำงานปกติ
sudo tail -f /var/log/mosquitto/mosquitto.log🔐 รักษาความปลอดภัยด้วย Password Authentication
⚠️ คำเตือน: การตั้งค่า allow_anonymous true เหมาะสำหรับการทดสอบเท่านั้น ห้ามใช้ใน Production!
สร้าง Password File:
# สร้าง password file และเพิ่ม user แรก
sudo mosquitto_passwd -c /etc/mosquitto/passwd esp32_user
# ระบบจะถาม password ให้ตั้งและยืนยัน
# Password: (พิมพ์ password และกด Enter)
# Reenter password: (พิมพ์ซ้ำและกด Enter)
# เพิ่ม user เพิ่มเติม (ถ้าต้องการ)
sudo mosquitto_passwd -b /etc/mosquitto/passwd sensor_node_1
sudo mosquitto_passwd -b /etc/mosquitto/passwd sensor_node_2อัปเดต mosquitto.conf:
# แก้ไขไฟล์ตั้งค่า
sudo nano /etc/mosquitto/mosquitto.conf เปลี่ยนบรรทัด allow_anonymous true เป็น:
# ปิดการเชื่อมต่อแบบไม่มี authentication
allow_anonymous false
# ระบุ password file
password_file /etc/mosquitto/passwd
# อนุญาตให้ user ทุกคนเข้าถึงทุก topic (เปลี่ยนตามต้องการ)
acl_file /etc/mosquitto/aclสร้าง ACL (Access Control List):
# สร้างไฟล์ ACL
sudo nano /etc/mosquitto/aclเพิ่มเนื้อหาต่อไปนี้:
# ESP32 User - อ่านเขียนได้ทุก topic
user esp32_user
topic readwrite #
# Sensor Node 1 - เขียนลง sensor/ ได้อย่างเดียว
user sensor_node_1
topic write sensor/#
topic read command/#รีสตาร์ท Mosquitto:
sudo systemctl restart mosquitto
sudo systemctl status mosquitto💡 เคล็ดลับความปลอดภัย:
- • ใช้ password ที่ซับซ้อน (อย่างน้อย 12 ตัวอักษร)
- • จำกัดสิทธิ์แต่ละ user ให้อ่าน/เขียนได้เฉพาะ topic ที่จำเป็น
- • เปิด TLS/SSL หากเชื่อมต่อผ่าน Internet
- • ใช้ Firewall บล็อกพอร์ต 1883 จากภายนอก
💻 ตัวอย่างโค้ด ESP32
ต่อไปนี้คือตัวอย่างโค้ด ESP32 ที่เชื่อมต่อกับ Mosquitto Broker ของคุณและส่งข้อมูลเซ็นเซอร์
ติดตั้ง Library:
// เปิด Arduino IDE
// ไปที่ Sketch -> Include Library -> Manage Libraries
// ค้นหา "PubSubClient" และติดตั้ง
// ค้นหา "DHT sensor library" และติดตั้ง (ถ้าใช้ DHT)โค้ด ESP32 ส่งข้อมูลเซ็นเซอร์:
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// ===== WiFi Credentials =====
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// ===== MQTT Broker Settings =====
const char* mqtt_server = "192.168.1.100"; // IP ของ Raspberry Pi หรือ VPS
const int mqtt_port = 1883;
const char* mqtt_user = "esp32_user";
const char* mqtt_password = "your_secure_password";
const char* mqtt_client_id = "ESP32_Sensor_01";
// ===== Sensor Settings =====
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// ===== MQTT Topics =====
const char* temp_topic = "sensor/esp32_01/temperature";
const char* humi_topic = "sensor/esp32_01/humidity";
const char* status_topic = "sensor/esp32_01/status";
// ===== Global Objects =====
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
const long interval = 5000; // ส่งข้อมูลทุก 5 วินาที
// ===== Function: เชื่อมต่อ 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());
}
// ===== Function: Callback รับข้อความจาก Broker =====
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("]: ");
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// ตัวอย่าง: รับคำสั่งจาก topic command/esp32_01
if (String(topic) == "command/esp32_01") {
if (message == "ON") {
digitalWrite(2, HIGH); // เปิด LED
Serial.println("LED turned ON");
} else if (message == "OFF") {
digitalWrite(2, LOW); // ปิด LED
Serial.println("LED turned OFF");
}
}
}
// ===== Function: เชื่อมต่อ MQTT Broker อีกครั้ง =====
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// พยายามเชื่อมต่อด้วย username/password
if (client.connect(mqtt_client_id, mqtt_user, mqtt_password)) {
Serial.println("connected");
// ส่งสถานะออนไลน์
client.publish(status_topic, "online");
// Subscribe หัวข้อที่ต้องการรับคำสั่ง
client.subscribe("command/esp32_01");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
// รอ 5 วินาทีแล้วลองใหม่
delay(5000);
}
}
}
// ===== Function: ส่งข้อมูลเซ็นเซอร์ =====
void sendSensorData() {
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 humiStr[8];
dtostrf(t, 1, 2, tempStr);
dtostrf(h, 1, 2, humiStr);
// ส่งข้อมูลไปยัง Broker
client.publish(temp_topic, tempStr);
client.publish(humi_topic, humiStr);
Serial.print("Temperature: ");
Serial.print(t);
Serial.print("°C | Humidity: ");
Serial.print(h);
Serial.println("%");
}
// ===== Setup =====
void setup() {
Serial.begin(115200);
pinMode(2, OUTPUT); // LED pin
dht.begin();
setup_wifi();
// ตั้งค่า MQTT Server
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
// ===== Loop =====
void loop() {
// ตรวจสอบการเชื่อมต่อ MQTT
if (!client.connected()) {
reconnect();
}
client.loop();
// ส่งข้อมูลเซ็นเซอร์ทุก 5 วินาที
unsigned long now = millis();
if (now - lastMsg > interval) {
lastMsg = now;
sendSensorData();
}
}อัปโหลดและทดสอบ:
- เปลี่ยน
YOUR_WIFI_SSIDและYOUR_WIFI_PASSWORD - เปลี่ยน
mqtt_serverเป็น IP ของ Raspberry Pi - เปลี่ยน
mqtt_userและmqtt_password - อัปโหลดโค้ดไปยัง ESP32
- เปิด Serial Monitor (115200 baud) เพื่อดูผล
🧪 การทดสอบระบบ
วิธีที่ 1: ใช้ Mosquitto Client:
# Terminal 1: Subscribe รับข้อมูล
mosquitto_sub -h 192.168.1.100 -u esp32_user -P your_secure_password -t "sensor/#" -v
# Terminal 2: Publish ส่งคำสั่ง
mosquitto_pub -h 192.168.1.100 -u esp32_user -P your_secure_password -t command/esp32_01 -m "ON"วิธีที่ 2: ใช้ MQTT Explorer (GUI):
- ดาวน์โหลดและติดตั้ง MQTT Explorer
- สร้าง connection ใหม่:
- Host: 192.168.1.100 (IP ของ Broker)
- Port: 1883
- Username: esp32_user
- Password: your_secure_password
- กด Connect และดูข้อมูลจาก ESP32 ได้เลย
🔧 การแก้ปัญหาที่พบบ่อย
ESP32 เชื่อมต่อไม่ได้
- • เช็คว่า ESP32 และ Broker อยู่ในเครือข่ายเดียวกัน
- • Ping จาก ESP32 ไปยัง Broker IP:
ping 192.168.1.100 - • ตรวจสอบ Username/Password ให้ถูกต้อง
- • เช็ค Firewall บน Broker
Connection Lost บ่อยๆ
- • เพิ่ม
client.setKeepAlive(60)ใน setup() - • ตรวจสอบความเสถียรของ WiFi
- • เพิ่ม keepalive ใน mosquitto.conf:
keepalive 60
Mosquitto ไม่สตาร์ท
- • เช็ค log:
sudo tail -f /var/log/mosquitto/mosquitto.log - • ตรวจสอบ syntax ใน mosquitto.conf
- • ตรวจสอบ permissions ของไฟล์ passwd และ acl
เข้าถึง Broker จากภายนอกไม่ได้
- • เปิดพอร์ต 1883 ใน Firewall:
sudo ufw allow 1883 - • ตรวจสอบ Router's Firewall
- • พิจารณาใช้ TLS/SSL (พอร์ต 8883) แทน
📚 สรุปและขั้นตอนถัดไป
ยินดีด้วย! ตอนนี้คุณมี MQTT Broker ส่วนตัวที่ทำงานบน Raspberry Pi หรือ VPS แล้ว คุณสามารถเชื่อมต่อ ESP32 หลายๆ ตัวเข้ากับระบบเดียวกันได้
สิ่งที่คุณเรียนรู้:
- ✅ ติดตั้งและตั้งค่า Mosquitto MQTT Broker
- ✅ รักษาความปลอดภัยด้วย Password Authentication
- ✅ ใช้ ACL จัดการสิทธิ์การเข้าถึง Topic
- ✅ เขียนโค้ด ESP32 เชื่อมต่อกับ Broker
- ✅ ทดสอบและแก้ปัญหาขั้นพื้นฐาน
แนวคิดต่อยอด:
🔒 เปิด TLS/SSL
ใช้ Let's Encrypt สร้าง certificate เพื่อเชื่อมต่ออย่างปลอดภัย
📊 Dashboard
ใช้ Node-RED หรือ Grafana สร้างหน้าจอแสดงผล
🗄️ Database
บันทึกข้อมูลลง InfluxDB หรือ TimescaleDB
🌐 Remote Access
ใช้ VPN หรือ Cloudflare Tunnel เข้าถึงจากภายนอก