ESP32 Gửi Dữ Liệu MQTT Qua Wi-Fi và Điều Khiển LED

Trong bài viết này, mình sẽ hướng dẫn bạn cách sử dụng ESP32 kết nối đến Wi-Fi và gửi dữ liệu lên MQTT broker (ở đây dùng broker.hivemq.com). Ngoài ra, hệ thống sẽ điều khiển 3 đèn LED để phản hồi trạng thái khởi động và hoạt động.

1. Phần cứng sử dụng:

2. Kết nối MQTT qua Wi-Fi

ESP32 sẽ:

  • Kết nối đến mạng Wi-Fi
  • Kết nối tới MQTT broker (port 1883)
  • Tự động reconnect nếu mất kết nối
  • Gửi dữ liệu định kỳ mỗi 3 giây đến topic esp32/zenopcb
  • In thông báo khi nhận dữ liệu từ topic

3. Thư viện cần thiết

Tải tại đây: https://github.com/knolleary/pubsubclient.git

4. Code hoàn chỉnh và giải thích chi tiết

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

// Định nghĩa chân LED (LOW là bật)
#define LED1 5
#define LED2 12
#define LED3 13

// WiFi Config
const char* WIFI_SSID = "iMTrongThan";
const char* WIFI_PASS = "imaker12345";

// MQTT Config
const char* MQTT_SERVER = "broker.hivemq.com";
const int   MQTT_PORT   = 1883;

// MQTT client sử dụng WiFi
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

// Xử lý tin nhắn MQTT nhận được
void mqttCallback(char* topic, byte* payload, unsigned int length) {
  String topicStr = String(topic);
  String message;

  for (unsigned int i = 0; i < length; i++) {
    message += (char)payload[i];
  }

  Serial.println("📩 Topic: " + topicStr);
  Serial.println("📄 Message: " + message);

  // Điều khiển LED dựa vào topic
  if (topicStr == "esp32/zenopcb/led1") {
    digitalWrite(LED1, message == "on" ? LOW : HIGH);
  } else if (topicStr == "esp32/zenopcb/led2") {
    digitalWrite(LED2, message == "on" ? LOW : HIGH);
  } else if (topicStr == "esp32/zenopcb/led3") {
    digitalWrite(LED3, message == "on" ? LOW : HIGH);
  }
}

// Kết nối lại MQTT nếu mất
void reconnectMQTT() {
  while (!mqttClient.connected()) {
    Serial.print("🔄 Kết nối MQTT...");
    String clientId = "ESP32Client-ZENOPCB";
    if (mqttClient.connect(clientId.c_str())) {
      Serial.println("✅ Thành công!");

      // Subscribe các topic điều khiển LED
      mqttClient.subscribe("esp32/zenopcb/led1");
      mqttClient.subscribe("esp32/zenopcb/led2");
      mqttClient.subscribe("esp32/zenopcb/led3");
    } else {
      Serial.print("❌ Thất bại, lỗi: ");
      Serial.println(mqttClient.state());
      delay(2000);
    }
  }
}

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

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);

  // Nháy LED khi khởi động
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  delay(500);
  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  delay(500);
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);

  // Kết nối WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.print("📡 Đang kết nối WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.print("\n✅ WiFi Connected. IP: ");
  Serial.println(WiFi.localIP());

  // Cấu hình MQTT
  mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
  mqttClient.setCallback(mqttCallback);
}

void loop() {
  if (!mqttClient.connected()) {
    reconnectMQTT();
  }

  static unsigned long lastSend = 0;
  if (millis() - lastSend > 3000) {
    String message = "Hello from ESP32 WiFi -> " + String(random(100, 900));
    mqttClient.publish("esp32/zenopcb", message.c_str());
    Serial.println("📤 Đã gửi: " + message);
    lastSend = millis();
  }

  mqttClient.loop();
}

5. Gửi lệnh điều khiển LED từ MQTT:

TopicPayloadTác dụng
esp32/zenopcb/led1"on" hoặc "off"Bật/tắt LED1
esp32/zenopcb/led2"on" hoặc "off"Bật/tắt LED2
esp32/zenopcb/led3"on" hoặc "off"Bật/tắt LED3

Bạn vừa thiết lập thành công một hệ thống ESP32 kết nối Wi-Fi và gửi dữ liệu MQTT định kỳ. Đây là nền tảng vững chắc để xây dựng các hệ thống như:

  • Điều khiển thiết bị IoT từ xa
  • Gửi dữ liệu cảm biến lên cloud
  • Giao tiếp thời gian thực giữa nhiều ESP32

Nếu bạn cần mình hướng dẫn thêm cách điều khiển LED qua MQTT, hoặc hiển thị dữ liệu lên web, hãy bình luận bên dưới nhé!

Để lại một bình luận

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 *