當各類感測器或裝置都能夠連網時,如何將這些資料進行分析或整合,就變成一個關鍵的環節,所謂雲端 IoT 資料庫因此存在。ThingSpeak 是很多人會使用的雲端服務平台,藉由這類的雲端資料庫,我們可以將感測原始資料上傳並儲存,再搭配應用演算法進行後端控制,今天這篇就來講一下如何使用 ThingSpeak MQTT 協定, 將 DHT11 的感測資料發佈並即時監看 。
Tips: 如果要透過 MQTT 上傳資料到雲端平台,可以先在自行架設的 Mosquitto Broker 主機測試,需要的朋友參考這篇:https://jimirobot.tw/esp32-micropython-mqtt-publish-tutorial-303/
1. 申請 ThingSpeak 帳號
ThingSpeak 現在為 Mathworks 旗下的產品線之一,所以如果你有 Matlab 帳號就可以直接使用 Free 的授權(不過我想離開學校後應該就比較少用了吧!🙄),關於免費授權的限制(https://thingspeak.com/pages/license_faq),大家可以留意一下:
- 用在非商業用途的 Project 沒有時間限制
- 每一年可以傳300萬的訊息,一天約8200個訊息
- 限制在 4 個 Channel
- 每一次更新訊息的間隔必須要15秒以上
- 同時 MQTT 訂閱數量只能有3個
以一般需求的Project來說,應該是可以滿足上述的條件,這邊先來示範一下怎麼申請帳號:
🔽 先到ThingSpeak 平台的官網,按下『Get Started for Free』
🔽 Create One,建立一個 MathWorks 的新帳號。
🔽 填入 Email 與相關內容,按下Continue。(現在不接受 google 的 email 了)
🔽 按下 Continue 後,會將確認連結寄到你填寫的 Email 。
🔽 找到確認信後,按下連結,便會出現下面的verified畫面。
🔽 開始填入你的密碼,並同時相關Service Agreement。
🔽 完成後,即可使用申請的帳號登入。
2. 在 ThingSpeak 新增 Channel 與 Field
ThinkSpeak的『Channel』 就類似一個 topic 主題一樣,Field 就是欄位,每個Channel 最多可以配到8個欄位,以這次的實驗為為例,房間狀態就是一個channel,DHT11所提供的溫度與濕度值分別代表兩個欄位,建立步驟如下:
🔽 登入後,點擊上方的『Channels』,並按下『New Channel』。
🔽 在 New Channel 視窗內,依序填上 Channel、Description、Field1、 Field2的內容。
🔽 滑鼠往下,其他欄位可以先不用填,按下『Save Channel』,完成 Channel 的設定。
3. 訊息上傳前的準備工作
在準備程式撰寫前,有三個 ThingSpeak 的參數要先記錄下來:ChannelID、WriteAPIKey、MQTTKey,可以分別在下面畫面找到:
🔽點擊剛剛新增的 Channel的 API Key 標籤頁,紀錄 Channel ID 跟 WriteAPI Key。
🔽我們此次會使用 MQTT 協定登入ThingSpeak,所以還需要 MQTT 登入的密碼。接著點選畫面右上方的帳號圖示內的『My Profile』。
🔽按下 MQTT API Key 更新按鈕。
🔽記下新增的 MQTT API Key,此字串就是登入 ThingSpeak MQTT 的密碼。
4. 開始上傳資訊到 ThingSpeak MQTT
>> 電路連接
關於電路連接的部分一樣是透過 ESP32 GPIO14 連接 DHT11,其他部分就是簡單的電源與 GND。
>> 完整程式碼
這邊主要的程式邏輯與上篇 303 MQTT Publish 發佈訊息到 Mosquitto Broker 是一樣的,唯一不同的就是連線從私有 Broker 變成雲端的ThingSpeak 主機。
from umqtt.simple import MQTTClient import machine,dht,utime,time,network d11=dht.DHT11(machine.Pin(14)) # GPIO14 as the DHT11 dataline mq_server = 'mqtt.thingspeak.com' mq_id = 'esp00001' mq_topic = "channels/" + "13xxxx" + "/publish/" + "JROxxxxxxxxxxxxxx" #id + write_api mq_user='james' mq_pass='KIBxxxxxxx' #thingspeak mqtt key wifi= network.WLAN(network.STA_IF) wifi.active(False) wifi.active(True) try: wifi.connect('tp_station','ooxx8811') print('start to connect wifi') for i in range(20): print('try to connect wifi in {}s'.format(i)) utime.sleep(1) if wifi.isconnected(): break if wifi.isconnected(): print('WiFi connection OK!') print('Network Config=',wifi.ifconfig()) else: print('WiFi connection Error') mqClient0 = MQTTClient(mq_id, mq_server, user=mq_user, password=mq_pass) mqClient0.connect() i=0 while True: i=i+1 d11.measure() mq_message='field1={}&field2={}'.format(d11.temperature(),d11.humidity()) mqClient0.publish(mq_topic, mq_message) print("message publish {}".format(i)) time.sleep(18) except Exception as e: print(e)
>> 程式解說
from umqtt.simple import MQTTClient import machine,dht,utime,time,network d11=dht.DHT11(machine.Pin(14)) # GPIO14 as the DHT11 dataline mq_server = 'mqtt.thingspeak.com' mq_id = 'esp00001' mq_topic = 'channels/' +'13xxxx' + '/publish/' + 'JROxxxxxxxxxxxxxx' #id + write_api mq_user='james' mq_pass='KIBxxxxxxx' #thingspeak mqtt key wifi= network.WLAN(network.STA_IF) wifi.active(False) wifi.active(True)
需要特別講解的就是關於 mqtt 的相關設定:
- 第5行:mq_server 指定連線的 broker 名稱或位址,這邊填入 mqtt.thingserver.com
- 第6行:裝置 ID,自行指定不要重複的名稱即可。
- 第7行:mq_topic 指定 mqtt 的主題,關於此項 ThingSpeak 有既定要求,格式為 ‘channels/’ + channel_id + ‘/publish/’ + write_api_key,剛剛從ThingSpeak網頁上記錄下來的 channel_id 跟 write_api_key就是填在這裡。
- 第8行: mqtt 登入帳號可以自己填。
- 第9行: mqtt 登入密碼就是ThingSpeak網頁的MQTT API KEY
try: wifi.connect('tp_station','ooxx8811') print('start to connect wifi') for i in range(20): print('try to connect wifi in {}s'.format(i)) utime.sleep(1) if wifi.isconnected(): break if wifi.isconnected(): print('WiFi connection OK!') print('Network Config=',wifi.ifconfig()) else: print('WiFi connection Error') mqClient0 = MQTTClient(mq_id, mq_server, user=mq_user, password=mq_pass) mqClient0.connect()
此段程式的前半部分進行 wifi 連線,一旦 wifi 狀態 OK 後,便開始連接 ThingSpeak 的 MQTT 主機。
i=0 while True: i=i+1 d11.measure() mq_message='field1={}&field2={}'.format(d11.temperature(),d11.humidity()) mqClient0.publish(mq_topic, mq_message) print("message publish {}".format(i)) time.sleep(18) except Exception as e: print(e)
ThingSpeak 的 MQTT 主機連上後,ESP32開始從 DHT11取得溫濕度數值,發佈MQTT訊息格式為 ‘field1=xxxx&field2=xxxx’,field1跟 field2 就是我們在網站上開啟的欄位, =後面放入想要在該欄位填寫的字串,field1跟field2中間用&作為連接,所以 mq_message='field1={}&field2={}'.format(d11.temperature(),d11.humidity())
這行就是把DHT11的溫濕度值填入 field1與field2的欄位。最後由於免費 license 的關係,每次必須超過15秒的更新區間,delay 設成18秒,也可超過DHT的更新時間2秒。
>> ThingSpeak 即時圖表觀看
雲端服務平台對於資料是數字型態時,通常會提供圖表方式的線上即時觀看,ThingSpeak 也有這樣的功能。先確定自己剛剛設定的 Channel 是 private 或 public (預設是 private),找到該 Channel 的 private 或 public view 標籤頁,即可知道目前資料更新的狀態。
5. 總結
要我們熟悉 Micropython 的 MQTT 模組用法,不管是發佈訊息到私有 Mosquitto Broker 或 ThingSpeak 類似平台,應該都當容易,差別在於每個平台都會有一些特別的語法,事先到官網確認並申請 API 就 OK了。除了 MQTT 外,雲端服務通常也會支援 HTTPS 或 websocket 協定,這些後續 JIMI哥 會再持續定期更新內容。
今天的內容就到這邊,如果各位有遇到什麼問題或想看那些教學內容,也歡迎在下面留言或寫信與我討論囉~
This Post Has 4 Comments
李岳駿
30 7 月 2021若是沒有MQTT API key 怎麼辦,該如何解決
jimi
6 8 月 2021很高興收到您的來信支持與詢問,我這邊再度檢視了一下 thingspaek 的 設定說明,
發現thingspeak 針對採用 MQTT協定的連線設定有更新步驟, 您可以可以參考下面網頁:
https://www.mathworks.com/help/thingspeak//mqtt-basics.html
裡面的 Create a ThingSpeak MQTT Device
現在的作法需要先新增 MQTT Device,才可以得到該device 的client ID 與 密碼相關設定,
後續在 EPS32 micropython mqtt 連線程式內容就大致一樣了, 您可以試試看,
我後續有空是會在針對這樣的流程更新一下該篇文章,
如果有其他問題 , 我們持續交流, 謝謝!
Denny Hsu
20 12 月 2021請問你用什麼工具寫呢?看起和一般Arduino IDE使用C不一樣, 好像是VB語法?是你介紹的Thonny 嗎? 再請教一下, 我看到這篇教學時已經變成你說的要Create a ThingSpeak MQTT Device了? 那Create完後哪個是APi KEY呢?Client ID?Username?Password?
jimi
21 12 月 2021你好,針對問題回覆如下:
1. 程式編輯:我個人是習慣vscode這個程式編輯器為主,並安裝 micropy-cli 這個套件來實現AutoComplete 的功能(這樣對於在寫micropython時,很多程式關鍵字編輯器就會自動完成),我之前寫的教學如下: https://jimirobot.tw/esp32-micropython-tutorial-autocomplete-106/
; Terminal(程式傳輸與電腦REPL連結):是使用 mpfshell-lite 工具(有些人會用ampy或 rshell)(https://github.com/junhuanchen/mpfshell-lite);
Thonny IDE 就是把上述兩個功能(程式編輯器與傳輸)整合再一起,所以推薦新手使用。
2.thingspeak 針對 mqtt 資料通訊已修改成上一則留言的方式,一旦透過該網址申請好 mqtt device 後, 在上方”Device”點選”MQTT”,就可以看到剛剛申請的裝置,點選”Edit”,就可以看到 username,clientID,password的內容, mqtt server的網址是 mqtt3.thingspeak.com , topic 則需改成 channels//publish/fields/field1, ( 在申請 channel 時就可以看到,filed1 為第一個欄位),之後在修改 python 程式 message 為上傳的數據(如 25)就可以在 thingspeak 監控畫面看到。
3. 本篇文章的第三節「3.訊息上傳前的準備工作」,這邊可以忽略,因為是 thingspeak 之前版本的設定。