Lập trình ESP32 MQTT bật tắt đèn với Hivemq Broker

Lập trình ESP32 MQTT dieu khien led voi Hive Brocker

Trong bài này chúng ta sẽ học các sử dụng ESP32 MQTT, giao tiếp với Hive Broker. Đây là một dịch vụ broker miễn phí, các bạn có thể sử dụng để test các sản phẩm IOT của mình.

Bài 6 Trong serie Học Esp32 từ A tới Z

Hivemq broker là gì?

Hivemq Broker là một nền tảng truyền nhận dữ liệu dựa trên giao thức MQTT, được thế kế với đặc tính nhanh, hiệu quả, độ tin cậy cao khi truyền dữ liệu 2 chiều giữa các thiết bị Internet of Things.

Đây là một dịch vụ miễn phí trên nền tảng Cloud, giúp các bạn có thể kết nối MQTT ở bất cứ đâu, không kể địa lý, phù hợp khi học lập trình IOT

hive broker

Hivemq Broker chia thành 2 loại:

  • Public broker: Sử dụng cổng 1883, không có bảo mật, thường dùng để test ứng dụng hoặc các sản phẩm đơn giản
  • Private broker: Sử dụng cổng 8883 và bảo mật SSL/TLS. Bạn có thể sử dụng nó trong các sản phẩm thương mại, nhưng tất nhiên nên để ý các điều khoản khi sử dụng nhé

Link ứng dụng: https://www.hivemq.com/

Cách sử dụng Public broker

Trong menu. nhấn MQTT – Public MQTT.

public broker

Giao điện bao gồm:

  • Thông tin MQTT chúng ta kết nối vào
  • Websocket để có thể điều khiển MQTT bằng web browser

public broker 2public broker websocket

Lập trình ESP32 MQTT

Cài đặt thư viện pubsubclient

Mở terminal gõ lệnh pio lib install “knolleary/PubSubClient”

Sau đó update đường dẫn thư viện trong platformio.ini

pubsubclient

Cài đặt các thông số của MQTT như sau:

  • Server broker và port lấy trên hivemq
  • Vì là kiểu public nên các bạn không cần user và password cũng được
  • Tạo ra 2 topic lưu giá trị của Led1 và Led 2

cai dat mqttt

Kết nối với broker

Lưu ý: Mỗi một thiết bị phải có 1 client ID riêng, nếu 2 thiết bị cùng client ID kết nối vào Broker. Nó sẽ đẩy thiết bị cũ ra hoặc không thể connect được. Trong bài này, mình sẽ cho Client ID 1 dãy số random khi kết nối vào.

Sau khi kết nối, chúng ta sẽ sub với 2 topic LED1 và LED2 để nhận dữ liệu từ Broker về.

ket noi voi broker

Kết nối phần cứng

Các bạn kết nối như sau

  • Button1 —– chân 4
  • Button1 —– chân 16
  • Led 1 —– chân 17
  • Led 2—– chân 5

Publish dữ liệu lên MQTT

Mỗi khi nhấn nút, chúng ta sẽ kiểm tra trạng thái của ledstatus, sau đó đảo ngược trạng thái đó.
Tiếp tới dùng client.publish để đẩy dữ liệu đó lên broker.

pub mqtt

Subcrible dữ liêu từ MQTT

Mỗi khi có dữ liệu thay đổi trên broker, hàm callback sẽ được gọi. Ở đây chúng ta sử lý như sau:

  • Copy dữ liệu trả về (payload) và status
  • Kiểm tra đó là topic nào
  • Ghi trạng thái led với dữ liệu trả về tương ứng với mỗi topic

sub mqtt

Full code

 

#include <WiFi.h>
#include <PubSubClient.h>
#define BUT1 4
#define BUT2 16
#define LED1 17
#define LED2 5
String ledStatus1 = "ON";
String ledStatus2 = "ON";

const char* ssid = "Nha Tao";
const char* password = "25251325";

#define MQTT_SERVER "broker.hivemq.com"
#define MQTT_PORT 1883
#define MQTT_USER "mabattu123"
#define MQTT_PASSWORD "12345678"

