Giao tiếp Arduino với Arduino bằng MQTT

Trong hướng dẫn này, chúng ta sẽ học:

giao tiếp giữa hai Arduino thông qua mqtt

Phần cứng cần chuẩn bị

2×Arduino UNO R4 WiFi
2×USB Cable Type-C
1×(Khuyến nghị) Screw Terminal Block Shield for Arduino UNO R4
1×(Khuyến nghị) Breadboard Shield for Arduino UNO R4
1×(Khuyến nghị) Enclosure for Arduino UNO R4
1×(Khuyến nghị) Power Splitter for Arduino UNO R4
1×(Khuyến nghị) Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

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

Về Arduino và MQTT

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

Giao tiếp giữa hai Arduino thông qua MQTT

Hai board Arduino có thể giao tiếp với nhau thông qua một máy chủ MQTT. Nếu bạn muốn hai Arduino giao tiếp trực tiếp mà không sử dụng máy chủ MQTT, vui lòng tham khảo hướng dẫn về Giao tiếp giữa hai Arduino.

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

  • Cả hai Arduino đều kết nối với broker MQTT.
  • Để Arduino #2 gửi dữ liệu đến Arduino #1:
    • Arduino #1 đăng ký nhận một chủ đề, ví dụ: arduino-1/data.
    • Arduino #2 có thể gửi dữ liệu đến Arduino #1 bằng cách phát dữ liệu lên chủ đề mà Arduino #1 đang đăng ký nhận.
  • Tương tự, để Arduino #1 gửi dữ liệu đến Arduino #2:
    • Arduino #2 đăng ký nhận một chủ đề, ví dụ: arduino-2/data.
    • Arduino #1 có thể gửi dữ liệu đến Arduino #2 bằng cách phát dữ liệu lên chủ đề mà Arduino #2 đang đăng ký nhận.

    Bằng cách làm theo phương pháp này, hai bộ mạch Arduino có thể trao đổi dữ liệu hai chiều.

Ví dụ về trường hợp sử dụng

Hãy hiện thực hóa ứng dụng sau: một nút hoặc công tắc được kết nối với Arduino #1 sẽ điều khiển một LED được kết nối với Arduino #2 thông qua MQTT.

giao tiếp giữa hai Arduino

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, chúng ta sẽ tự định nghĩa một giao thức (một giao thức do chính chúng ta tự định nghĩa).

Giao thức tự định nghĩa

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

  • Arduino #1Arduino #2 kết nối với MQTT Broker (máy chủ MQTT)
  • Arduino #1:
    • Arduino #1 phát một thông điệp MQTT đến một chủ đề khi trạng thái của công tắc bị thay đổi.
    • Khi nút/công tắc được chuyển sang trạng thái bật, nội dung của thông điệp MQTT là 1.
    • Khi nút/công tắc được chuyển sang trạng thái tắt, nội dung của thông điệp MQTT là 0.
  • Arduino #2:
    • Arduino #2 đăng ký nhận tin từ chủ đề
    • Nếu Arduino #2 nhận được một thông điệp MQTT có nội dung là 1, nó sẽ bật đèn LED
    • Nếu Arduino #2 nhận được một thông điệp MQTT có nội dung là 0, nó sẽ tắt đèn LED

    Sơ đồ nối dây

    • Arduino #1 - Sơ đồ nối giữa Arduino và nút nhấn
    sơ đồ nối nút Arduino

    This image is created using Fritzing. Click to enlarge image

    • Arduino số 2 - Sơ đồ nối dây giữa Arduino và LED
    sơ đồ nối dây LED với Arduino

    This image is created using Fritzing. Click to enlarge image

Giao tiếp giữa hai Arduino qua MQTT

Mã Arduino #1

/* * Mã Arduino này được phát triển bởi newbiely.vn * Mã Arduino 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/arduino/arduino-to-arduino-mqtt-communication */ // ARDUINO #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER #include <WiFiS3.h> #include <MQTTClient.h> #include <ezButton.h> const int BUTTON_PIN = 7; 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[] = "arduino-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 Arduino should publish/subscribe const char MQTT_TOPIC[] = "arduino/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("ARDUINO #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER"); int status = WL_IDLE_STATUS; while (status != WL_CONNECTED) { Serial.print("Arduino - Attempting to connect to SSID: "); Serial.println(WIFI_SSID); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // wait 10 seconds for connection: delay(10000); } // print your board's IP address: Serial.print("IP Address: "); Serial.println(WiFi.localIP()); 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("Arduino - 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("Arduino - MQTT broker Timeout!"); return; } Serial.println("Arduino - MQTT broker Connected!"); } void sendToMQTT(char command) { char messageBuffer[1]; messageBuffer[0] = command; mqtt.publish(MQTT_TOPIC, messageBuffer); Serial.println("Arduino - sent to MQTT:"); Serial.print("- topic: "); Serial.println(MQTT_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); }

Mã Arduino số 2

/* * Mã Arduino này được phát triển bởi newbiely.vn * Mã Arduino 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/arduino/arduino-to-arduino-mqtt-communication */ // ARDUINO #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER #include <WiFiS3.h> #include <MQTTClient.h> const int LED_PIN = 9; 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[] = "arduino-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 Arduino should publish/subscribe const char MQTT_TOPIC[] = "arduino/command"; // CHANGE IT AS YOU DESIRE WiFiClient network; MQTTClient mqtt = MQTTClient(256); void setup() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); Serial.println("ARDUINO #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER"); int status = WL_IDLE_STATUS; while (status != WL_CONNECTED) { Serial.print("Arduino - Attempting to connect to SSID: "); Serial.println(WIFI_SSID); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // wait 10 seconds for connection: delay(10000); } // print your board's IP address: Serial.print("IP Address: "); Serial.println(WiFi.localIP()); 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("Arduino - 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("Arduino - MQTT broker Timeout!"); return; } // Subscribe to a topic, the incoming messages are processed by messageReceived() function if (mqtt.subscribe(MQTT_TOPIC)) Serial.print("Arduino - Subscribed to the topic: "); else Serial.print("Arduino - Failed to subscribe to the topic: "); Serial.println(MQTT_TOPIC); Serial.println("Arduino - MQTT broker Connected!"); } void messageReceived(String &topic, String &payload) { Serial.println("Arduino - 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); } }

Hướng dẫn từng bước

  • Nối một nút/nút công tắc vào Arduino #1
  • Nối một đèn LED vào Arduino #2
  • Mở Arduino IDE (được gọi là Arduino IDE #1)
  • Mở một cửa sổ Arduino IDE khác (được gọi là Arduino IDE #2) bằng cách nhấp chuột vào biểu tượng Arduino IDE trên máy tính của bạn (quan trọng!())
  • Mở Library Manager bằng cách nhấp vào biểu tượng Trình quản lý thư viện trên thanh điều hướng bên trái của Arduino IDE
  • MQTT vào ô tìm kiếm, sau đó tìm thư viện MQTT của Joel Gaehwiler.
  • Nhấp vào nút Cài đặt để cài đặt thư viện MQTT.
thư viện mqtt cho Arduino
  • ezButton vào ô tìm kiếm, sau đó tìm thư viện nút từ ArduinoGetStarted.
  • Nhấp vào nút Install để cài đặt thư viện ezButton.
thư viện nút Arduino
  • Kết nối Arduino #1 với PC qua cáp USB và chọn cổng COM của Arduino #1 trên Arduino IDE #1
  • Kết nối Arduino #2 với PC qua cáp USB và chọn cổng COM của Arduino #2 trên Arduino IDE #2
  • Sao chép mã Arduino #1, dán vào Arduino IDE #1 và lưu nó (được đặt tên Arduino-1)
  • Sao chép mã Arduino #2, dán vào Arduino IDE #2 và lưu nó (được đặt tên Arduino-2)
  • Thay thế thông tin WiFi (SSID và mật khẩu) trong cả hai mã bằng thông tin của bạn.
  • Thay thế địa chỉ broker MQTT trong cả hai mã (tên miền hoặc địa chỉ IP).
  • Tải mã Arduino #1 lên Arduino #1
  • Tải mã Arduino #2 lên Arduino #2
  • Mở Serial Monitor trên Arduino IDE #1
  • Mở Serial Monitor trên Arduino IDE #2
  • Nhấn và giữ nút trên Arduino #1 → xem trạng thái đèn LED trên Arduino #2 (BẬT)
  • Nhả nút trên Arduino #1 → xem trạng thái đèn LED trên Arduino #2 (TẮT)
  • Nhấn, giữ và thả nút vài lần.
  • Xem đầu ra trên cả hai Serial Monitor
  • Serial Monitor của Arduino #1
COM6
Send
Arduino #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER Arduino - Attempting to connect to SSID: YOUR_WIFI_SSID IP Address: 192.168.0.2 Arduino - Connecting to MQTT broker Arduino - MQTT broker Connected! - The button is pressed, send command: 1 Arduino - sent to MQTT: - topic: arduino/command - payload:1 - The button is released, send command: 0 Arduino - sent to MQTT: - topic: arduino/command - payload:0
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Trình theo dõi nối tiếp của Arduino #2
COM6
Send
Arduino #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER Arduino - Attempting to connect to SSID: YOUR_WIFI_SSID IP Address: 192.168.0.2 Arduino - Connecting to MQTT broker Arduino - Subscribed to the topic: arduino/command Arduino - MQTT broker Connected! Arduino - received from MQTT: - topic: arduino/command - payload: 1 - Received command: 1 => Turned LED on Arduino - received from MQTT: - topic: arduino/command - payload: 0 - Received command: 0 => Turned LED off
Autoscroll Show timestamp
Clear output
9600 baud  
Newline