ในยุคของ Internet of Things (IoT) อุปกรณ์ต่าง ๆ เช่น เซ็นเซอร์, กล้อง, และอุปกรณ์สมาร์ทโฮม มักจะเชื่อมต่อกันผ่านเครือข่ายอินเทอร์เน็ต เพื่อแลกเปลี่ยนข้อมูล ในการสื่อสารระหว่างอุปกรณ์เหล่านี้ MQTT (Message Queuing Telemetry Transport) เป็นโปรโตคอลที่ได้รับความนิยมอย่างมาก โดยเฉพาะในระบบที่ต้องการการเชื่อมต่อที่มีความเบาและสามารถส่งข้อมูลได้อย่างรวดเร็ว

ในบทความนี้ เราจะนำเสนอวิธีการใช้ ESP32 ในการเชื่อมต่อกับ MQTT Broker โดยใช้ไลบรารี PubSubClient และจะเขียนโค้ดสำหรับการทำ Publisher (ส่งข้อมูล) และ Subscriber (รับข้อมูล) พร้อมกับการใช้ username และ password ในการยืนยันตัวตน

ความรู้พื้นฐานเกี่ยวกับ MQTT

MQTT เป็นโปรโตคอลที่ใช้ในการแลกเปลี่ยนข้อความระหว่างอุปกรณ์ต่าง ๆ ผ่าน Broker ซึ่งทำหน้าที่เป็นตัวกลางในการรับส่งข้อมูลระหว่าง Publisher (ผู้ส่งข้อความ) และ Subscriber (ผู้รับข้อความ) โดยที่ MQTT มีลักษณะเด่นในเรื่องของการทำงานที่มีประสิทธิภาพและการส่งข้อมูลที่เบา ซึ่งเหมาะสมกับการใช้งานในระบบ IoT ที่มีข้อจำกัดในเรื่องของแบนด์วิธและพลังงาน

ทำไมต้องใช้ MQTT?

  • ประหยัดพลังงาน: เหมาะกับอุปกรณ์เล็กๆ ที่มีแบตเตอรี่อยู่ได้นาน
  • ใช้แบนด์วิดท์น้อย: ส่งข้อมูลขนาดเล็กได้เร็ว
  • รองรับการเชื่อมต่อที่ไม่เสถียร: แม้สัญญาณอินเทอร์เน็ตไม่ดี MQTT ก็ยังทำงานได้

ทำงานอย่างไร?

  1. Publisher (ผู้ส่ง):

    • อุปกรณ์หรือเซ็นเซอร์ที่ส่งข้อมูล เช่น เซ็นเซอร์อุณหภูมิส่งค่าความร้อนไปยังระบบ
  2. Broker (ตัวกลาง):

    • ทำหน้าที่เหมือนคนส่งจดหมาย คอยรับข้อมูลจากผู้ส่งแล้วกระจายไปให้ผู้ที่สนใจ
    • เปรียบเสมือน “ไปรษณีย์” ที่ส่งข้อมูลระหว่างอุปกรณ์
  3. Subscriber (ผู้รับ):

    • อุปกรณ์ที่ขอรับข้อมูล เช่น แอปพลิเคชันมือถือที่ต้องการดูค่าความร้อนจากเซ็นเซอร์

ตัวอย่างใช้งาน

  1. สมาร์ทโฮม:

    • เมื่อคุณเปิดแอปมือถือเพื่อเปิดไฟบ้าน MQTT จะส่งคำสั่งจากโทรศัพท์ไปยังหลอดไฟเพื่อให้เปิด
  2. การเกษตรอัจฉริยะ:

    • เซ็นเซอร์วัดความชื้นดินส่งข้อมูลไปยังคลาวด์ ถ้าดินแห้ง ระบบก็เปิดสปริงเกอร์ให้น้ำอัตโนมัติ
  3. โรงงานอุตสาหกรรม:

    • เซ็นเซอร์จับการทำงานของเครื่องจักร ส่งข้อมูลให้ผู้จัดการโรงงานเพื่อปรับปรุงการผลิต

เปรียบเทียบง่ายๆ


ลองนึกถึง MQTT เหมือนระบบประกาศในโรงเรียน:

  • คุณครู (Publisher) ประกาศข่าว
  • ไมโครโฟน (Broker) ส่งเสียงไปทั่วโรงเรียน
  • นักเรียน (Subscriber) คนที่ฟังข่าวที่ตัวเองสนใจ

ส่วนประกอบหลักใน MQTT

  • Publisher: อุปกรณ์หรือแอปพลิเคชันที่ส่งข้อมูลไปยัง Broker
  • Subscriber: อุปกรณ์หรือแอปพลิเคชันที่รับข้อมูลจาก Broker
  • Broker: เซิร์ฟเวอร์ที่ทำหน้าที่กลางในการรับและส่งข้อมูลระหว่าง Publisher และ Subscriber
  • Topic: หมวดหมู่หรือหัวข้อที่ใช้ในการจัดระเบียบข้อมูลภายใน MQTT โดยทั้ง Publisher และ Subscriber จะใช้หัวข้อนี้ในการสื่อสารกัน

