Giao Tiếp MQTT Giữa ESP32-to-ESP32

Trong hướng dẫn này, chúng ta sẽ đề cập đến các chủ đề sau:

communication between two ESP32 via mqtt

Linh Kiện Cần Thiết

2×mô-đun phát triển ESP-WROOM-32
2×Cáp USB Type-C
1×(Khuyến nghị) Screw Terminal Expansion Board for ESP32
1×(Khuyến nghị) Breakout Expansion Board for ESP32
1×(Khuyến nghị) Power Splitter for ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Về ESP32 và MQTT

Chúng tôi có một hướng dẫn chi tiết về cách sử dụng ESP32 với MQTT tại đây:

Giao Tiếp Giữa Hai ESP32 Qua MQTT

Hai bo mạch ESP32 có thể giao tiếp với nhau thông qua một MQTT server. Nếu bạn muốn chúng giao tiếp trực tiếp mà không sử dụng MQTT server, hãy tham khảo hướng dẫn về giao tiếp ESP32 to ESP32 TCP Client/Server.

Khi ESP32 #1ESP32 #2 trao đổi dữ liệu qua một MQTT broker:

  • Cả hai ESP32 kết nối đến MQTT broker.
  • Để cho phép ESP32 #2 gửi dữ liệu đến ESP32 #1:
    • ESP32 #1 đăng ký (subscribe) một chủ đề (topic), ví dụ: esp32-1/data.
    • ESP32 #2 có thể gửi dữ liệu đến ESP32 #1 bằng cách xuất bản (publish) dữ liệu lên topic mà ESP32 #1 đã đăng ký.
  • Tương tự, để ESP32 #1 gửi dữ liệu đến ESP32 #2:
    • ESP32 #2 đăng ký một topic, chẳng hạn: esp32-2/data.
    • ESP32 #1 có thể gửi dữ liệu đến ESP32 #2 bằng cách xuất bản dữ liệu lên topic mà ESP32 #2 đã đăng ký.

    Theo cách này, hai ESP32 có thể trao đổi dữ liệu hai chiều.

Ví Dụ Ứng Dụng

Hãy thực hiện ứng dụng sau: Một nút nhấn/công tắc kết nối với ESP32 #1 điều khiển một LED kết nối với ESP32 #2 thông qua MQTT.

communication between two ESP32

Như đã đề cập ở trên, có một số giao thức ứng dụng mà chúng ta có thể sử dụng. Trong ví dụ này, để đơn giản hóa, chúng ta sẽ tự định nghĩa một giao thức (giao thức tự định nghĩa).

Cách Hoạt Động

Hãy định nghĩa một giao thức đơn giản:

  • Cả ESP32 #1ESP32 #2 đều kết nối đến một MQTT Broker (MQTT server).
  • Đối với ESP32 #1:
    • Nó xuất bản một tin nhắn MQTT đến một topic cụ thể bất cứ khi nào trạng thái của công tắc thay đổi.
    • Khi nút nhấn/công tắc được bật, payload của tin nhắn MQTT được đặt thành 1.
    • Khi nút nhấn/công tắc được tắt, payload của tin nhắn MQTT được đặt thành 0.
  • Đối với ESP32 #2:
    • Nó đăng ký cùng một topic.
    • Nếu ESP32 #2 nhận được tin nhắn MQTT với payload là 1, nó sẽ bật LED.
    • Nếu ESP32 #2 nhận được tin nhắn MQTT với payload là 0, nó sẽ tắt LED.

    Sơ Đồ Kết Nối

    • ESP32 #1 - Sơ đồ kết nối giữa ESP32 và nút nhấn
    ESP32 nút nhấn sơ đồ đấu dây

    This image is created using Fritzing. Click to enlarge image

    Nếu bạn chưa rõ cách cấp nguồn cho ESP32 và các linh kiện khác, xem: Cách Cung Cấp Nguồn Điện Cho ESP32.

    • ESP32 #2 - Sơ đồ kết nối giữa ESP32 và LED
    ESP32 LED sơ đồ đấu dây

    This image is created using Fritzing. Click to enlarge image

Giao Tiếp Giữa Hai ESP32 Qua MQTT

Code ESP32 #1

