實驗目的:通過自己制作的手機APP,連接MQTT服務器,獲取ESP32單片機的溫濕度信息,控制ESP32單片機上的LED開關。
實驗准備:
1、硬件:ESP32開發板(型號不限,esp01s也可以)、LED燈、DH11溫濕度傳感器、面包板等
2、軟件:
(1)arduino軟件,可以到官網https://www.arduino.cc/en/Main/Software下載。
(2)App Inventor 2 集成版,可以到官網https://www.wxbit.com/下載。(解釋一下:這個軟件是適用於初學者的手機APP制作軟件,界面設計所見即所得,程序設計通過拖拽積木塊來實現。)
(3)需要一台服務器。(可以是自己的電腦,也可以到網上買雲服務器,筆者是購買的騰訊雲服務器(每年79元),除了運行網站外,再捎帶着提供MQTT服務。)
實驗步驟:
一、總體設想
1、建一個MQTT服務器,提供訂閱/發布 消息的功能。
2、用App Inventor 2 制作一個APP,功能是連接MQTT服務器,訂閱ESP32單片機的溫濕度信息,控制ESP32單片機上的LED開關。
3、為ESP32編寫程序並燒錄,完成連接MQTT服務器,發布溫濕度信息,訂閱LED控制主題,根據消息來開、關LED燈。

二、MQTT服務器的建立
MQTT是IBM開發的一個即時通訊協議。MQTT是面向M2M和物聯網的連接協議,采用輕量級發布和訂閱消息傳輸機制。可以發布或接收特定主題的消息,基於發布/訂閱模式。
筆者使用的是騰訊雲服務器,操作系統是centos7.5,我使用的軟件是Mosquitto,這是一款實現了 MQTT v3.1 協議的開源消息代理軟件,提供輕量級的,支持發布/訂閱的的消息推送模式,使設備對設備之間的短消息通信簡單易用。
安裝比較簡單:
# 首先要下載源代碼包,目前最高版本是1.6.9 wget http://mosquitto.org/files/source/mosquitto-1.6.9.tar.gz # 下載后,首先是解壓 tar zxfv mosquitto-1.6.9.tar.gz # 進入解壓后的目錄 cd mosquitto-1.6.9 # 先編譯 make # 最后安裝 make instal
安裝過程中,可以出現找不**文件的情況,可以使用yum install命令進行安裝 。
安裝完成后,通過使用以下命令啟動。
mosquitto -c /etc/mosquitto/mosquitto.conf -d
對於這個軟件,筆者也不太熟悉,僅用到了最基本的功能。
三、設計制作手機APP
設計手機APP,有很多專業軟件,功能強大,但對於這些極其簡單的應用來說,安裝、使用都過於復雜,所以筆者選用了為中小學生設計的一款軟件,App Inventor 2 。
WxBit 漢化版由華南理工大學楊道全老師基於 MIT App Inventor 開源項目二次開發,為志同道合的 App Inventor 愛好者服務。通過界面設計和邏輯設計來完成APP的制作,比較簡單。
具體使用方法因過於簡單,在這兒就不說了,直接貼圖吧。
首先是界面的設計 :

最后是邏輯設計,也就是咱們常說的程序代碼:

因為是圖形的界面,比較簡單,就不逐一解釋了。
四、ESP32單片機的程序、連接
(一)編寫arduino程序,用於完成連接MQTT服務器,發布溫濕度信息,訂閱LED控制主題,根據消息來開、關LED燈。
1、安裝arduino軟件,下載直接安裝就可以了。Windows安裝USB驅動時會彈出安全提示,一定要選擇“安裝”。
2、簡單介紹一下軟件的界面:(看圖)

3、編程前的准備工作:
(1)安裝對ESP32硬件的支持,一般有兩種方法,一種是下載硬件包,解壓到程序所在文件夾中的hardware文件夾里,一般適用於一些非常見類型的板子。二種是在首選項中設置附加開發板管理網址:https://github.com/espressif/arduino-esp32/releases/download/1.0.2/package_esp32_index.json。
然后在軟件中選擇工具--開發板****--開發板管理器,在這里輸入ESP32進行查找,然后點擊安裝。(操作看圖)

選擇合適的開發板及相應參數。

(2)安裝DH11溫濕度傳感器的程序包。
在arduino UNO等硬件中,使用DH11溫濕度傳感器比較簡單,但是在ESP32開發板中使用它,就需要選擇合適的程序包了

單擊more info鏈接,可以進入Github網站源碼倉庫,可以看一下它的例程,因為使用很簡單,這里就不詳說了。
4、正式編程
思路前邊已經說了,在程序中,我也進行了注釋,比較簡單,為節省時間,直接上代碼吧。
#include <WiFi.h> //wlan連接庫,有很多種,如esp8266.h……等 #include <PubSubClient.h>//發布訂閱庫,也可以使用mqtt.h #include "DHT.h" //這是一個讀取DHT溫濕度儀的庫,用這個庫能省點事。這個庫也有很多種,這是其中一個。 #define DHTPIN 15 //定義15號口為DHT11溫濕度儀的控制口。 #define DHTTYPE DHT11 //定義DHT溫濕度儀的類型。如DHT11、DHT21、DHT22,這個要根據實際來選。 DHT dht(DHTPIN, DHTTYPE); //構造函數 const char* ssid = "ssid"; //WIFI的ID const char* password = "password"; //WIFI的PASSWORD const char* mqtt_server = "*.*.*.*"; // mqtt服務器的地址。 const char* TOPIC = "ledconc"; // 訂閱信息主題 const char* client_id = "cid_dnt_led";//設備的客戶端編號 char* sh = new char[10]; //定義兩個字符串數組,用來存放溫濕度的浮點數轉換過來的字符串。 char* st = new char[10]; WiFiClient espClient; // 定義WLAN實例 PubSubClient client(espClient); // 定義PubSubClient的實例 long lastMsg = 0; // 記錄上一次發送信息的時間。 void setup() { dht.begin(); //初始化DHT11溫濕度儀。 pinMode(18, OUTPUT); // 定義18號口連接LED燈,設為輸出方式 //連接WIFI,如果連接不成功,則等待0.5秒后,繼續連接。 delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } // client.setServer(mqtt_server, 1883);//設定MQTT服務器與使用的端口 client.setCallback(leddev); //設定回調程序,當ESP32收到訂閱消息時會調用此方法 } void leddev(char* topic, byte* payload, unsigned int length) { if ((char)payload[0] == '1') { digitalWrite(18, HIGH); // 亮燈 } else { digitalWrite(18, LOW); // 熄燈 } } void reconnect() { while (!client.connected()) { if (client.connect(client_id)) { client.subscribe(TOPIC); } else { delay(5000); } } } void loop() { if (!client.connected()) //如果MQTT服務器連接不成功,則反復重試,連接成功后重新訂閱。 { reconnect(); } delay(2000); float h = dht.readHumidity(); //獲取溫濕度,是float格式 的。 float t = dht.readTemperature(); dtostrf(h, 2, 2, sh); // dtostrf()函數將float格式轉換為字符串。 dtostrf(t, 2, 2, st); client.loop(); long now = millis(); if (now - lastMsg > 2000)//每過2秒,發送溫濕度數據。 { lastMsg = now; client.publish("temperature", st); client.publish("humidity", sh); } }
5、進行燒錄
這個比較簡單,連接設備,選擇合適的COM端口,直接上傳即可,這里有一個小技巧,如果提示一直無法連接硬件,可以按一下ESP32板上的BOOT鍵。
