MQTT và ESP8266

MQTT là gì ? Cách sử dụng MQTT như thế nào ? Các ví dụ về MQTT với ESP8266 được thực hiện ra sao ? Trong bài viết này mình sẽ trình bày một số khái niệm và các bước thực hiện MQTT với ví dụ minh họa cơ bản trên ESP8266 cho mọi người cùng tham khảo.

Trước khi bắt đầu mình cùng xem qua một hình ảnh cơ bản về MQTT

Với hình ảnh trên thì ta có thể thấy MQTT Broker là một trạm trung chuyển, nói đơn giản dễ hiểu thì coi như nó là một trung tâm thông tin, có nhiệm vụ nhận thông tin từ rất nhiều các thiết bị khác nhau và chuyển các thông tin này tới từng thiết bị riêng biệt.

Sẽ có một câu hỏi được đặt ra là Broker MQTT này sẽ lấy ở đâu ra ? Chúng ta sẽ có 2 cách

  • Tự tạo Broker MQTT trên máy tính, raspberry, server,.. tùy vào điều kiện hiện có: cách này tốn kém thêm chi phí, phức tạp, không dành cho người mới bắt đầu.
  • Sử dụng các dịch vụ MQTT broker có sẵn: cách này dễ thở hơn chút, sử dụng cái sẵn có, thao tác cấu hình lấy thông tin để sử dụng, phù hợp với những người muốn thử nghiệm, tham khảo, tận dụng cái có sẵn. Trong bài viết này mình sẽ sử dụng cách này.

Để hiểu hơn một chút về cách thức hoạt động của MQTT Broker và ESP8266 ta sẽ đi vào ví dụ cụ thể

Chuẩn bị

Phần cứng

  • ESP8266 (NodeMCU)

Phần mềm

Cách kết nối nối cũng như dùng Arduino cho ESP8266 và các vấn đề liên quan các bạn tham khảo ở đây giúp mình nếu các bạn mới bắt đầu tìm hiểu.

Thực hiện

Sau khi chuẩn bị đầy đủ đồ nghề thì mình bắt tay vào thử chút thôi. Về cách làm mình sẽ dùng ESP8266 (NodeMCU) làm Client để kết nối lên một dịch vụ MQTT Broker là CloudMQTT với 2 nhiệm vụ chính, nhiệm vụ 1 là tham khảo từ Phan Tiến Sang, nhiệm vụ 2 là thay đổi 1 chút để điều khiển LED

  • Nhiệm vụ 1: Gửi (publish) dữ liệu lên broker, và nhận thông tin (subcribe) từ broker, mục đích chính là kiểm tra publish và subcribe giữa ESP8266 và MQTT Broker.
  • Nhiệm vụ 2: Nhận(subcribe) thông tin từ broker, kiểm tra dữ liệu và thực hiện bật tắt LED

 

Tạo tài khoản và cấu hình CloudMQTT

Bước 1: Bạn vào trực tiếp trang CloudMQTT để tạo một tài khoản cho mình, sẽ có một đường dẫn để kích hoạt thông tin và cấu hình cho tài khoản của bạn, trừ email và mật khẩu ra thì các ô còn lại các bạn nhập gì tùy thích.

Bước 2: Tạo MQTT Broker bằng cách ấn vào nút Create màu xanh, nhập các thông tin vào như hình.

Bước 3: Chọn Details để cấu hình thông tin

Trong manage User điền tên user là esp8266, password là 123456, sau đó Save

Trong New Rule chọn user như hình, tên topic đặt demo, tick chọn Read,Write

Vậy là xong bước cấu hình broker, kết quả, ta sẽ quan tâm tới 3 ô khoanh đỏ

Lập trình ESP8266

Kiểm tra chức năng subcribe và publish

Để ESP8266 có thể publish và subcribe dữ liệu lên MQTT broker thì cần phải có thư viện MQTT, ở đây mình dùng thư viện sẵn có là PubSubClient để thử nghiệm cho nhanh

Chương trình

Mình giải thích qua một chút về chương trình, chương trình này sẽ thực hiện kết nối với mạng wifi trước để có kết nối tới internet, sau đó thực hiện gửi thông tin lên broker bằng lệnh publish, sau đó lắng nghe thông tin có trên Broker(ở đây là thông tin do chính nó gửi lên) và in thông tin này ra terminal của Arduino thông qua hàm callback.

