[IoT] Bài 7: ESP8266 - Arduino Ide Và Giao Thức MQTT
Giao thức MQTT phù hợp nhất cho các dự án IoT thương mại, nó dáp ứng tốc độ tốt, băng thông ít, độ tin cậy cao. Tài liệu về giao thức MQTT thì các bạn tham khảo ở các trên mạng hoặc 1 số bài sau :
- https://smartfactoryvn.com/technology/internet-of-things/giao-thuc-mqtt-la-gi-nhung-ung-dung-cua-mqtt-nhu-the-nao/
- https://esp8266.vn/nonos-sdk/mqtt/what-is-mqtt/
Mình sẽ không nhắc lại phần lí thuyết nữa vì trên mạng có rất nhiều rồi. Chúng ta sẽ đi vào thực hành làm thử 1 project với giao thức MQTT luôn
Đầu tiên, phía esp8266 các bạn tải thư viện Pubsubclient
Giao thức MQTT cần có 1 server ( gọi là broker) để làm trung tâm của mọi luồng dữ liệu, trong các bài viết sau mình sẽ hướng dẫn các bạn tự build server, còn trong bài này mình sẽ sử dụng server miễn phí không bảo mật là broker.hivemq.com để demo
Các bạn copy chương trình cho esp8266
C #include <ESP8266WiFi.h> #include <PubSubClient.h> // Thông tin về wifi #define ssid "dieukhien" #define password "12345678" #define mqtt_server "broker.hivemq.com" const uint16_t mqtt_port = 1883; //Port của CloudMQTT TCP WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); } // Hàm kết nối wifi 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("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } // Hàm call back để nhận dữ liệu void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Co tin nhan moi tu topic:"); Serial.println(topic); for (int i = 0; i < length; i++) Serial.print((char)payload[i]); Serial.println(); } // Hàm reconnect thực hiện kết nối lại khi mất kết nối với MQTT Broker void reconnect() { while (!client.connected()) // Chờ tới khi kết nối { // Thực hiện kết nối với mqtt user và pass if (client.connect("ESP8266_id1","ESP_offline",0,0,"ESP8266_id1_offline")) //kết nối vào broker { Serial.println("Đã kết nối:"); client.subscribe("IoT47_MQTT_Test"); //đăng kí nhận dữ liệu từ topic IoT47_MQTT_Test } else { Serial.print("Lỗi:, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Đợi 5s delay(5000); } } } unsigned long t; void loop() { if (!client.connected())// Kiểm tra kết nối reconnect(); client.loop(); if(millis() - t > 500) //nếu 500 mili giây trôi qua { t=millis(); Serial.print("Gui tin nhan \"Xin chao\" vao topic IoT47_MQTT_Test"); client.publish("IoT47_MQTT_Test", "Xin chao !"); // gửi dữ liệu lên topic IoT47_MQTT_Test } }1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | #include <ESP8266WiFi.h>#include <PubSubClient.h> // Thông tin về wifi#define ssid "dieukhien"#define password "12345678"#define mqtt_server "broker.hivemq.com"constuint16_t mqtt_port=1883;//Port của CloudMQTT TCP WiFiClient espClient;PubSubClient client(espClient); voidsetup(){Serial.begin(115200);setup_wifi();client.setServer(mqtt_server,mqtt_port);client.setCallback(callback);}// Hàm kết nối wifivoidsetup_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(".");}Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());}// Hàm call back để nhận dữ liệuvoidcallback(char*topic,byte*payload,unsignedintlength){Serial.print("Co tin nhan moi tu topic:");Serial.println(topic);for(inti=0;i<length;i++)Serial.print((char)payload[i]);Serial.println();}// Hàm reconnect thực hiện kết nối lại khi mất kết nối với MQTT Brokervoidreconnect(){while(!client.connected())// Chờ tới khi kết nối{// Thực hiện kết nối với mqtt user và passif(client.connect("ESP8266_id1","ESP_offline",0,0,"ESP8266_id1_offline"))//kết nối vào broker{Serial.println("Đã kết nối:");client.subscribe("IoT47_MQTT_Test");//đăng kí nhận dữ liệu từ topic IoT47_MQTT_Test}else{Serial.print("Lỗi:, rc=");Serial.print(client.state());Serial.println(" try again in 5 seconds");// Đợi 5sdelay(5000);}}}unsignedlongt;voidloop(){if(!client.connected())// Kiểm tra kết nốireconnect();client.loop();if(millis()-t>500)//nếu 500 mili giây trôi qua{t=millis();Serial.print("Gui tin nhan \"Xin chao\" vao topic IoT47_MQTT_Test");client.publish("IoT47_MQTT_Test","Xin chao !");// gửi dữ liệu lên topic IoT47_MQTT_Test}} |
- Ở dòng 5 và 6 các bạn đổi thành wifi của mình.
- Hàm callback là hàm gọi lại khi có dữ liệu gửi đến topic mà chúng ta đăng kí
- Hàm client.subscribe dùng để đăng kí 1 topic
- Hàm client.publish dùng để gửi dữ liệu lên 1 topic
- Hàm client.connect để kết nối vào MQTT Broker, với các tham sốESP8266_id1 : Id của thiết bị đăng kí vào (có thể chỉnh sửa bất thành bất kì)ESP_offline : khi thiết bị (esp8266) mất mạng (offline) thì broker sẽ xuất bản1 tin nhắn vào topic nàyESP8266_offline : Nội dung của tin nhắn offline
Sau khi kết nối thành công ở dòng 53 mình đăng kí topic IoT47_MQTT_Test và trong hàm loop xuất bản tin nhắn “Xin chao” vào chính topic IoT47_MQTT_Test .Như vậy chúng ta sẽ nhận lại được chính tin nhắn mà ta đã xuất bản !
Kết quả: Mình đã nhận được chính tin nhắn mà mình xuất bản lên
Thiết kế giao diện web gửi tin nhắn cho ESP8266
Để có thể kết nối tới MQTT broker, mình sẽ sử dụng ngôn ngữ JavaScript và thư viện PahoMQTT
Các bạn tạo 1 file tên là index.html và thêm mã code web
C <!DOCTYPE html> <html> <head> <title>Demo MQTT</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script> <script type = "text/javascript" language = "javascript"> var max,at_OK; function makeid() { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < 5; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; } // Create a client instance var client = new Paho.MQTT.Client("broker.hivemq.com", 8000, makeid()); // set callback handlers client.onConnectionLost = onConnectionLost; client.onMessageArrived = onMessageArrived; var options = { useSSL: false, userName: "", password: "", onSuccess:onConnect, onFailure:doFail } console.log("Connect to broker.hivemq.com:8000"); // connect the client client.connect(options); function doFail(e){ console.log(e); } function onConnect() //sự kiên kết nối thành công { console.log("Connect OK"); client.subscribe("IoT47_MQTT_Test"); //đăng kí kênh } // called when the client loses its connection function onConnectionLost(responseObject) { if (responseObject.errorCode !== 0) { console.log(responseObject.errorMessage); } } // called when a message arrives function onMessageArrived(message) { console.log(message.destinationName + ":" +message.payloadString); } function public (topic,data) { message = new Paho.MQTT.Message(data); message.destinationName = topic; client.send(message); } </script> </head> <body> </body> </html>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 | <!DOCTYPE html><html><head><title>Demo MQTT</title><meta name="viewport"content="width=device-width, initial-scale=1"><meta charset="utf-8"><script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js"type="text/javascript"></script><script type="text/javascript"language="javascript">varmax,at_OK;functionmakeid(){vartext="";varpossible="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for(vari=0;i<5;i++)text+=possible.charAt(Math.floor(Math.random()*possible.length)); returntext;}// Create a client instancevarclient=newPaho.MQTT.Client("broker.hivemq.com",8000,makeid()); // set callback handlersclient.onConnectionLost=onConnectionLost;client.onMessageArrived=onMessageArrived; varoptions={useSSL:false,userName:"",password:"",onSuccess:onConnect,onFailure:doFail} console.log("Connect to broker.hivemq.com:8000");// connect the clientclient.connect(options); functiondoFail(e){console.log(e);} functiononConnect()//sự kiên kết nối thành công{console.log("Connect OK");client.subscribe("IoT47_MQTT_Test");//đăng kí kênh } // called when the client loses its connectionfunctiononConnectionLost(responseObject){if(responseObject.errorCode!==0){console.log(responseObject.errorMessage);}} // called when a message arrivesfunctiononMessageArrived(message){console.log(message.destinationName+":"+message.payloadString);}functionpublic(topic,data){message=newPaho.MQTT.Message(data);message.destinationName=topic;client.send(message);}</script></head><body> </body></html> |
- Hàm makeID có nhiệm vụ tạo ra 1 id ngẫu nhiên để web kết nối tới MQTT broker tránh bị trùng id
- Mình sẽ kết nối vào broker.hivemq.com qua cổng 8000 vì cổng 8000 là cổng dành cho các kết nối thông qua Socket, trong khi cổng 1883 dành cho các kết nối qua TCP
- Hàm public dùng để xuất bản 1 tín nhắn tới 1 topic nào dó
- Hàm client.subscribe dùng để đăng kí nhận tin nhắn từ 1 topic nào đó
- Hàm onMessageArrived là hàm callback khi có 1 tin nhắn từ 1 topic đã đăng kí gửi tới
Mình sẻ lưu lại và mở file này bằng trình duyệt, sau đó ấn F12 để xem dữ liệu debug in ra màn hình console
Các bạn có thể thấy sau khi thông báo Connect OK thì chúng ta đã nhận được tin nhắn “Xin chao !” mà esp8266 liên tục gửi lên mỗi 500 mili giây
Cũng trong màn hình debug, mình gõ hàm public để gửi thử dữ liệu đến esp8266 nhé !
Thiết kế giao diện nút nhấn điều khiển thiết bị cho giao thức mqtt
Chúng ta sẽ tận dùng lại giao diện dã xài ở bài 5 nhé
C <!DOCTYPE html> <html> <head> <title>Demo MQTT</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script> <script type = "text/javascript" language = "javascript"> var max,at_OK; function makeid() { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < 5; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; } // Create a client instance var client = new Paho.MQTT.Client("broker.hivemq.com", 8000, makeid()); // set callback handlers client.onConnectionLost = onConnectionLost; client.onMessageArrived = onMessageArrived; var options = { useSSL: false, userName: "", password: "", onSuccess:onConnect, onFailure:doFail } console.log("Connect to broker.hivemq.com:8000"); // connect the client client.connect(options); function doFail(e){ console.log(e); } function onConnect() //sự kiên kết nối thành công { console.log("Connect OK"); client.subscribe("ESP8266_sent_data"); //đăng kí kênh } // called when the client loses its connection function onConnectionLost(responseObject) { if (responseObject.errorCode !== 0) { console.log(responseObject.errorMessage); } } // called when a message arrives function onMessageArrived(message) { console.log(message.destinationName + ":" +message.payloadString); document.getElementById("tinnhan").innerHTML = "Tin nhắn từ esp8266: " + message.payloadString; } function public (topic,data) { message = new Paho.MQTT.Message(data); message.destinationName = topic; client.send(message); } </script> <style> .b{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#4caf50;border-radius: 10px;} .t{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#f44336;border-radius: 10px;} </style> </head> <body> <div style="width: 330px;height: auto;margin: 0 auto;margin-top: 70px"> <h1 align="center">Điều khiển thiết bị qua WIFI - MQTT</h1> <p align="center" id="tinnhan">Tin nhắn từ esp8266: ... </p> <table align="center"> <tr> <td><button class='b' onclick="public('ESP8266_read_data','Bật 1')">Bật 1</button><td> <td><button class='t' onclick="public('ESP8266_read_data','Tắt 1')">Tắt 1</button><td> <tr> <tr> <td><button class='b' onclick="public('ESP8266_read_data','Bật 2')">Bật 2</button><td> <td><button class='t' onclick="public('ESP8266_read_data','Tắt 2')">Tắt 2</button><td> <tr> <tr> <td><button class='b' onclick="public('ESP8266_read_data','Bật 3')">Bật 3</button><td> <td><button class='t' onclick="public('ESP8266_read_data','Tắt 3')">Tắt 3</button><td> <tr> <tr> <td><button class='b' onclick="public('ESP8266_read_data','Bật 4')">Bật 4</button><td> <td><button class='t' onclick="public('ESP8266_read_data','Tắt 4')">Tắt 4</button><td> <tr> </table> </div> </body> </html>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | <!DOCTYPE html><html><head><title>Demo MQTT</title><meta name="viewport"content="width=device-width, initial-scale=1"><meta charset="utf-8"><script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js"type="text/javascript"></script><script type="text/javascript"language="javascript">varmax,at_OK;functionmakeid(){vartext="";varpossible="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for(vari=0;i<5;i++)text+=possible.charAt(Math.floor(Math.random()*possible.length)); returntext;}// Create a client instancevarclient=newPaho.MQTT.Client("broker.hivemq.com",8000,makeid()); // set callback handlersclient.onConnectionLost=onConnectionLost;client.onMessageArrived=onMessageArrived; varoptions={useSSL:false,userName:"",password:"",onSuccess:onConnect,onFailure:doFail} console.log("Connect to broker.hivemq.com:8000");// connect the clientclient.connect(options); functiondoFail(e){console.log(e);} functiononConnect()//sự kiên kết nối thành công{console.log("Connect OK");client.subscribe("ESP8266_sent_data");//đăng kí kênh } // called when the client loses its connectionfunctiononConnectionLost(responseObject){if(responseObject.errorCode!==0){console.log(responseObject.errorMessage);}} // called when a message arrivesfunctiononMessageArrived(message){console.log(message.destinationName+":"+message.payloadString);document.getElementById("tinnhan").innerHTML="Tin nhắn từ esp8266: "+message.payloadString; }functionpublic(topic,data){message=newPaho.MQTT.Message(data);message.destinationName=topic;client.send(message);}</script><style>.b{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#4caf50;border-radius:10px;}.t{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#f44336;border-radius:10px;}</style></head><body><div style="width: 330px;height: auto;margin: 0 auto;margin-top: 70px"><h1 align="center">Điềukhiểnthiếtbịqua WIFI-MQTT</h1><palign="center"id="tinnhan">Tin nhắntừesp8266:...</p><table align="center"><tr><td><button class='b'onclick="public('ESP8266_read_data','Bật 1')">Bật1</button><td><td><button class='t'onclick="public('ESP8266_read_data','Tắt 1')">Tắt1</button><td><tr><tr><td><button class='b'onclick="public('ESP8266_read_data','Bật 2')">Bật2</button><td><td><button class='t'onclick="public('ESP8266_read_data','Tắt 2')">Tắt2</button><td><tr><tr><td><button class='b'onclick="public('ESP8266_read_data','Bật 3')">Bật3</button><td><td><button class='t'onclick="public('ESP8266_read_data','Tắt 3')">Tắt3</button><td><tr><tr><td><button class='b'onclick="public('ESP8266_read_data','Bật 4')">Bật4</button><td><td><button class='t'onclick="public('ESP8266_read_data','Tắt 4')">Tắt4</button><td><tr></table></div></body></html> |
Tin nhắn từ esp8266: ...
Bật 1 | Tắt 1 | ||
Bật 2 | Tắt 2 | ||
Bật 3 | Tắt 3 | ||
Bật 4 | Tắt 4 | ||
Khi ấn nút ( sự kiện OnClick) mình sẽ cho xuất bản tin nhắn tương ứng tới ESP8266 qua topic ESP8266_read_data. Do vậy ở code esp8266 mình sẽ sửa lại code cho nó đăng kí vào topic ESP8266_read_data và cho web đăng kí vào kênh ESP8266_sent_data để nhận tin nhắn esp8266 gửi lên
Mình cũng thêm đoạn mã đọc data tử cổng Serial để gửi lên cho web
Full code cho esp8266
C #include <ESP8266WiFi.h> #include <PubSubClient.h> // Thông tin về wifi #define ssid "dieukhien" #define password "12345678" #define mqtt_server "broker.hivemq.com" const uint16_t mqtt_port = 1883; //Port của CloudMQTT TCP WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); } // Hàm kết nối wifi 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("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } // Hàm call back để nhận dữ liệu void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Co tin nhan moi tu topic:"); Serial.println(topic); for (int i = 0; i < length; i++) Serial.print((char)payload[i]); Serial.println(); } // Hàm reconnect thực hiện kết nối lại khi mất kết nối với MQTT Broker void reconnect() { while (!client.connected()) // Chờ tới khi kết nối { // Thực hiện kết nối với mqtt user và pass if (client.connect("ESP8266_id1","ESP_offline",0,0,"ESP8266_id1_offline")) //kết nối vào broker { Serial.println("Đã kết nối:"); client.subscribe("ESP8266_read_data"); //đăng kí nhận dữ liệu từ topic ESP8266_read_data } else { Serial.print("Lỗi:, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Đợi 5s delay(5000); } } } void loop() { if (!client.connected())// Kiểm tra kết nối reconnect(); client.loop(); if(Serial.available() > 0) { delay(30); char inputString[30]=""; int i=0; while(Serial.available() > 0) { char inChar = (char)Serial.read(); inputString[i++] = inChar; } client.publish("ESP8266_sent_data", inputString); // gửi dữ liệu lên topic ESP8266_sent_data } }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 | #include <ESP8266WiFi.h>#include <PubSubClient.h> // Thông tin về wifi#define ssid "dieukhien"#define password "12345678"#define mqtt_server "broker.hivemq.com"constuint16_t mqtt_port=1883;//Port của CloudMQTT TCP WiFiClient espClient;PubSubClient client(espClient); voidsetup(){Serial.begin(115200);setup_wifi();client.setServer(mqtt_server,mqtt_port);client.setCallback(callback);}// Hàm kết nối wifivoidsetup_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(".");}Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());}// Hàm call back để nhận dữ liệuvoidcallback(char*topic,byte*payload,unsignedintlength){Serial.print("Co tin nhan moi tu topic:");Serial.println(topic);for(inti=0;i<length;i++)Serial.print((char)payload[i]);Serial.println();}// Hàm reconnect thực hiện kết nối lại khi mất kết nối với MQTT Brokervoidreconnect(){while(!client.connected())// Chờ tới khi kết nối{// Thực hiện kết nối với mqtt user và passif(client.connect("ESP8266_id1","ESP_offline",0,0,"ESP8266_id1_offline"))//kết nối vào broker{Serial.println("Đã kết nối:");client.subscribe("ESP8266_read_data");//đăng kí nhận dữ liệu từ topic ESP8266_read_data}else{Serial.print("Lỗi:, rc=");Serial.print(client.state());Serial.println(" try again in 5 seconds");// Đợi 5sdelay(5000);}}}voidloop(){if(!client.connected())// Kiểm tra kết nốireconnect();client.loop();if(Serial.available()>0){delay(30);charinputString[30]="";inti=0;while(Serial.available()>0){charinChar=(char)Serial.read();inputString[i++]=inChar;}client.publish("ESP8266_sent_data",inputString);// gửi dữ liệu lên topic ESP8266_sent_data}} |
Related posts:
[IOT FULL STACK] Bài 1: Giới thiệu chip esp8266, điều khiển đèn led bật tắt[ENC28J60] Bài 14: Giao thức HTTP - Tạo Webserver với ENC28J60[ENC28J60] Bài 21: LWIP - Giao thức TCP với raw apiBảo mật chương trình cho esp8266Từ khóa » Mqtt Với Esp8266
-
MQTT Và ESP8266 | Học ARM
-
ESP8266 – MQTT - Unicloud Blogs
-
ESP8266 Phần 3: MQTT Và Esp8266 - STKT Blog
-
Node-red MQTT Và ESP8266 - Duy Đặng - Robot And Technology
-
Thiết Kế Hệ Thống IoT đơn Giản Dùng Giao Thức MQTT Kết Hợp PHP ...
-
ESP8266 Và Giao Thức MQTT Cơ Bản | MCA - MicroController Academy
-
KẾT NỐI VỚI MQTT SỬ DỤNG ESP8266/ESP32 - P1 - YouTube
-
ESP8266 Connects To MQTT Broker With Arduino - EMQ
-
Connect ESP8266 + Local MQTT On Window Using Mosquitto #2
-
Giao Tiếp ESP32 Với ESP8266 Qua Giao Thức MQTT | HTT Offical
-
Vấn đề Về MQTT Và ESP8266 - Programming - Dạy Nhau Học
-
Thiminhnhut/esp8266-cloud-mqtt - GitHub