Hotline/Zalo: 0919.890.938 (Mr Hơn)
Bài 16. Giao thức MQTT trong lập trình ESP8266 và IOT
MQTT là một giao thức giao tiếp nhẹ và linh hoạt, được thiết kế cho các ứng dụng IOT (Internet of Things). Giao thức MQTT dựa trên mô hình publish-subscribe, trong đó các thiết bị IOT có thể gửi và nhận các tin nhắn qua một máy chủ trung gian gọi là broker. Trong bài viết này Điện thông minh E-smart sẽ cùng các bạn tìm hiểu về MQTT trong lập trình ESP8266.
Giao thức MQTT là gì?
MQTT là viết tắt của Message Queuing Telemetry Transport, là một giao thức giao tiếp nhẹ dựa trên mô hình publish-subscribe. Giao thức này cho phép các thiết bị IOT gửi và nhận các tin nhắn nhỏ và đơn giản qua mạng Internet.
MQTT có ba thành phần chính: publisher, broker và subscriber. Publisher là thiết bị gửi tin nhắn đến broker, broker là máy chủ trung gian quản lý các tin nhắn và chuyển tiếp chúng đến subscriber, subscriber là thiết bị nhận tin nhắn từ broker.
MQTT sử dụng khái niệm topic để phân loại các tin nhắn. Topic là một chuỗi ký tự có cấu trúc theo dạng /level1/level2/…/leveln. Mỗi publisher và subscriber có thể đăng ký hoặc hủy đăng ký các topic tùy ý. Broker sẽ chuyển tiếp các tin nhắn từ publisher đến subscriber dựa trên topic của tin nhắn.
MQTT có ba mức độ Quality of Service (QoS) để đảm bảo tính toàn vẹn của các tin nhắn:
- QoS 0: Tin nhắn được gửi một lần duy nhất, không có xác nhận. Có thể bị mất hoặc trùng lặp.
- QoS 1: Tin nhắn được gửi ít nhất một lần, có xác nhận. Có thể bị trùng lặp.
- QoS 2: Tin nhắn được gửi chính xác một lần, có xác nhận. Không bị mất hoặc trùng lặp.
ESP8266 là gì?
ESP8266 là một chip vi điều khiển có khả năng kết nối Wi-Fi và thực hiện các ứng dụng IOT. ESP8266 có thể lập trình bằng nhiều ngôn ngữ khác nhau, nhưng phổ biến nhất là dùng Arduino IDE.
ESP8266 có nhiều phiên bản khác nhau, nhưng phổ biến nhất là NodeMCU và Wemos D1 mini. Các phiên bản này có sẵn các chân GPIO để kết nối với các cảm biến và thiết bị ngoại vi.
ESP8266 có thể sử dụng các thư viện Arduino để hỗ trợ giao tiếp MQTT, như PubSubClient hoặc ESP-MQTT. Các thư viện này cho phép ESP8266 kết nối với broker MQTT, đăng ký và hủy đăng ký các topic, gửi và nhận các tin nhắn với các mức QoS khác nhau.
Lập trình MQTT với ESP8266
Phần cứng và phần mềm
Chúng ta cần trang bị các thành phần sau:
- Một ESP8266 (NodeMCU hoặc Wemos D1 mini) và cáp USB để kết nối với máy tính.
- Một broker MQTT trên mạng Internet, có thể sử dụng các dịch vụ miễn phí như HiveMQ, Mosquitto hoặc CloudMQTT.
- Một ứng dụng MQTT client trên máy tính hoặc điện thoại, có thể sử dụng các phần mềm như MQTT.fx, MQTT Explorer, MQTT Dash hoặc bạn có thể sử dụng Websocket Client.
- Một cảm biến nhiệt độ và độ ẩm DHT11 để kết nối với ESP8266.
Các bước thực hiện
Tạo broker MQTT
Trong ví dụ này mình sử dụng HiveMQ broker. Bạn truy cập vào website: https://www.hivemq.com/ sau đó chọn Get HiveMQ
Chọn tiếp HiveMQ Cloud
Click vào Sign Up, điền địa chỉ email và mật khẩu sau đó chọn Sign Up để đăng ký
Truy cập và mở Email do HiveMQ gửi đến click vào Confirm my account để hoàn tất đăng ký
Tiến hành đăng nhập tài khoản HiveMQ và thiết lập thông tin cơ bản
- Lấy thông tin về địa chỉ, cổng, tên người dùng và mật khẩu của broker MQTT.
Lấy thông tin về địa chỉ URL và port kết nối của broker MQTT
Tạo tên người dùng và mật khẩu truy cập của broker MQTT
Kết nối phần cứng và nạp code chương trình
- Cài đặt Arduino IDE và thêm ESP8266 vào board manager.
- Cài đặt thư viện PubSubClient và DHT sensor library for ESPx cho Arduino IDE.
- Kết nối cảm biến DHT với ESP8266 theo sơ đồ sau:
- Mở Arduino IDE và tạo một sketch mới với nội dung sau:
#include<ESP8266WiFi.h>
#include "DHTesp.h"
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#define DHTpin 2
DHTesp dht;
//----Thay đổi thành thông tin của bạn---------------
const char* ssid = "DTM E-SMART"; //Wifi connect
const char* password = "0919890938"; //Password
const char* mqtt_server = "ec405b5b55474xxxxxxxxxx.s2.eu.hivemq.cloud";
const int mqtt_port = 8883;
const char* mqtt_username = "e-smart"; //User
const char* mqtt_password = "abc@1234"; //Password
//--------------------------------------------------
WiFiClientSecure espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//------------Connect to MQTT Broker-----------------------------
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientID = "ESPClient-";
clientID += String(random(0xffff),HEX);
if (client.connect(clientID.c_str(), mqtt_username, mqtt_password)) {
Serial.println("connected");
client.subscribe("esp8266/client");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
//-----Call back Method for Receiving MQTT massage---------
void callback(char* topic, byte* payload, unsigned int length) {
String incommingMessage = "";
for(int i=0; i<length;i++) incommingMessage += (char)payload[i];
Serial.println("Massage arived ["+String(topic)+"]"+incommingMessage);
}
//-----Method for Publishing MQTT Messages---------
void publishMessage(const char* topic, String payload, boolean retained){
if(client.publish(topic,payload.c_str(),true))
Serial.println("Message published ["+String(topic)+"]: "+payload);
}
void setup() {
Serial.begin(9600);
while(!Serial) delay(1);
dht.setup(DHTpin,DHTesp::DHT11);
setup_wifi();
espClient.setInsecure();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
unsigned long timeUpdata=millis();
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
//read DHT11
if(millis()-timeUpdata>5000){
delay(dht.getMinimumSamplingPeriod());
float h = dht.getHumidity();
float t = dht.getTemperature();
DynamicJsonDocument doc(1024);
doc["humidity"]=h;
doc["temperature"]=t;
char mqtt_message[128];
serializeJson(doc,mqtt_message);
publishMessage("esp8266/dht11", mqtt_message, true);
timeUpdata=millis();
}
}
Thay thế phần tên wifi, mật khẩu wifi, mqtt_server, mqtt_username và mqtt_password
- Để kiểm tra kết quả của chương trình, bạn cần làm các bước sau:
- Nạp sketch vào ESP8266 bằng Arduino IDE.
- Mở serial monitor để xem các thông báo từ ESP8266.
- Mở WEB CLIENT và kết nối với broker MQTT mà bạn đã đăng ký.
- Đăng ký topic mà bạn đã định nghĩa trong sketch, ví dụ
esp8266/dht
.
- Xem các tin nhắn JSON được gửi từ ESP8266 đến topic đó, chứa các giá trị nhiệt độ và độ ẩm.
- Bạn cũng có thể gửi các tin nhắn khác đến topic esp8266/client để kiểm tra khả năng nhận của ESP8266, ví dụ
{"message": "Hello from MQTT client"}
.
Kết luận
Trong bài viết này, bạn đã học cách sử dụng giao thức MQTT trong lập trình ESP8266 và IOT. Bạn đã biết cơ bản về giao thức MQTT, cách kết nối ESP8266 với broker MQTT, cách gửi và nhận các tin nhắn MQTT với các mức QoS khác nhau, cách sử dụng cảm biến DHT để đo nhiệt độ và độ ẩm, cách tạo và phân tích các tin nhắn JSON. Bạn cũng đã thử nghiệm chương trình của mình bằng Arduino IDE và WEB CLIENT. Hy vọng bài viết này sẽ giúp bạn có thêm kiến thức và kỹ năng để thực hiện các ứng dụng IOT với ESP8266 và MQTT. Chúc bạn thành công!