Điều khiển đèn led qua MQTT

Ở bài trước chúng ta đã biết cách điều khiển đèn LED thông qua WebSocket thông qua việc truyền các tin nhắn “on” hoặc “off“. Trong bài này chúng ta sẽ làm điều tương tự nhưng sử dụng MQTT.

Thiết bị cần chuẩn bị

  • 1 x Node WiFi

Chương Trình

Trước tiên chúng ta cần cài đặt thư viện PubSubClient cho Arduino IDE. Bạn vào menu Sketch > Include Library > Manage Libraries. Tìm và cài đặt thư viện PubSubClient:

Khai báo các thư viện cần thiết:

#include <ESP8266WiFi.h>                // Thư viện dùng để kết nối WiFi của ESP8266
#include <PubSubClient.h>               // Thư viện dùng để connect, publish/subscribe MQTT

Để sử dụng thư viện PubSubClient ta cần khởi tạo một đối tượng tên là là client.

WiFiClient espClient;
PubSubClient client(espClient);

Khai báo hàm dùng để kết nối đến broker. Ta sẽ dùng broker miễn phí của HiveMQ có thông tin như sau:

const char* mqttServer = "broker.hivemq.com";
const int   mqttPort = 8000;
const char* mqttUser = "";
const char* mqttPassword = "";
void connectBroker() {
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);                                           // Hàm callback sẽ được gọi khi nhận được tin nhắn từ broker

  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");

    if (client.connect("BlockyNodeClient", mqttUser, mqttPassword )) {    // Kêt nối đến broker thành công
      Serial.println("connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }
  }
}

Để đăng ký nhận tin từ một kênh cụ thể ta dùng lệnh sau:

client.subscribe("blockynode/led");                           // Đăng ký nhận tin từ topic = "blockynode/led"

Để gởi tin nhắn đến một kênh cụ thể ta dùng lệnh sau:

client.publish("blockynode/led", "Hello from Blocky Node");   // Gởi message = "Hello from Blocky Node" đến topic = "blockynode/led"

Khi nhận được tin nhắn từ broker, hàm callback sẽ được gọi và ta sẽ dựa vào nội dung tín nhắn nhận được để điều khiển đèn LED.

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  int i;
  for (i = 0; i < length; i++) {
    messageBuff[i] = (char)payload[i];
  }
  messageBuff[i] = '\0';

  String message = String(messageBuff);
  Serial.println(message);

  if (message == "on") {
    digitalWrite(led, LOW);                       // Bật đèn LED khi nhận được tin nhắn "on"
    client.publish("blockynode/led", "LED is turned ON");   // Thông báo trạng thái bật LED cho tất cả client đăng ký topic = "blockynode/led"
  } else if (message == "off") {                  // Tắt đèn LED khi nhận được tin nhắn "off"
    digitalWrite(led, HIGH);
    client.publish("blockynode/led", "LED is turned OFF");  // Thông báo trạng thái tắt LED cho tất cả client đăng ký topic = "blockynode/led"
  }
}

Cuối cùng chúng ta cần gọi phương thức client.loop() trong vòng lặp chính để lắng nghe các sự kiện từ broker.

void loop() {
  client.loop();
}

Bạn dùng Arduino IDE để nạp chương trình sau:

#include <ESP8266WiFi.h>                // Thư viện dùng để kết nối WiFi của ESP8266
#include <PubSubClient.h>               // Thư viện dùng để connect, publish/subscribe MQTT

const char* ssid = "Blocky AP";         // Tên của mạng WiFi mà bạn muốn kết nối đến
const char* password = "password_ap";   // Mật khẩu của mạng WiFi

const char* mqttServer = "broker.hivemq.com";
const int   mqttPort = 1883;
const char* mqttUser = "";
const char* mqttPassword = "";

const int led = 15;                      // Đèn led ở chân GPIO2

char messageBuff[100];                  // Biến dùng để lưu nội dung tin nhắn

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);                 // Khởi tạo kết nối Serial để truyền dữ liệu đến máy tính

  pinMode(led, OUTPUT);

  startWiFi();

  connectBroker();

  client.subscribe("blockynode/led");                           // Đăng ký nhận tin từ topic = "blockynode/led"
  client.publish("blockynode/led", "Hello from Blocky Node");   // Gởi message = "Hello from Blocky Node" đến topic = "blockynode/led"

}

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

void startWiFi() {
  WiFi.begin(ssid, password);           // Kết nối vào mạng WiFi
  Serial.print("Connecting to ");
  Serial.print(ssid);
  // Chờ kết nối WiFi được thiết lập
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("\n");
  Serial.println("Connection established!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());       // Gởi địa chỉ IP đến máy tinh
}

void connectBroker() {
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);

  while (!client.connected()) {
    Serial.print("Connecting to MQTT...");
    if (client.connect("BlockyNodeClientID")) {    // Kêt nối đến broker thành công
      Serial.println("\n");
      Serial.println("MQTT connected");
    } else {
      Serial.println("\n");
      Serial.print("MQTT failed with state ");
      Serial.println(client.state());
      delay(2000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  int i;
  for (i = 0; i < length; i++) {
    messageBuff[i] = (char)payload[i];
  }
  messageBuff[i] = '\0';

  String message = String(messageBuff);
  Serial.println(message);

  if (message == "on") {
    digitalWrite(led, LOW);                       // Bật đèn LED khi nhận được tin nhắn "on"
    client.publish("blockynode/led", "LED is turned ON");   // Thông báo trạng thái bật LED cho tất cả client đăng ký topic = "blockynode/led"
  } else if (message == "off") {                  // Tắt đèn LED khi nhận được tin nhắn "off"
    digitalWrite(led, HIGH);
    client.publish("blockynode/led", "LED is turned OFF");  // Thông báo trạng thái tắt LED cho tất cả client đăng ký topic = "blockynode/led"
  }
}

Sau khi nạp code thành công, ta dùng một MQTT Client để kiểm tra. Ta có thể dùng HiveMQ online tại đây:

Bạn kết nối chương trình đến brorker broker.hivemq.com (Port 8000).

Sau đó subscribe/publish topic = “blockynode/led” và thử gởi các tin nhắn như “on“, “off” để kiểm tra sự thay đổi trạng thái của đèn LED ở chân GPIO2 (có sẵn trên ESP8266).

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Fill out this field
Fill out this field
Vui lòng nhập địa chỉ email hợp lệ.
You need to agree with the terms to proceed

1 Bình luận.

  • Đây là khóa học IoT với Arduino phần nâng cao, giúp các bạn làm quen với các khái niệm về phần truyền và nhận dữ liệu lên Internet thông qua kết nối WiFi và nhiều phương thức (protocol) khác nhau.

Menu