#define MQTT_LED1_TOPIC "MQTT_ESP32/LED1"
#define MQTT_LED2_TOPIC "MQTT_ESP32/LED2"

unsigned long previousMillis = 0; 
const long interval = 5000;

WiFiClient wifiClient;
PubSubClient client(wifiClient);


void setup_wifi() {
  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());
}

void connect_to_broker() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP32";
    clientId += String(random(0xffff), HEX);
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      client.subscribe(MQTT_LED1_TOPIC);
      client.subscribe(MQTT_LED2_TOPIC);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      delay(2000);
    }
  }
}

void callback(char* topic, byte *payload, unsigned int length) {
  char status[20];
  Serial.println("-------new message from broker-----");
  Serial.print("topic: ");
  Serial.println(topic);
  Serial.print("message: ");
  Serial.write(payload, length);
  Serial.println();
  for(int i = 0; i<length; i++)
  {
    status[i] = payload[i];
  }
  Serial.println(status);
  if(String(topic) == MQTT_LED1_TOPIC)
  {
    if(String(status) == "OFF")
    {
      ledStatus1 = "OFF";
      digitalWrite(LED1, LOW);
      Serial.println("LED1 OFF");
    }
    else if(String(status) == "ON")
    {
      ledStatus1 = "ON";
      digitalWrite(LED1, HIGH);
      Serial.println("LED1 ON");
    }
  }

  if(String(topic) == MQTT_LED2_TOPIC)
  {
    if(String(status) == "OFF")
    {
      ledStatus2 = "OFF";
      digitalWrite(LED2, LOW);
      Serial.println("LED2 OFF");
    }
    else if(String(status) == "ON")
    {
      ledStatus2 = "ON";
      digitalWrite(LED2, HIGH);
      Serial.println("LED2 ON");
    }
  }
  
}

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(500);
  setup_wifi();
  client.setServer(MQTT_SERVER, MQTT_PORT );
  client.setCallback(callback);
  connect_to_broker();
  Serial.println("Start transfer");
  pinMode(BUT1, INPUT_PULLUP);
  pinMode(BUT2, INPUT_PULLUP);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}

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

  if(digitalRead(BUT1) == 0) 
  {
    while (digitalRead(BUT1) == 0)
    {
      /* cho nut dc nha */
    }
    if(ledStatus1 == "ON")
    {
      client.publish(MQTT_LED1_TOPIC, "OFF");
      ledStatus1 = "OFF";
    }
    else if(ledStatus1 == "OFF")
    {
      client.publish(MQTT_LED1_TOPIC, "ON");
      ledStatus1 = "ON";
    }
  }
  if(digitalRead(BUT2) == 0) 
  {
    while (digitalRead(BUT2) == 0)
    {
      /* cho nut dc nha */
    }
    if(ledStatus2 == "ON")
    {
      client.publish(MQTT_LED2_TOPIC, "OFF");
      ledStatus2 = "OFF";
    }
    else if(ledStatus2 == "OFF")
    {
      client.publish(MQTT_LED2_TOPIC, "ON");
       ledStatus2 = "ON";
    }
  }
}

Kết quả

Kết

Sử dụng ESP32 MQTT sẽ giúp việc điều khiển thiết bị một cách Realtime hơn, khi có sự thay đổi dữ liệu trên broker, gần như các thiết bị sub vào broker đó gần như nhận được dữ liệu ngay tức khắc mà không cần phải request lên server như giao thức HTTP.

Cám ơn bạn đã đón đọc, cùng vào hội Anh Em Nghiện Lập Trình để cùng trao đổi nhé

5/5 - (1 bình chọn)

2 thoughts on “Lập trình ESP32 MQTT bật tắt đèn với Hivemq Broker

  1. Hào says:

    cho em hỏi là sao khi em bật(tắt) bằng máy tính xong qua tắt(bật) bằng tay thì nó lại không tắt(bật) luôn mà phải ấn hai lần mới được ạ. Có thể cho em xin cách khắc phục không ạ

Trả lời

Email của bạn sẽ không được hiển thị công khai.