/* * Mã ESP32 này được phát triển bởi newbiely.vn * Mã ESP32 này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp32/esp32-to-esp32-mqtt-communication */ // ESP32 #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER #include <WiFi.h> #include <MQTTClient.h> #include <ezButton.h> #define BUTTON_PIN 21 // ESP32 pin GPIO21 connected to button const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // CHANGE TO YOUR WIFI SSID const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // CHANGE TO YOUR WIFI PASSWORD const char MQTT_BROKER_ADRRESS[] = "test.mosquitto.org"; // CHANGE TO MQTT BROKER'S ADDRESS //const char MQTT_BROKER_ADRRESS[] = "192.168.0.26"; // CHANGE TO MQTT BROKER'S IP ADDRESS const int MQTT_PORT = 1883; const char MQTT_CLIENT_ID[] = "esp32-001"; // CHANGE IT AS YOU DESIRE const char MQTT_USERNAME[] = ""; // CHANGE IT IF REQUIRED, empty if not required const char MQTT_PASSWORD[] = ""; // CHANGE IT IF REQUIRED, empty if not required // The MQTT topics that ESP32 should publish/subscribe const char MQTT_TOPIC[] = "esp32/command"; // CHANGE IT AS YOU DESIRE WiFiClient network; MQTTClient mqtt = MQTTClient(256); ezButton button(BUTTON_PIN); // create ezButton that attach to pin 7 void setup() { Serial.begin(9600); button.setDebounceTime(100); // set debounce time to 100 milliseconds Serial.println("ESP32 #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER"); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.println("ESP32 - Connecting to Wi-Fi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); connectToMQTT(); } void loop() { mqtt.loop(); button.loop(); // MUST call the loop() function first if (button.isPressed()) { Serial.println("- The button is pressed, send command: 1"); sendToMQTT('1'); } if (button.isReleased()) { Serial.println("- The button is released, send command: 0"); sendToMQTT('0'); } } void connectToMQTT() { // Connect to the MQTT broker mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network); Serial.print("ESP32 - Connecting to MQTT broker"); while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { Serial.print("."); delay(100); } Serial.println(); if (!mqtt.connected()) { Serial.println("ESP32 - MQTT broker Timeout!"); return; } Serial.println("ESP32 - MQTT broker Connected!"); } void sendToMQTT(char command) { char messageBuffer[1]; messageBuffer[0] = command; mqtt.publish(MQTT_TOPIC, messageBuffer); Serial.println("ESP32 - sent to MQTT:"); Serial.print("- topic: "); Serial.println(MQTT_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); }

Code ESP32 #2

/* * Mã ESP32 này được phát triển bởi newbiely.vn * Mã ESP32 này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp32/esp32-to-esp32-mqtt-communication */ // ESP32 #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER #include <WiFi.h> #include <MQTTClient.h> #define LED_PIN 18 // ESP32 pin GPIO18 connected to LED const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // CHANGE TO YOUR WIFI SSID const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // CHANGE TO YOUR WIFI PASSWORD const char MQTT_BROKER_ADRRESS[] = "test.mosquitto.org"; // CHANGE TO MQTT BROKER'S ADDRESS //const char MQTT_BROKER_ADRRESS[] = "192.168.0.26"; // CHANGE TO MQTT BROKER'S IP ADDRESS const int MQTT_PORT = 1883; const char MQTT_CLIENT_ID[] = "esp32-002"; // CHANGE IT AS YOU DESIRE const char MQTT_USERNAME[] = ""; // CHANGE IT IF REQUIRED, empty if not required const char MQTT_PASSWORD[] = ""; // CHANGE IT IF REQUIRED, empty if not required // The MQTT topics that ESP32 should publish/subscribe const char MQTT_TOPIC[] = "esp32/command"; // CHANGE IT AS YOU DESIRE WiFiClient network; MQTTClient mqtt = MQTTClient(256); void setup() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); Serial.println("ESP32 #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER"); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.println("ESP32 - Connecting to Wi-Fi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); connectToMQTT(); } void loop() { mqtt.loop(); } void connectToMQTT() { // Connect to the MQTT broker mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network); // Create a handler for incoming messages mqtt.onMessage(messageReceived); Serial.print("ESP32 - Connecting to MQTT broker"); while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { Serial.print("."); delay(100); } Serial.println(); if (!mqtt.connected()) { Serial.println("ESP32 - MQTT broker Timeout!"); return; } // Subscribe to a topic, the incoming messages are processed by messageReceived() function if (mqtt.subscribe(MQTT_TOPIC)) Serial.print("ESP32 - Subscribed to the topic: "); else Serial.print("ESP32 - Failed to subscribe to the topic: "); Serial.println(MQTT_TOPIC); Serial.println("ESP32 - MQTT broker Connected!"); } void messageReceived(String &topic, String &payload) { Serial.println("ESP32 - received from MQTT:"); Serial.println("- topic: " + topic); Serial.print("- payload: "); Serial.println(payload); char command = payload[0]; if (command == '1') { Serial.print("- Received command: "); Serial.print(command); Serial.println(" => Turned LED on"); digitalWrite(LED_PIN, HIGH); // Turn LED on } else if (command == '0') { Serial.print("- Received command: "); Serial.print(command); Serial.println(" => Turned LED off"); digitalWrite(LED_PIN, LOW); // Turn LED off } else { Serial.print("- Received an unsupported command: "); Serial.println(command); } }