Kết quả

Log Arduino

Log Websocket UI

Bật tắt LED

Coi như đã giao tiếp thực hiện publish và subcribe trên MQTT Broker. Giờ thực hiện cải tiến thêm một chút, là từ giao diện Websocket  UI Send message xuống, ở dưới khi nhận được message thì ESP8266 thực hiện bật/tắt LED có sẵn trên kit.

Chương trình

Với chương trình này mình sẽ thay đổi và thực hiện kiểm tra gói tin từ Broker gửi về để điều khiển LED trong hàm callback

Kết quả

MQTT là gì ?

Một số ví dụ trên có thể cho chúng ta phần nào hình dung được về MQTT, tất nhiên nó vẫn dừng lại ở mức độ cơ bản, mình tiếp tục quay lại tìm hiểu một số khái niệm về MQTT, khái niệm này đã được anh Tuấn PM, người viết ra thư viện MQTT khá nổi tiếng trình bày tại đây, mình xin trích dẫn lại

MQTT (Message Queuing Telemetry Transport) là một giao thức gởi dạng publish/subscribe sử dụng cho các thiết bị Internet of Things với băng thông thấp, độ tin cậy cao và khả năng được sử dụng trong mạng lưới không ổn định. Bởi vì giao thức này sử dụng băng thông thấp trong môi trường có độ trễ cao nên nó là một giao thức lý tưởng cho các ứng dụng M2M. MQTT cũng là giao thức sử dụng trong Facebook Messager.

Các định nghĩa “subscribe”, “publish”, “qos”, “retain”, “last will and testament (lwt)” trong giao thức MQTT là gì ?

Publish, subscribe

Trong một hệ thống sử dụng giao thức MQTT, nhiều node trạm (gọi là mqtt client – gọi tắt là client) kết nối tới một MQTT server (gọi là broker). Mỗi client sẽ đăng ký một vài kênh (topic), ví dụ như “/client1/channel1”, “/client1/channel2”. Quá trình đăng ký này gọi là “subscribe”, giống như chúng ta đăng ký nhận tin trên một kênh Youtube vậy. Mỗi client sẽ nhận được dữ liệu khi bất kỳ trạm nào khác gởi dữ liệu và kênh đã đăng ký. Khi một client gởi dữ liệu tới kênh đó, gọi là “publish”.

QoS

Ở đây có 3 tuỳ chọn *QoS (Qualities of service) * khi “publish” và “subscribe”:

  • QoS0 Broker/client sẽ gởi dữ liệu đúng 1 lần, quá trình gởi được xác nhận bởi chỉ giao thức TCP/IP, giống kiểu đem con bỏ chợ.
  • QoS1 Broker/client sẽ gởi dữ liệu với ít nhất 1 lần xác nhận từ đầu kia, nghĩa là có thể có nhiều hơn 1 lần xác nhận đã nhận được dữ liệu.
  • QoS2 Broker/client đảm bảm khi gởi dữ liệu thì phía nhận chỉ nhận được đúng 1 lần, quá trình này phải trải qua 4 bước bắt tay.

Bạn có thể tham khảo thêm về QoS

Một gói tin có thể được gởi ở bất kỳ QoS nào, và các client cũng có thể subscribe với bất kỳ yêu cầu QoS nào. Có nghĩa là client sẽ lựa chọn QoS tối đa mà nó có để nhận tin. Ví dụ, nếu 1 gói dữ liệu được publish với QoS2, và client subscribe với QoS0, thì gói dữ liệu được nhận về client này sẽ được broker gởi với QoS0, và 1 client khác đăng ký cùng kênh này với QoS 2, thì nó sẽ được Broker gởi dữ liệu với QoS2.

Một ví dụ khác, nếu 1 client subscribe với QoS2 và gói dữ liệu gởi vào kênh đó publish với QoS0 thì client đó sẽ được Broker gởi dữ liệu với QoS0. QoS càng cao thì càng đáng tin cậy, đồng thời độ trễ và băng thông đòi hỏi cũng cao hơn.

Retain

