Quynh Cute2021-10-07T18:09:27+07:00
INTERNET OF THINGS (IOT) : CHO NGƯỜI MỚI BẮT ĐẦU
Giao thức MQTT với ESP32 và Node-red: Người mới bắt đầu cần nắm bắt điều gì?
Giới thiệu nội dung :
MQTT (Message Queuing Telemetry Transport) là một giao thức truyền thông sử dụng cho các thiết bị IoT, giao thức này có độ tin cậy cao và khả năng được sử dụng trong các đường tuyền không ổn định bởi vì giao thức này chỉ sử dụng băng thông thấp trong môi trường có độ trễ cao nên nói là một giao thức lý tưởng cho các ứng dụng M2M và IoT.
MQTT cũng là giao thức sử dụng trong Facebook Messenger.
Bài viết này cung cấp các kiến thức cơ bản, đủ để người đọc hiểu về MQTT, xung quanh các yếu tố cốt lõi của giao thức này, bao gồm “subscribe“, “publish“, “qos“, “retain“, “last will and testament (lwt)“.
Publish, subcribe
Hệ thống MQTT bao gồm các node trạm ( MQTT client ) và một MQTT Server (gọi là Broker). Các client kết nối với Broker, mỗi client sẽ đăng ký một hoặc nhiều kênh (topic), ví dụ “/esp32/humidity” , “house/money ”. Khi một client đăng ký tới một topic, điều này gọi là subcribe, điều này tương tự như khi ta đăng ký một kênh Youtube
Lưu ý: . Nếu có nhiều client subcribe tới một topic, khi một client publish một dữ liệu lên topic thì tất cả các client subcribe tới topic đều sẽ nhận được thông báo về dữ liệu này.
QoS
QoS (Quality of service) là tùy chọn đường tuyền quyết định độ trễ và độ chính xác của thông tin khi “publish” và “subcribe”.
– QoS 0: Broker/Client sẽ gửi dữ liệu đúng 1 lần, thông qua giao thức TCP/IP, không cần xác nhận bởi điểm nhân, giống như người giao báo, chỉ cần đặt báo trước cửa chứ không cần quan tâm người nhận có nhận được hay không.
– QoS 1: Broker/Client sẽ gửi dữ liệu và cần ít nhất 1 lần xác nhận từ điểm nhận.
– QoS 2: Broker/Client sẽ gửi dữ liệu và cần đúng 1 lần xác nhận từ đầu kia, quá trình này phải trải qua 4 bước bắt tay.
Đọc thêm: Google Code Archive – Long-term storage for Google Code Project Hosting.
Một gói tin có thể được gởi ở bất kỳ QoS nào, các Client cũng có thể subcribe tới topic với bất kỳ QoS nào. Nếu một client subcribe tới 1 topic với QoS 2, thì QoS tối đa của các gói tin được gửi/nhận bởi client đó là QoS 2.
Retain
Nếu Retain = 1, khi Client publish 1 gói tin, Broker bắt buộc phải lưu trữ lại gói tin với QoS. Khi một Client kết nối tới Broker và subcribe một topic, nó sẽ nhận được gói tin cuối cùng có Retain = 1 của topic đó.
– Khi một Client subcribe tới một topic, Broker sẽ gửi một gói tin có Retain = 1 như là một xác nhận cho việc subcribe thanh công của Client.
LWT
Khi một Client subcribe tới một topic A và có đăng ký LWT tới 1 topic B một tin nhắn lwt. Trong trường hợp người dùng cũng đăng ký tới topic này, nếu vì một lý do gì đó, Client này rơi vào trạng thái ngoại tuyến, vì Client đã đăng kí LWT, người dùng sẽ nhận được một gói tin từ Broker là ID của Client ngoại tuyến trên topic B.
ESP32 MQTT Client
Ta đã biết 2 thành phần chinh của giao thức MQTT là Broker và Client, thông thường, vai trò của ESP32 trong giao thức MQTT là Client.
Thực hành
Trong ví dụ này, chúng ta sẽ tạo ra một kết nối MQTT giữa một Broker và một Client. Broker sẽ được tạo bằng Node-red và chạy trên máy tính, nội dung thự hành sẽ là điều khiển 1 led và gửi dữ liệu cảm biến lên Broker và visualize chúng bằng dashboard node-red.
– MQTT Broker được xây dựng bằng Node-red và chạy trên localhost.
– ESP32 đọc cảm biến DHT11/DHT22 và publish lên 2 topic “esp32/temperature” và “esp32/humidity” .
– ESP32 subcribe topic “esp32/out” để nhận tin nhắn về việc bật tắt LED trên GPIO 2.
– Node-red dashboard subcribe 2 topic “esp32/temperature” và “esp32/humidity”
Chuẩn bị
– Cảm biến DHT 11, điện trở 4k7.
– ESP32 và dây nạp
– Jump và breadboard.
– PC được cài đặt node-red và arduino
Sơ đồ kết nối
– Trong ví dụ này, chân tín hiệu của DHT được kết nối với GPIO 4
Chuẩn bị cho Arduino IDE
– Tất nhiên là bạn cần một phiên bản Arduino không quá cũ, nên là 1.8 trở lên được cài đặt ESP32, nếu bạn chưa biết cách cài đặt, hãy xem ở đây : https://espitek.com/arduino/cai-dat-esp32-cho-arduino-ide/
– Ngoài ra Arduino của bạn cần được cài đặt một số thư viện mà chúng tôi sẽ trình bày ở dưới đây.
PubSubClient
1. Thư viện này cho phép ESP32 tương tác với Broker MQTT node – red.
2. Tải file zip thư viện PubSubClient: https://github.com/knolleary/pubsubclient
3. Bạn cũng có thể cài đặt qua mục quản lý thư viện của Arduino IDE.
Thư viện cho cảm biến DHT
– Phần này gồm 2 thư viện DHT sensor library & Adafruit Unified Sensor
Code
ESP32 Arduino:
#include <WiFi.h>
#include <PubSubClient.th>
#include <string.h>
#include <DHT.h>// Replace with your network credentials
const char* ssid = “REPLACE_WITH_YOUR_SSID”;
const char* password = “REPLACE_WITH_YOUR_PASSWORD”;// Add your MQTT Broker IP address, example:
//const char* mqtt_server = “192.168.1.144”;
const char* mqtt_server = “YOUR_MQTT_BROKER_IP_ADDRESS”;// Digital pin connected to the DHT sensor
#define DHTPIN 4// Uncomment whatever DHT sensor type you’re using
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);void setup(){
Serial.begin(115200);
dht.begin();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(ledPin, OUTPUT);
}void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println(“IP address: “);
Serial.println(WiFi.localIP());
}void callback(char* topic, byte* message, unsigned int length) {
Serial.print(“Message arrived on topic: “);
Serial.print(topic);
Serial.print(“. Message: “);
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp32/output, you check if the message is either “on” or “off”.
// Changes the output state according to the message
if (String(topic) == “esp32/output”) {
Serial.print(“Changing output to “);
if(messageTemp == “on”){
Serial.println(“on”);
digitalWrite(ledPin, HIGH);
}
else if(messageTemp == “off”){
Serial.println(“off”);
digitalWrite(ledPin, LOW);
}
}
}void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
// Attempt to connect
if (client.connect(“ESP32Client”)) {
Serial.println(“connected”);
// Subscribe
client.subscribe(“esp32/output”);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(” try again in 5 seconds”);
// Wait 5 seconds before retrying
delay(5000);
}
}
}void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();long now = millis();
if (now – lastMsg > 5000) {
lastMsg = now;//Get tempatature and humidity
// New DHT sensor readings
humidity = dht.readHumidity();
// Read temperature as Celsius (the default)
temperature = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//temp = dht.readTemperature(true);// Check if any reads failed and exit early (to try again).
if (isnan(temp) || isnan(hum)) {
Serial.println(F(“Failed to read from DHT sensor!”));
return;
}
// Convert the value to a char array
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print(“Temperature: “);
Serial.println(tempString);
client.publish(“esp32/temperature”, tempString);
// Convert the value to a char array
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print(“Humidity: “);
Serial.println(humString);
client.publish(“esp32/humidity”, humString);
}
}
// converts character array
// to string and returns it
String convertToString(char* a, int size)
{
int i;
String s = “”;
for (i = 0; i < size; i++) {
s = s + a[i];
}
return s;
}
NODE RED
Chuẩn bị
– Cài đặt node-red trên PC : http://www.brainboxes.com/faq/items/installing-and-running-node-red-on-a-windows-pc
– Hiểu một vài nodes cơ bản trên node-red:
Code node-red: truy cập 127.0.0.1:1880
KẾT QUẢ
Kết quả: Nhiệt độ và độ ẩm được hiển thị
lên dashboard, bạn có thể nhấn nút Output
để điều khiển LED trên board phát triển, LED
này đã được hàn sẵn với GPIO số 2.
UI: 127.0.0.1:1880/ui