Các Bước Thực Hiện

  • Nếu đây là lần đầu tiên bạn sử dụng ESP32, hãy xem ESP32 - Cài Đặt Phần Mềm.
  • Mở hai Arduino IDE trên PC của bạn.
  • Kết nối nút nhấn/công tắc với ESP32 #1
  • Kết nối LED với ESP32 #2
  • Mở Library Manager bằng cách click vào biểu tượng Library Manager trên thanh điều hướng bên trái của Arduino IDE
  • MQTT trong ô tìm kiếm, sau đó tìm thư viện MQTT của Joel Gaehwiler.
  • Click nút Install để cài đặt thư viện MQTT.
ESP32 mqtt thư viện
  • ezButton trong ô tìm kiếm, sau đó tìm thư viện button của ArduinoGetStarted
  • Click nút Install để cài đặt thư viện ezButton.
ESP32 nút nhấn thư viện
  • Chọn bo mạch ESP32 phù hợp (ví dụ: ESP32 Dev Module).
  • Kết nối ESP32 #1 với PC qua cáp USB và chọn COM port của ESP32 #1 trên Arduino IDE #1
  • Kết nối ESP32 #2 với PC qua cáp USB và chọn COM port của ESP32 #2 trên Arduino IDE #2
  • Copy code ESP32 #1, dán vào Arduino IDE #1 và lưu lại (đặt tên ESP32-1)
  • Copy code ESP32 #2, dán vào Arduino IDE #2 và lưu lại (đặt tên ESP32-2)
  • Thay thế thông tin WiFi (SSID và password) trong cả hai code với thông tin của bạn.
  • Thay thế địa chỉ MQTT broker trong cả hai code (tên miền hoặc địa chỉ IP).
  • Upload code ESP32 #1 lên ESP32 #1
  • Upload code ESP32 #2 lên ESP32 #2
  • Mở Serial Monitor trên Arduino IDE #1
  • Mở Serial Monitor trên Arduino IDE #2
  • Nhấn và giữ nút nhấn trên ESP32 #1 → xem trạng thái LED trên ESP32 #2 (BẬT)
  • Thả nút nhấn trên ESP32 #1 → xem trạng thái LED trên ESP32 #2 (TẮT)
  • Nhấn, giữ và thả nút nhấn nhiều lần.
  • Xem kết quả trên cả hai Serial Monitor
    • Serial Monitor của ESP32 #1
    COM6
    Send
    ESP32 #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER ESP32 - Attempting to connect to SSID: YOUR_WIFI_SSID ESP32 - Connecting to MQTT broker ESP32 - MQTT broker Connected! - The button is pressed, send command: 1 ESP32 - sent to MQTT: - topic: esp32/command - payload:1 - The button is released, send command: 0 ESP32 - sent to MQTT: - topic: esp32/command - payload:0
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  
    • Serial Monitor của ESP32 #2
    COM6
    Send
    ESP32 #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER ESP32 - Attempting to connect to SSID: YOUR_WIFI_SSID ESP32 - Connecting to MQTT broker ESP32 - Subscribed to the topic: esp32/command ESP32 - MQTT broker Connected! ESP32 - received from MQTT: - topic: esp32/command - payload: 1 - Received command: 1 => Turned LED on ESP32 - received from MQTT: - topic: esp32/command - payload: 0 - Received command: 0 => Turned LED off
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline