Arduino MQTT

Trong bài hướng dẫn này, chúng ta sẽ học cách sử dụng Arduino để gửi và nhận dữ liệu tới broker MQTT bằng giao thức MQTT. Cụ thể, chúng ta sẽ học:

Arduino mqtt

Chúng ta sẽ khám phá hai trường hợp sử dụng khác nhau:

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

1×Arduino UNO R4 WiFi
1×Alternatively, DIYables STEM V4 IoT
1×(Tùy chọn) DIYables STEM V4 IoT
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
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 STEM V4 IoT Starter Kit (Arduino included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Về Arduino và MQTT

Giả sử bạn đã làm quen với giao thức MQTT. Nếu chưa, vui lòng tra cứu trên Internet. Hướng dẫn này tập trung vào lập trình Arduino để gửi và nhận dữ liệu bằng giao thức MQTT.

Dưới đây là các trường hợp sử dụng của Arduino với MQTT:

  • Arduino kết nối với broker MQTT trực tuyến, ví dụ: broker Mosquitto trực tuyến, AWS IoT...
  • Arduino kết nối với broker MQTT được cài đặt trên máy tính của bạn, ví dụ: broker Mosquitto, broker HiveMQ
  • Arduino kết nối với broker MQTT được cài đặt trên Raspberry Pi của bạn, ví dụ: broker Mosquitto
  • Arduino kết nối với broker MQTT được cài đặt trên đám mây: ví dụ: broker Mosquitto hoặc HiveMQ trên AWS EC2

Trong bài hướng dẫn này, chúng ta sẽ bắt đầu bằng cách nhanh chóng kiểm tra xem Arduino có thể kết nối với một broker Mosquitto trực tuyến hay không. Arduino sẽ phát và đăng ký nhận với broker này qua Internet.

Tiếp theo, chúng ta sẽ tiến hành cài đặt máy chủ Mosquitto trên máy tính của mình. Sau đó, chúng ta sẽ kết nối Arduino với broker MQTT được cài đặt trên máy tính, tiếp tục phát và nhận dữ liệu thông qua broker cục bộ này.

Sau khi bạn hoàn thành bài hướng dẫn này, bạn có thể khám phá thêm bằng cách học về Arduino với MQTT trong các bài hướng dẫn sau:

Kết nối Arduino với một máy chủ MQTT trực tuyến

Trong phần này, chúng ta sẽ học cách kết nối Arduino với test.mosquitto.org, một broker MQTT trực tuyến do Mosquitto tạo ra. Lưu ý rằng broker này chỉ dành cho mục đích thử nghiệm.

Mã Arduino

Mã Arduino dưới đây thực hiện điều gì:

  • Kết nối tới máy chủ MQTT
  • Đăng ký một chủ đề
  • Định kỳ phát tin nhắn tới cùng một chủ đề mà nó đã đăng ký
/* * 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-mqtt */ #include <WiFiS3.h> #include <MQTTClient.h> #include <ArduinoJson.h> 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 int MQTT_PORT = 1883; const char MQTT_CLIENT_ID[] = "YOUR-NAME-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 PUBLISH_TOPIC[] = "YOUR-NAME-arduino-001/loopback"; // CHANGE IT AS YOU DESIRE const char SUBSCRIBE_TOPIC[] = "YOUR-NAME-arduino-001/loopback"; // CHANGE IT AS YOU DESIRE const int PUBLISH_INTERVAL = 5000; // 5 seconds WiFiClient network; MQTTClient mqtt = MQTTClient(256); unsigned long lastPublishTime = 0; void setup() { Serial.begin(9600); 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(); if (millis() - lastPublishTime > PUBLISH_INTERVAL) { sendToMQTT(); lastPublishTime = millis(); } } void connectToMQTT() { // Connect to the MQTT broker mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network); // Create a handler for incoming messages mqtt.onMessage(messageHandler); 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 messageHandler() function if (mqtt.subscribe(SUBSCRIBE_TOPIC)) Serial.print("Arduino - Subscribed to the topic: "); else Serial.print("Arduino - Failed to subscribe to the topic: "); Serial.println(SUBSCRIBE_TOPIC); Serial.println("Arduino - MQTT broker Connected!"); } void sendToMQTT() { StaticJsonDocument<200> message; message["timestamp"] = millis(); message["data"] = analogRead(0); // Or you can read data from other sensors char messageBuffer[512]; serializeJson(message, messageBuffer); mqtt.publish(PUBLISH_TOPIC, messageBuffer); Serial.println("Arduino - sent to MQTT:"); Serial.print("- topic: "); Serial.println(PUBLISH_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); } void messageHandler(String &topic, String &payload) { Serial.println("Arduino - received from MQTT:"); Serial.println("- topic: " + topic); Serial.println("- payload:"); Serial.println(payload); }

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

  • Nếu đây là lần đầu bạn sử dụng Arduino Uno R4, hãy xem Cách bắt đầu với Arduino UNO R4.
  • Mở Arduino IDE trên máy tính của bạn
  • Mở Quản lý Thư viện bằng cách nhấp vào biểu tượng Quản lý Thư viện ở thanh điều hướng bên trái của Arduino IDE
  • Nhập MQTT vào hộp tìm kiếm, sau đó tìm thư viện MQTT do Joel Gaehwiler.
  • Nhấp vào nút Cài đặt để cài đặt thư viện MQTT.
thư viện mqtt cho Arduino
  • Nhập ArduinoJson vào ô tìm kiếm, sau đó tìm thư viện ArduinoJson của Benoit Blanchon.
  • Nhấn nút Cài đặt để cài đặt thư viện ArduinoJson.
thư viện Arduinojson
  • Sao chép mã ở trên và mở bằng Arduino IDE
  • Thay thế thông tin WiFi (SSID và mật khẩu) trong mã bằng của bạn.
  • Trong mã, bạn sẽ thấy từ 'YOUR-NAME' xuất hiện ba lần. Thay thế từ này bằng tên của bạn hoặc ký tự ngẫu nhiên (chỉ ký tự chữ cái, không có khoảng trắng). Điều này là cần thiết vì nếu bạn không thực hiện thay đổi, có thể có nhiều người chạy mã này cùng lúc, dẫn đến xung đột do các ID của client MQTT và các chủ đề (topics) giống nhau cho mọi người.
  • Nhấn nút Tải lên trên Arduino IDE để tải mã lên Arduino
  • Mở Serial Monitor
  • Xem kết quả trên Serial Monitor.
COM6
Send
IP Address: 192.168.0.2 Arduino - Connecting to MQTT broker Arduino - Subscribed to the topic: YOUR-NAME-arduino-001/loopback Arduino - MQTT broker Connected! Arduino - sent to MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload:{"timestamp":11757,"data":255} Arduino - received from MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload: {"timestamp":11757,"data":255} Arduino - sent to MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload:{"timestamp":16896,"data":259} Arduino - received from MQTT: - topic: YOUR-NAME-arduino-001/loopback - payload: {"timestamp":16896,"data":259}
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Như bạn có thể thấy, Arduino gửi các thông điệp tới máy chủ MQTT (broker), sau đó nhận lại cùng một thông điệp. Đó là vì đoạn mã ở trên đăng ký nhận trên cùng một chủ đề mà nó xuất bản dữ liệu tới. Nếu bạn không muốn Arduino nhận được thông điệp mà nó phát, chỉ cần để cho chủ đề nhận (SUBSCRIBE) khác với chủ đề phát (PUBLISH).

Kết nối Arduino với broker MQTT được cài đặt trên PC của bạn

Cài đặt máy chủ MQTT Mosquitto

  • Tải xuống Mosquitto MQTT Broker
  • Cài đặt nó trên ổ đĩa D: thay vì ổ đĩa C:. Tránh cài đặt broker Mosquitto trên ổ đĩa C: để ngăn ngừa các sự cố có thể xảy ra.

Chạy máy chủ MQTT Mosquitto

Bây giờ, hãy kiểm tra xem broker MQTT có hoạt động đúng hay không bằng cách làm theo các bước sau:

  • Đi đến thư mục đã cài đặt Mosquitto. Ví dụ: D:\Draft\mosquitto>
  • Tạo một tệp mới có tên test.conf, sao chép nội dung dưới đây, và lưu nó vào thư mục đó:
listener 1883 allow_anonymous true
  • Chạy Command Prompt với quyền quản trị trên máy tính của bạn. Hãy gọi nó là Broker Window. Không đóng nó cho đến khi kết thúc bài hướng dẫn.
dòng lệnh windows quản trị viên
  • Chạy lần lượt các lệnh dưới đây:
cd /d D:\Draft\mosquitto mosquitto -v -c test.conf
  • Bạn sẽ thấy:
Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto -v -c test.conf 1710918939: mosquitto version 2.0.18 starting 1710918939: Config loaded from test.conf. 1710918939: Opening ipv6 listen socket on port 1883. 1710918939: Opening ipv4 listen socket on port 1883. 1710918939: mosquitto version 2.0.18 running
  • Mở một cửa sổ Dòng lệnh khác ở chế độ Quản trị viên trên máy tính của bạn.
  • Tìm địa chỉ IP của máy tính của bạn bằng cách chạy lệnh dưới đây:
ipconfig
Command Prompt
C:\WINDOWS\system32>ipconfig Windows IP Configuration Ethernet adapter: Subnet Mask . . . . . . . . . . . : 255.0.0.0 IPv4 Address. . . . . . . . . . . : 192.168.0.26 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . :
  • Ghi lại địa chỉ IP để dùng sau. Trong ví dụ ở trên: 192.168.0.26

Kiểm tra xem Mosquitto Broker có hoạt động không

  • Mở một cửa sổ Dòng lệnh khác với quyền quản trị trên máy tính của bạn. Hãy gọi nó là Cửa sổ người đăng ký
  • Đăng ký một chủ đề bằng cách chạy các lệnh dưới đây lần lượt (thay thế bằng địa chỉ IP của bạn):
cd /d D:\Draft\mosquitto mosquitto_sub -h 192.168.0.26 -p 1883 -t arduino-001/send
  • Mở Command Prompt khác với quyền quản trị viên trên máy tính của bạn. Gọi nó là Cửa sổ Người phát hành
  • Đăng một thông điệp lên cùng một chủ đề bằng cách chạy lần lượt các lệnh dưới đây (thay bằng địa chỉ IP của bạn):
cd /d D:\Draft\mosquitto mosquitto_pub -h 192.168.0.26 -p 1883 -t arduino-001/send -m "Hello, MQTT!"
  • Bạn sẽ thấy:
Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto_pub -h 192.168.0.26 -p 1883 -t arduino-001/send -m "Hello, MQTT!" D:\Draft\mosquitto>

Bạn sẽ thấy thông điệp được chuyển tiếp tới Cửa sổ người đăng ký như sau:

Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto_sub -h 192.168.0.26 -p 1883 -t arduino-001/send Hello, MQTT!

Bây giờ, bạn đã cài đặt thành công máy chủ MQTT Mosquitto trên máy tính của mình. Vui lòng KHÔNG đóng ba cửa sổ sau: Cửa sổ Broker, Cửa sổ Người đăng ký, và Cửa sổ Người phát. Chúng ta sẽ dùng chúng ở phần sau.

Mã Arduino

Đoạn mã Arduino dưới đây thực hiện:

  • Kết nối tới broker MQTT
  • Đăng ký nhận tin nhắn từ một chủ đề
  • Định kỳ phát tin nhắn đến một chủ đề khác
/* * 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-mqtt */ #include <WiFiS3.h> #include <MQTTClient.h> #include <ArduinoJson.h> 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 PUBLISH_TOPIC[] = "arduino-001/send"; // CHANGE IT AS YOU DESIRE const char SUBSCRIBE_TOPIC[] = "arduino-001/receive"; // CHANGE IT AS YOU DESIRE const int PUBLISH_INTERVAL = 5000; // 5 seconds WiFiClient network; MQTTClient mqtt = MQTTClient(256); unsigned long lastPublishTime = 0; void setup() { Serial.begin(9600); 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(); if (millis() - lastPublishTime > PUBLISH_INTERVAL) { sendToMQTT(); lastPublishTime = millis(); } } void connectToMQTT() { // Connect to the MQTT broker mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network); // Create a handler for incoming messages mqtt.onMessage(messageHandler); 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 messageHandler() function if (mqtt.subscribe(SUBSCRIBE_TOPIC)) Serial.print("Arduino - Subscribed to the topic: "); else Serial.print("Arduino - Failed to subscribe to the topic: "); Serial.println(SUBSCRIBE_TOPIC); Serial.println("Arduino - MQTT broker Connected!"); } void sendToMQTT() { StaticJsonDocument<200> message; message["timestamp"] = millis(); message["data"] = analogRead(0); // Or you can read data from other sensors char messageBuffer[512]; serializeJson(message, messageBuffer); mqtt.publish(PUBLISH_TOPIC, messageBuffer); Serial.println("Arduino - sent to MQTT:"); Serial.print("- topic: "); Serial.println(PUBLISH_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); } void messageHandler(String &topic, String &payload) { Serial.println("Arduino - received from MQTT:"); Serial.println("- topic: " + topic); Serial.println("- payload:"); Serial.println(payload); // You can process the incoming data as json object, then control something /* StaticJsonDocument<200> doc; deserializeJson(doc, payload); const char* message = doc["message"]; */ }

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

  • Sao chép mã ở trên và mở bằng Arduino IDE
  • Thay thế thông tin WiFi (SSID và mật khẩu) trong mã bằng của bạn.
  • Thay thế địa chỉ broker MQTT trong mã (tên miền hoặc địa chỉ IP).
  • Nhấp vào nút Tải lên trên Arduino IDE để tải mã lên Arduino

Gửi tin nhắn từ Arduino tới PC qua MQTT

Mã Arduino phát dữ liệu lên chủ đề MQTT arduino-001/send, Cửa sổ người đăng ký trên PC đăng ký chủ đề đó để nhận dữ liệu.

  • Mở Serial Monitor, bạn sẽ thấy Arduino định kỳ phát một tin nhắn lên một chủ đề.
COM6
Send
IP Address: 192.168.0.2 Arduino - Connecting to MQTT broker Arduino - Subscribed to the topic: arduino-001/receive Arduino - MQTT broker Connected! Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":10708,"data":311} Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":15837,"data":298} Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":20965,"data":291} Arduino - sent to MQTT: - topic: arduino-001/send - payload:{"timestamp":26094,"data":286}
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Kiểm tra Cửa sổ người đăng ký, bạn sẽ thấy nó nhận được thông điệp được Arduino phát hành như dưới đây:
Command Prompt
Microsoft Windows [Version 10.0.19045.3930] (c) Microsoft Corporation. All rights reserved. C:\WINDOWS\system32>cd /d D:\Draft\mosquitto D:\Draft\mosquitto>mosquitto_sub -h 192.168.0.26 -p 1883 -t arduino-001/send Hello, MQTT! {"timestamp":10708,"data":311} {"timestamp":15837,"data":298} {"timestamp":20965,"data":291} {"timestamp":26094,"data":286}

Gửi tin nhắn từ PC đến Arduino thông qua MQTT

Arduino đăng ký nhận chủ đề arduino-001/receive, Cửa sổ Người xuất bản trên PC sẽ phát một thông điệp tới chủ đề đó để gửi nó đến Arduino.

  • Đăng một tin nhắn lên chủ đề mà Arduino đã đăng ký bằng cách chạy lệnh sau trên Publisher Window:
mosquitto_pub -h 192.168.0.26 -p 1883 -t arduino-001/receive -m "Hello, Arduino!"
  • Bạn sẽ thấy tin nhắn này được Arduino nhận trên Serial Monitor như sau:
COM6
Send
Arduino - received from MQTT: - topic: arduino-001/receive - payload: Hello, Arduino!
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Video Tutorial

Việc sản xuất video tốn rất nhiều thời gian. Nếu video hướng dẫn hữu ích cho việc học của bạn, hãy đăng ký kênh YouTube để ủng hộ. Nếu nhu cầu đủ cao, chúng tôi sẽ cố gắng làm thêm nhiều video.