ESP8266作為一款功能強大的的物聯網模塊,已經被應用到了很多實用的物聯網項目中。作為一個菜鳥,本人也搗鼓這個東西很長時間了,在搗鼓這個東西的同時我也總結了一些使用經驗。在此借助CSDN平臺出幾個教程,將這些經驗分享給大家,同時也做為個人的實踐經驗總結。 ESP8266的主要開發方式有三種:官方SDK(深圳樂鑫的官方庫+深圳安信可的類eclipse開發環境),lua語言以及arduino的ESP8266庫。樓主經常使用第一種和第三種(對lua不太熟悉),對于新手而言官方的SDK開發還是比較晦澀難懂的,教程也不是很多(B站技新課堂基于官方SDK的ESP8266視頻教程比較不錯,有興趣的可以去了解),因此本esp8266初級入門實用教程還是使用arduino進行開發,需要大家配置好arduino中ESP8266的開發環境并對arduino的ESP8266庫有一定的了解。(大家可以去搜單片機菜鳥博哥的教程,私以為是我看過的基于arduino的最好的ESP8266文本教程)。 第一個實踐教程當然是從大家喜聞樂見的讀取網絡實時天氣開始,這個搞明白的話,大家基本上也就會對物聯網有一個感性的認識了。實現該項目的主要步驟如下: (一)注冊心知天氣賬戶,申請天氣數據AP免費版并記下訪問私鑰。
1.jpg (213.29 KB, 下載次數: 89)
下載附件
2020-5-29 00:55 上傳

打開心知天氣官網后進行注冊和登錄。
2.PNG (155.54 KB, 下載次數: 75)
下載附件
2020-5-29 00:55 上傳

申請天氣數據API免費版
3.PNG (118.63 KB, 下載次數: 68)
下載附件
2020-5-29 00:55 上傳