เครื่องมือที่ใช้

    1. ESP32: บอร์ดไมโครคอนโทรลเลอร์ที่มีคุณสมบัติการเชื่อมต่อ Wi-Fi และ Bluetooth ที่ทรงพลัง

  1. Arduino IDE: โปรแกรมที่ใช้ในการเขียนและอัปโหลดโค้ดไปยัง ESP32
  2. PubSubClient: ไลบรารีที่ใช้ในการเชื่อมต่อกับ MQTT Broker และจัดการการส่งรับข้อมูลผ่าน MQTT

การติดตั้งไลบรารี PubSubClient

การติดตั้งไลบรารี PubSubClient ใน Arduino IDE สามารถทำได้ง่าย ๆ โดยทำตามขั้นตอนดังนี้:

  1. เปิด Arduino IDE
  2. ไปที่ Sketch > Include Library > Manage Libraries...
  3. ในหน้าต่าง Library Manager, ค้นหาคำว่า PubSubClient และคลิก Install ติดตั้งไลบรารีนี้

การเขียนโค้ดสำหรับ ESP32: Publisher และ Subscriber

1. โค้ดสำหรับ Publisher (ส่งข้อมูล)

โค้ดตัวอย่างนี้จะใช้ ESP32 ในการส่งข้อความผ่าน MQTT ไปยัง MQTT Broker โดยเชื่อมต่อกับ Wi-Fi และใช้ username และ password ในการยืนยันตัวตนกับ Broker:

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

// กำหนดข้อมูล Wi-Fi
const char* ssid = "Your_SSID";  // ชื่อ Wi-Fi ของคุณ
const char* wifiPassword = "Your_PASSWORD";  // รหัสผ่าน Wi-Fi

// กำหนดข้อมูล MQTT Broker
const char* mqttServer = "mqtt.eclipse.org";  // ที่อยู่ MQTT Broker (ใช้เซิร์ฟเวอร์สาธารณะ)
const int mqttPort = 1883;  // พอร์ตสำหรับ MQTT
const char* mqttUser = "Username";  // Username สำหรับ MQTT
const char* mqttPassword = "Password";  // Password สำหรับ MQTT
const char* mqttTopic = "test/topic";  // หัวข้อที่ใช้ส่งข้อมูล

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);

  // เชื่อมต่อกับ Wi-Fi
  WiFi.begin(ssid, wifiPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // เชื่อมต่อกับ MQTT Broker
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
}

void callback(char* topic, byte* payload, unsigned int length) {
  // ฟังก์ชัน Callback สำหรับการรับข้อมูลจาก Broker
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {
  // เชื่อมต่อกับ MQTT Broker ถ้ายังไม่เชื่อมต่อ
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP32Publisher", mqttUser, mqttPassword)) {
      Serial.println("connected");
      client.subscribe(mqttTopic);  // Subscribe หัวข้อ
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

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

  // ส่งข้อความทุกๆ 5 วินาที
  if (millis() % 5000 == 0) {
    String message = "Hello from ESP32";
    client.publish(mqttTopic, message.c_str());
    Serial.println("Message Sent: " + message);
  }
}
2. โค้ดสำหรับ Subscriber (รับข้อมูล)

ในส่วนนี้จะเป็นโค้ดสำหรับ ESP32 ที่ใช้รับข้อมูลจาก MQTT Broker

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

// กำหนดข้อมูล Wi-Fi
const char* ssid = "Your_SSID";  // ชื่อ Wi-Fi ของคุณ
const char* wifiPassword = "Your_PASSWORD";  // รหัสผ่าน Wi-Fi

// กำหนดข้อมูล MQTT Broker
const char* mqttServer = "mqtt.eclipse.org";  // ที่อยู่ MQTT Broker (ใช้เซิร์ฟเวอร์สาธารณะ)
const int mqttPort = 1883;  // พอร์ตสำหรับ MQTT
const char* mqttUser = "Username";  // Username สำหรับ MQTT
const char* mqttPassword = "Password";  // Password สำหรับ MQTT
const char* mqttTopic = "test/topic";  // หัวข้อที่ใช้รับข้อมูล

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);

  // เชื่อมต่อกับ Wi-Fi
  WiFi.begin(ssid, wifiPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // เชื่อมต่อกับ MQTT Broker
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
}

void callback(char* topic, byte* payload, unsigned int length) {
  // ฟังก์ชัน Callback สำหรับการรับข้อมูลจาก Broker
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {
  // เชื่อมต่อกับ MQTT Broker ถ้ายังไม่เชื่อมต่อ
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP32Subscriber", mqttUser, mqttPassword)) {
      Serial.println("connected");
      client.subscribe(mqttTopic);  // Subscribe หัวข้อ
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

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

Library pubsubclient ที่เกี่ยวข้อง 

สนับสนุนบทความโดย Panmaneecnc.com