網頁

2022年8月13日 星期六

ESP32 - 使用 BlocklyDuino-物聯網MQTT的應用

 主題

設計一個專案,可以遠端遙控家裏的LED 燈和 讀取家裏的溫度、濕度。

MQTT的介紹

MQTT(Message Queuing Telemetry Transport)是基於發布 (Publish)/訂閱 (Subscribe)範式的訊息協定,需要1個 Broker(代理者),負責「資料傳遞的橋梁」。
MQTT 最主要應用在物聯網(IoT,Internet of Things) 的訊息交換。

4個主要的元素:
Publisher(發佈者)
Subscriber(訂閱者) 
Topic(主題)
Broker(代理者,轉訊站 )

Client(客戶端)可同時扮演 Publisher和 Subscriber的角色。

Topic(主題)是使用 UTF-8(萬國碼)編碼的字串,可使用中英文,亦可由多個 '/' 分開,建議Topic中不要包含空格字元。
如果代理者接收到某個主題的訊息,但這個主題沒有任何訂閱者,這個主題就會被丟棄,除非發布者將其標記為保留訊息(Retained message)。
MQTT 預設埠為 1883。加密(使用 SSL/TLS)的埠為 8883。
Keep alive(保活) 最大保活間隔:18小時12分鐘15秒。客戶在保活間隔乘以1.5倍的時間內可以不與broker通信。

MQTT QoS(Quality of Service)級別

QoS 代表Publisher與Broker、Broker與Subscriber之間傳輸品質,有3個層級。
  • QoS 0 :最多傳送一次(at most once),不會回傳確認封包。
  • QoS 1 :至少傳送一次(at least once),Publisher 沒收到確認訊息,會再傳送,訂閱者可能收到重複的訊息。
  • QoS 2 :確實傳送一次(exactly once),不會重覆傳送相同訊息。
等級愈高,佔用頻寬與傳送時間就愈多
QoS 詳細資料,請參考 https://ithelp.ithome.com.tw/articles/10224407

Broker

broker.hivemq.com : TCP Port:1883,WebsocketPort:8000。
網頁網址: http://www.hivemq.com/demos/websocket-client/
mqttgo.io:TCP Port:1883,WebsocketPort:8000。網頁網址: http://mqttgo.io/
test.mosquitto.org:TCP Port:1883 / 8883(TLS,加密)

使用的電子元件

本主題使用「 DHT-11溫濕度感測器」電子元件 。
有關「 DHT-11溫濕度感測器」,請看我的另一篇文章「ESP32 - 使用 BlocklyDuino-溫濕度感測器」。

接線方式

「 DHT-11溫濕度感測器」接到 Pin 16。
紅色 led 燈接到 Pin 2,如果可以連線到 MQTT   Server,燈就亮,否則燈滅。
黃色 led 燈接到 Pin 5。綠色 led 燈接到 Pin 17。黃色 led 燈和 綠色 led 燈 ,皆由遠端來遙控亮不亮。


以網頁(WebSocket-Client)的方式使用MQTT   Server 

以 HiveMQ 為例,使用瀏覽器,連到 HiveMQ網頁工具,網址:http://www.hivemq.com/demos/websocket-client/
按 「Connect」。這是讓 普通的網頁瀏覽器成為基於WebSocket的MQTT client。
Topic(主題),可用中英文,如「led燈」。主題名稱儘量是 獨1無2的名稱,我輸入「my666/home/light」,表示要控制家裏的led燈。
如果在下面 Message 欄位輸入 「yon」,按 「Publish」(發布),表示送「yon」給 「my666/home/light」此主題。當 家裏的 ESP32 接收到主題 「my666/home/light」的訊息內容為 yon ,就打開黃色led 燈。如果收到 主題 「my666/home/light」的訊息內容為 yoff,就關掉黃色led 燈。依此類推,gon,打開綠色led 燈。goff,關掉綠色led 燈。

在網頁按「Publish」,下面的Messages 沒有反應,因為 Messages此欄位是用來接收 Subscrib(訂閱)的內容,但是我們尚未訂閱任何東西。
按右邊的 「Add New Topic Subscription」,增加訂閱的主題。

輸入新主題的名稱 ,如 「my666/home/溫度」,按「Subscribe」,完成新增的動作。
再新增1個主題,如 「my666/home/濕度」。Color 可以改,Qos 有3個可選(0,1,2)。
結果訂閱2個主題如下:


程式











程式說明

從「變數」類別,拿出「宣告 全域  整數  i」block。