記下訪問私鑰
完成上述三個步驟我們就擁有了讀取心知天氣實時天氣狀況的權限,注意:免費版的訪問數據是有限制的,訪問頻次每分鐘只有20次,但對于我們而言已經夠用了。
(二)了解HTTP協議,獲取URL并確定最終訪問格式。
HTTP協議(超文本傳輸協議)是互聯網上應用最為廣泛的一種應用層網絡協議,用作客戶端和服務器之間的請求 - 響應協議,具體可參考此篇博文https://blog.csdn.net/weixin_34259559/article/details/87951549
HTTP協議中客戶端的數據請求和上傳主要依靠GET請求和POST請求進行。此次教程中我們只需要向服務器進行數據的請求,所以只講GET請求及其請求格式。
HTTP協議中數據的請求格式包含請求行(request line)、請求頭部(header)、空行和請求數據四個部分,下圖給出了請求報文的一般格式:
4.PNG (69.16 KB, 下載次數: 91)
下載附件
2020-5-29 00:55 上傳
HTTP協議使用統一資源標識符(Uniform Resource Identifiers, URI)來傳輸數據和建立連接。URL是一種特殊類型的URI,包含了用于查找某個資源的足夠的信息。我們想讀取心知天氣的數據資源也必須知道它的URL,心知天氣的文檔中給我們提供了它的URL格式,如下圖:
5.jpg (829.09 KB, 下載次數: 85)
下載附件
2020-5-29 00:55 上傳
知道了HTTP報文的格式和心知天氣的URL我們就可知得到最終的訪問格式,如下:
URL是; /v3/weather/now.json?key=“你的私鑰”&location=beijing&language=zh-Hans&unit=c HTTP/1.1\r\n //根據HTTP報文格式,在URL協議后面綴上協議版本HTTP/1.1請求頭部: 主機名:Host: api.seniverse.com\r\n 接收的語言:Accept-Language: zh-cn\r\n 連接的模式-- 斷開服務器連接:Connection: close\r\n 
(三)程序編寫,實現ESP8266訪問心知天氣并讀取當前實時天氣。
由于心知天氣返回的是JSON字符串,需要進行數據解析,自寫解析函數的話比較麻煩,這里我們使用前輩們已經為我們造好的輪子,JSON庫。程序中的JSON數據解析我已經附上了B站的教程地址。
#include <ESP8266WiFi.h>#include <ArduinoJson.h> //使用JSON-v5版的庫 const char* AP_SSID = "644"; // XXXXXX -- 使用時請修改為當前你的 wifi ssidconst char* AP_PSK = "@644.1234"; // XXXXXX -- 使用時請修改為當前你的 wifi 密碼WiFiClient client; //創建一個網絡對象/* 請求的Json數據格式如下: * { * "results": [ * { * "location": { * "id": "WX4FBXXFKE4F", * "name": "北京", * "country": "CN", * "path": "北京,北京,中國", * "timezone": "Asia/Shanghai", * "timezone_offset": "+08:00" * }, * "now": { * "text": "多云", * "code": "4", * "temperature": "23" * }, * "last_update": "2019-10-13T09:51:00+08:00" * } * ] *} */void wifi_start_connect() //連接WIFI{ WiFi.mode(WIFI_STA); //設置esp8266 工作模式 Serial.println("Connecting to "); //寫幾句提示 Serial.println(AP_SSID); WiFi.begin(AP_SSID, AP_PSK); //連接wifi WiFi.setAutoConnect(true); while (WiFi.status()!= WL_CONNECTED) //這個函數是wifi連接狀態,返回wifi鏈接狀態 { delay(500); Serial.print("."); } Serial.println("WiFi connected IP is"); Serial.println(WiFi.localIP()); }void parseUserData(String content) // Json數據解析并串口打印.可參考https://www.bilibili.com/video/av65322772{ const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210; DynamicJsonBuffer jsonBuffer(capacity); JsonObject& root = jsonBuffer.parseObject(content); JsonObject& results_0 = root["results"][0]; JsonObject& results_0_location = results_0["location"]; const char* results_0_location_id = results_0_location["id"]; const char* results_0_location_name = results_0_location["name"]; const char* results_0_location_country = results_0_location["country"]; const char* results_0_location_path = results_0_location["path"]; const char* results_0_location_timezone = results_0_location["timezone"]; const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; JsonObject& results_0_now = results_0["now"]; const char* results_0_now_text = results_0_now["text"]; const char* results_0_now_code = results_0_now["code"]; const char* results_0_now_temperature = results_0_now["temperature"]; const char* results_0_last_update = results_0["last_update"]; Serial.println(results_0_location_name); //通過串口打印出需要的信息 Serial.println(results_0_now_text); Serial.println(results_0_now_code); Serial.println(results_0_now_temperature); Serial.println(results_0_last_update); Serial.print("\r\n");}void setup() { Serial.begin(115200); wifi_start_connect(); client.setTimeout(5000);//設置服務器連接超時時間}void loop() { if(client.connect("api.seniverse.com", 80)==1) //連接服務器并判斷是否連接成功,若成功就發送GET 請求數據下發 { //換成你自己在心知天氣申請的私鑰//改成你所在城市的拼音 client.print("GET /v3/weather/now.json?key=“你的私鑰”&location=zhengzhou&language=zh-Hans&unit=c HTTP/1.1\r\n"); //心知天氣的URL格式 client.print("Host:api.seniverse.com\r\n"); client.print("Accept-Language:zh-cn\r\n"); client.print("Connection:close\r\n\r\n"); //向心知天氣的服務器發送請求。 String status_code = client.readStringUntil('\r'); //讀取GET數據,服務器返回的狀態碼,若成功則返回狀態碼200 Serial.println(status_code); if(client.find("\r\n\r\n")==1) //跳過返回的數據頭,直接讀取后面的JSON數據, { String json_from_server=client.readStringUntil('\n'); //讀取返回的JSON數據 Serial.println(json_from_server); parseUserData(json_from_server); //將讀取的JSON數據,傳送到JSON解析函數中進行顯示。 } }else { Serial.println("connection failed this time"); delay(5000); //請求失敗等5秒 } client.stop(); //關閉HTTP客戶端,采用HTTP短鏈接,數據請求完畢后要客戶端要主動斷開https://blog.csdn.net/huangjin0507/article/details/52396580delay(5000); }
(四)實際演示;
6.jpg (4.05 MB, 下載次數: 80)
下載附件
2020-5-29 00:55 上傳
我們可以清楚的看到ESP8266成功的讀取到了當前天氣數據,并通過串口打印了出來。
(五)總結
本次教程只是做了一個走馬觀花式的粗略演示(有錯誤也請各位指出,相互交流),無論是其中的HTTP協議還是JSON解析都可以再引出一大波知識點,這些都需要各位自己去搜索資料學習。 接下來我會更新一些ESP8266使用HTTP和MQTT協議與ONENET交互的教程(樓主作為懶癌晚期患者,就隨緣吧)。 |