| ESP32 教學 | MicroPython | 發佈訊息到 ThingSpeak MQTT 平台| 304 |

當各類感測器或裝置都能夠連網時,如何將這些資料進行分析或整合,就變成一個關鍵的環節,所謂雲端 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 更新按鈕。

ThingSpeak MQTT

🔽記下新增的 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 2 Comments

  1. 若是沒有MQTT API key 怎麼辦,該如何解決

    1. 很高興收到您的來信支持與詢問,我這邊再度檢視了一下 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 連線程式內容就大致一樣了, 您可以試試看,

      我後續有空是會在針對這樣的流程更新一下該篇文章,

      如果有其他問題 , 我們持續交流, 謝謝!

發佈留言

Close Menu