ThingSpeak雲端平台修改了MQTT服務的設置方式,本文將說明取得MQTT密碼的步驟,以及在ESP8266控制板(如:NodeMCU或Wemos D1 mini)執行Arduino和MicroPython,透過MQTT協定上傳DHT11溫溼度資料到ThingSpeak的程式碼。
本文的硬體連線與「MQTT教學(九)」相同:

新增ThingSpeak的MQTT裝置
舊版的ThingSpeak “My Profile”頁面有個產生MQTT API密鑰的欄位,在新版網頁中移除了,改由底下步驟產生MQTT API密鑰。
1. 登入ThingSpeak網站後,點擊導覽列上的Devices→MQTT(裝置→MQTT)選單。

2. 在MQTT Devices(MQTT裝置)頁面,點擊Add a new device(新增一個裝置)鈕:

3. 在底下的畫面中,填入裝置名稱和描述、選擇要授權存取的通道,然後按下Add Channel(新增通道)鈕。

4. 畫面底下將顯示已授權的通道。點擊Add Device(新增裝置)鈕。

5. 畫面將顯示新增裝置的用戶端ID、使用者名稱和密碼,請複製這些密碼備用,也可以點擊左下的Download Credentials鈕儲存純文字格式的密鑰。

6. 按下Done(完成)鈕,畫面將顯示MQTT裝置的摘要。

上傳資料到ThingSpeak MQTT伺服器的MicroPython程式
沿用《超圖解Python物聯網實作入門》18-22頁的MicroPython程式碼,需要修改MQTT伺服器的網址、使用者名稱、密碼和用戶端ID。topic(主題)字串末尾,本來有附加「寫入API密鑰」,現在不需要了,修改後的完整程式碼如下:
import machine import ubinascii import time import dht from machine import Pin from umqtt.simple import MQTTClient config = { 'broker':'mqtt3.thingspeak.com', # 之前是:mqtt.thingspeak.com 'user': '上個步驟產生的使用者名稱', 'pwd': '上個步驟產生的密碼', 'id' : '上個步驟產生的用戶端ID', 'port':1883, 'topic' : b'channels/通道ID/publish' # 不用填「寫入API密鑰」 } client = MQTTClient(client_id=config['id'], server=config['broker'], port=config['port'], user=config['user'], password=config['pwd']) d = dht.DHT11(Pin(5)) # DHT11接GPIO5 (D1) d.measure() data = 'field1={}&field2={}'.format( d.temperature(), d.humidity()) client.connect() client.publish(config['topic'], data.encode()) time.sleep(2) client.disconnect()
在燒錄MicroPython的ESP8266執行上面的程式,它將上傳DHT11溫濕度到ThingSpeak平台。
上傳資料到ThingSpeak MQTT伺服器的Arduino程式
修改「MQTT教學(九)」貼文的Arduino程式,更新MQTT伺服器的網址、使用者名稱、密碼和用戶端ID。topic(主題)字串末尾,本來有附加「寫入API密鑰」,現在不需要了,修改後的完整程式碼如下:
#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <dht11.h> #define DHT11PIN D1 // DHT11資料接腳 #define mqttPort 1883 // MQTT伺服器埠號 const char* ssid = "Wi-Fi網路名稱"; const char* password = "Wi-Fi網路密碼"; const char* mqttServer = "mqtt3.thingspeak.com"; // MQTT伺服器位址 const char* mqttUserName = "使用者名稱"; const char* mqttPwd = " MQTT密碼"; const char* clientID = "用戶端ID "; const char* topic = "channels/通道ID/publish"; // 不用填「寫入API密鑰」 unsigned long prevMillis = 0; // 暫存經過時間(毫秒) const long interval = 20000; // 上傳資料的間隔時間,20秒。 String msgStr = ""; // 暫存MQTT訊息字串 dht11 DHT11; int temp; // 暫存溫度 int hum; // 暫存濕度 WiFiClient espClient; PubSubClient client(espClient); void setup_wifi() { delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); } void reconnect() { while (!client.connected()) { if (client.connect(clientID, mqttUserName, mqttPwd)) { Serial.println("MQTT connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); // 等5秒之後再重試 } } } void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqttServer, mqttPort); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); // 等待20秒 if (millis() - prevMillis > interval) { prevMillis = millis(); // 讀取DHT11的溫濕度資料 int chk = DHT11.read(DHT11PIN); if (chk == 0) { temp = DHT11.temperature; hum = DHT11.humidity; } // 組合MQTT訊息;field1填入溫度、field2填入濕度 msgStr = msgStr + "field1=" + temp + "&field2=" + hum; Serial.print("Publish message: "); Serial.println(msgStr); client.publish(topic, msgStr.c_str()); // 發布MQTT主題與訊息 msgStr = ""; } }
編譯、上傳程式到ESP8266控制板,它將上傳DHT11溫濕度到ThingSpeak平台。
想知道怎麼透過MQTT上傳感測器E18-D80NK感測器資料到THINGSPEAK平台(也是使用ESP8266,NODE MCU V2)
1. 讀取感測器資料
2. 上傳ThingSpeak
3. 延遲一段時間
4. 重複1
老師 您好,
想詢問一下,當感測器 DHT11 Publish 到ThingSpeak ,如果到一定閥值例如30度,要透過ThingSpeak發布訊息給Client(ESP : subscribe),以這樣的架構能否用 ThingSpeak一些內建的功能,來達到此目的?
應該沒有這樣的設定,要由你的程式碼判斷執行。