整數 改為 浮點數(因溫度、濕度有小數),重新命名變數...

輸入 temperature,按「確定」。

選「宣告 全域  」此block,按右鍵,選「複製」。

按「建立變數」。

輸入 「humidity」。

從「Wi-Fi」類別 ,取出「連線到 Wi-Fi AP」。


Wi-Fi  ID 即 Wi-Fi 的 SSID, Wi-Fi無線基地台的名稱。
從「吉哥積木/物聯網/MQTT」類別 ,取出「連線到MQTT」block。

輸入伺服器 : broker.hivemq.com,連接埠:1883。
從「吉哥積木/物聯網/MQTT」類別 ,取出「訂閱 Topic」block。
輸入要訂閱的主題名稱 :my666/home/light。
從「邏輯」類別 ,取出「如果 執行」block。

「如果」原本祇有1個條件,按 「*」,可以增加條件,移進來是增加,移出去是減少。再按一次「*」關掉小視窗。

從「吉哥積木/物聯網/MQTT」類別 ,取出「當收到到MQTT訊息時」block。
在「序列埠 I/O」類別,拿出「序列埠印出(換行)」block。
從「吉哥積木/物聯網/MQTT」類別 ,取出「接收到的訊息」block。
將「接收到的訊息」從「序列埠印出(換行)」印出,這是偵錯用,看是否能接收到訊息。
如果 「接收到的訊息」是 "yon" 執行 「數位寫入 Pin 5 狀態 高電位」,表示打開黃燈。
否則 如果 「接收到的訊息」是 "yoff"  執行 「數位寫入 Pin 5 狀態 低電位」表示關閉黃燈。
其它依此類推。

在「重複執行」 block內。
從「字串」類別,取出 「字串組合」。
「字串組合」原本祇有2個項目,按 「*」,可以增加或減少項目。再按一次「*」關掉小視窗。


從「感測模組/環境感測」類別,取出 「溫濕度計 DHT11 Pin 0 量測數值 相對濕度」block,將Pin 0 改成 Pin 16,相對濕度 改成 溫度。

把上一次的溫度( temperature 變數)和現在取得的溫度(「溫濕度計 DHT11 Pin 16 量測數值  溫度」相比,如果不相等(從「邏輯」類別,取出 =  block,將 = 改成 ≠ )
 就 「發佈訊息  TOPIC 名稱 "my666/home/溫度" 訊息 字串組合  溫濕度計 DHT11 Pin 16 量測數值  溫度」。將取得的溫度 發佈 到 MQTT Server,主題名稱為  "my666/home/溫度" ,內容為取得的溫度。

因為 發佈訊息的訊息要接字串,而 取得的溫度值是數值,二者不能接起來。所以 使用「字串組合」, 把取得的溫度 轉換成 字串。
「字串組合」原本祇有2個項目,按 「*」,移1個項目往外,祇剩下1個項目 在 「加入 」內。


執行結果

在 hivemq網站 (http://www.hivemq.com/demos/websocket-client/),Message 欄位,輸入 yon,按「Publish」。

結果,打開黃燈。

Message 欄位,輸入 gon,按「Publish」。

結果,打開綠燈。

Message 欄位,輸入 yoff,按「Publish」。

結果,關掉黃燈。

Message 欄位,輸入 goff,按「Publish」,結果,關掉綠燈。

從 「 DHT-11溫濕度感測器」取得的溫度 放在 「my666/home/溫度」此主題,從 「 DHT-11溫濕度感測器」取得的濕度 放在 「my666/home/濕度」。
在 Messages 欄位 顯示 這2個主題的內容,即 溫度和濕度。
因為程式有檢查目前取得的溫度和濕度,如果跟上次不一樣,才 Pulish 出去。所以祇有跟上次不一樣的數值,才顯示在網頁中。

程式改良

  • 當連線時,紅色 led 燈就一直亮著,可以改成:沒連線才亮紅燈。
  • 有2個 led 燈要控制,但祇用一個主題「my666/home/light」,會造成後送的訊息,覆蓋掉前面的訊息。應該使用2個主題,1個控制黃燈,1個控制綠燈。
  • 當溫度和濕度有變時,才發佈資料到Server。所以當手機連線時,可能沒有溫度和濕度顯示,直到 溫度和濕度有變化時,才看到溫度和濕度的數值。
  • 用網頁來遙控,對使用者不方便,可以寫成一個App,改用手機控制,如下:
修改後的程式