Nếu RETAIN được set bằng 1, khi gói tin được publish từ Client, Broker PHẢI lưu trữ lại gói tin với QoS, và nó sẽ được gởi đến bất kỳ Client nào subscribe cùng kênh trong tương lai. Khi một Client kết nối tới Broker và subscribe, nó sẽ nhận được gói tin cuối cùng có RETAIN = 1 với bất kỳ topic nào mà nó đăng ký trùng. Tuy nhiên, nếu Broker nhận được gói tin mà có QoS = 0 và RETAIN = 1, nó sẽ huỷ tất cả các gói tin có RETAIN = 1 trước đó. Và phải lưu gói tin này lại, nhưng hoàn toàn có thể huỷ bất kỳ lúc nào.

Khi publish một gói dữ liệu đến Client, Broker phải se RETAIN = 1 nếu gói được gởi như là kết quả của việc subscribe mới của Client (giống như tin nhắn ACK báo subscribe thành công). RETAIN phải bằng 0 nếu không quan tâm tới kết quả của viẹc subscribe.

LWT

Gói tin LWT (last will and testament) không thực sự biết được Client có trực tuyến hay không, cái này do gói tin KeepAlive đảm nhận. Tuy nhiên gói tin LWT như là thông tin điều gì sẽ xảy đến sau khi thiết bị ngoại tuyến.

Ví dụ: Tôi có 1 cảm biến, nó gởi những dữ liệu quan trọng và rất không thường xuyên. Nó có đăng ký trước với Broker một tin nhắn lwt ở topic /node/gone-offline với tin nhắn id của nó. Và tôi cũng đăng ký theo dõi topic /node/gone-offline, sẽ gởi SMS tới điện thoại thôi mỗi khi nhận được tin nhắn nào ở kênh mà tôi theo dõi.
Trong quá trình hoạt động, cảm biến luôn giữ kết nối với Broker bởi việc luôn gởi gói tin keepAlive. Nhưng nếu vì lý do gì đó, cảm biến này chuyển sang ngoại tuyến, kết nối tới Broker timeout do Broker không còn nhận được gói keepAlive.
Lúc này, do cảm biến của tôi đã đăng ký LWT, do vậy broker sẽ đóng kết nối của Cảm biến, đồng thời sẽ publish một gói tin là Id của cảm biến vào kênh /node/gone-offline, dĩ nhiên là tôi cũng sẽ nhận được tin nhắn báo cái Cảm biến yêu quý của mình đã ngoại tuyến.

Tóm gọn: Ngoài việc đóng kết nối của Client đã ngoại tuyến, gói tin LWT có thể được định nghĩa trước và được gởi bởi Broker tới kênh nào đó khi thiết bị đăng ký LWT ngoại tuyến.

Tạm kết

Làm xong được vài ví dụ rồi quay lại phần lý thuyết thì lại càng cảm thấy khoai hơn phải không các bạn ? Ta có thể nhận thấy với thư viện PubsubClient thì chỉ thấy được pub, sub, mình cũng có kiểm tra xem có Qos, LWT không nhưng chưa thấy trong thư viện. Thư viện MQTT của anh Tuấn thì khá đầy đủ, nhưng hình như chưa có phiên bản cho arduino, nếu các bạn muốn có thể tham khảo để dùng nó lập trình cho ESP với nonos. Còn rất nhiều điều phải làm với MQTT nếu muốn tự làm hết mọi thứ các bạn có thể tham khảo cách tự build server MQTT và tạo giao diện điều khiển với nodered thông qua bài viết sau

 

14 thoughts on “MQTT và ESP8266

  1. ad cho mình hỏi mình muốn tự tạo 1 kịch bản riêng theo ý mình như thêm nút nhún, các biểu tượng hiển thị trạng thái có đc không , cảm ơn ạ

    1. đúng rồi, ở đây mình chỉ làm ví dụ với 1 LED, bạn cần nhiều led hơn thì bạn gửi gói tin khác thôi, ví dụ led1,led2,led3,.. tương ứng với từng cái thì bật/tắt led 1 2 3,..

  2. Bạn ơi! Mình không hiểu nhiều về lập trình lắm. Nếu bật, tắt nhiều Led hơn thì viết như thế nào? Cảm ơn bạn

  3. ad cho mình hỏi về trường hợp của mình! mình có 2 client là 2 con esp.8266, mình muốn truyền dữ liệu qua lại giữa 2 con này thì mình đã sub và pub cungf 1 topic rồi nhưng vẫn ko thể tự động nhận dữ liệu đc! chỉ có thể nhận khi minh thao tác thủ công trên máy tính thôi..ad có thể cho mình code mẫu đễ sub 1 topic đc ko?

Add Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.