找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6739|回復(fù): 1
收起左側(cè)

esp8266初級(jí)入門實(shí)用教程一之訪問(wèn)心知天氣讀取實(shí)時(shí)天氣數(shù)據(jù)

[復(fù)制鏈接]
ID:418061 發(fā)表于 2020-5-28 23:30 | 顯示全部樓層 |閱讀模式
ESP8266作為一款功能強(qiáng)大的的物聯(lián)網(wǎng)模塊,已經(jīng)被應(yīng)用到了很多實(shí)用的物聯(lián)網(wǎng)項(xiàng)目中。作為一個(gè)菜鳥,本人也搗鼓這個(gè)東西很長(zhǎng)時(shí)間了,在搗鼓這個(gè)東西的同時(shí)我也總結(jié)了一些使用經(jīng)驗(yàn)。在此借助CSDN平臺(tái)出幾個(gè)教程,將這些經(jīng)驗(yàn)分享給大家,同時(shí)也做為個(gè)人的實(shí)踐經(jīng)驗(yàn)總結(jié)。
ESP8266的主要開發(fā)方式有三種:官方SDK(深圳樂(lè)鑫的官方庫(kù)+深圳安信可的類eclipse開發(fā)環(huán)境),lua語(yǔ)言以及arduino的ESP8266庫(kù)。樓主經(jīng)常使用第一種和第三種(對(duì)lua不太熟悉),對(duì)于新手而言官方的SDK開發(fā)還是比較晦澀難懂的,教程也不是很多(B站技新課堂基于官方SDK的ESP8266視頻教程比較不錯(cuò),有興趣的可以去了解),因此本esp8266初級(jí)入門實(shí)用教程還是使用arduino進(jìn)行開發(fā),需要大家配置好arduino中ESP8266的開發(fā)環(huán)境并對(duì)arduino的ESP8266庫(kù)有一定的了解。(大家可以去搜單片機(jī)菜鳥博哥的教程,私以為是我看過(guò)的基于arduino的最好的ESP8266文本教程)。
第一個(gè)實(shí)踐教程當(dāng)然是從大家喜聞樂(lè)見的讀取網(wǎng)絡(luò)實(shí)時(shí)天氣開始,這個(gè)搞明白的話,大家基本上也就會(huì)對(duì)物聯(lián)網(wǎng)有一個(gè)感性的認(rèn)識(shí)了。實(shí)現(xiàn)該項(xiàng)目的主要步驟如下:
(一)注冊(cè)心知天氣賬戶,申請(qǐng)?zhí)鞖鈹?shù)據(jù)AP免費(fèi)版并記下訪問(wèn)私鑰。
1.jpg

                                                                      打開心知天氣官網(wǎng)后進(jìn)行注冊(cè)和登錄。
2.PNG

                                                                                  申請(qǐng)?zhí)鞖鈹?shù)據(jù)API免費(fèi)版
3.PNG

                                                                                           記下訪問(wèn)私鑰
完成上述三個(gè)步驟我們就擁有了讀取心知天氣實(shí)時(shí)天氣狀況的權(quán)限,注意:免費(fèi)版的訪問(wèn)數(shù)據(jù)是有限制的,訪問(wèn)頻次每分鐘只有20次,但對(duì)于我們而言已經(jīng)夠用了。
(二)了解HTTP協(xié)議,獲取URL并確定最終訪問(wèn)格式。
HTTP協(xié)議(超文本傳輸協(xié)議)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種應(yīng)用層網(wǎng)絡(luò)協(xié)議,用作客戶端和服務(wù)器之間的請(qǐng)求 - 響應(yīng)協(xié)議,具體可參考此篇博文https://blog.csdn.net/weixin_34259559/article/details/87951549
HTTP協(xié)議中客戶端的數(shù)據(jù)請(qǐng)求和上傳主要依靠GET請(qǐng)求和POST請(qǐng)求進(jìn)行。此次教程中我們只需要向服務(wù)器進(jìn)行數(shù)據(jù)的請(qǐng)求,所以只講GET請(qǐng)求及其請(qǐng)求格式。
HTTP協(xié)議中數(shù)據(jù)的請(qǐng)求格式包含請(qǐng)求行(request line)、請(qǐng)求頭部(header)、空行和請(qǐng)求數(shù)據(jù)四個(gè)部分,下圖給出了請(qǐng)求報(bào)文的一般格式:
4.PNG
HTTP協(xié)議使用統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifiers, URI)來(lái)傳輸數(shù)據(jù)和建立連接。URL是一種特殊類型的URI,包含了用于查找某個(gè)資源的足夠的信息。我們想讀取心知天氣的數(shù)據(jù)資源也必須知道它的URL,心知天氣的文檔中給我們提供了它的URL格式,如下圖:
5.jpg
知道了HTTP報(bào)文的格式和心知天氣的URL我們就可知得到最終的訪問(wèn)格式,如下:
URL是; /v3/weather/now.json?key=“你的私鑰”&location=beijing&language=zh-Hans&unit=c HTTP/1.1\r\n            //根據(jù)HTTP報(bào)文格式,在URL協(xié)議后面綴上協(xié)議版本HTTP/1.1請(qǐng)求頭部:        主機(jī)名:Host: api.seniverse.com\r\n                 接收的語(yǔ)言:Accept-Language: zh-cn\r\n                 連接的模式-- 斷開服務(wù)器連接:Connection: close\r\n        
(三)程序編寫,實(shí)現(xiàn)ESP8266訪問(wèn)心知天氣并讀取當(dāng)前實(shí)時(shí)天氣。
由于心知天氣返回的是JSON字符串,需要進(jìn)行數(shù)據(jù)解析,自寫解析函數(shù)的話比較麻煩,這里我們使用前輩們已經(jīng)為我們?cè)旌玫妮喿,JSON庫(kù)。程序中的JSON數(shù)據(jù)解析我已經(jīng)附上了B站的教程地址。
#include <ESP8266WiFi.h>#include <ArduinoJson.h>                 //使用JSON-v5版的庫(kù) const char* AP_SSID     = "644";         // XXXXXX -- 使用時(shí)請(qǐng)修改為當(dāng)前你的 wifi ssidconst char* AP_PSK = "@644.1234";        // XXXXXX -- 使用時(shí)請(qǐng)修改為當(dāng)前你的 wifi 密碼WiFiClient client;                       //創(chuàng)建一個(gè)網(wǎng)絡(luò)對(duì)象/*  請(qǐng)求的Json數(shù)據(jù)格式如下: * { *    "results": [ *        { *            "location": { *                "id": "WX4FBXXFKE4F", *                "name": "北京", *                "country": "CN", *                "path": "北京,北京,中國(guó)", *                "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);                 //設(shè)置esp8266 工作模式   Serial.println("Connecting to ");    //寫幾句提示  Serial.println(AP_SSID);  WiFi.begin(AP_SSID, AP_PSK);         //連接wifi  WiFi.setAutoConnect(true);  while (WiFi.status()!= WL_CONNECTED) //這個(gè)函數(shù)是wifi連接狀態(tài),返回wifi鏈接狀態(tài)        {           delay(500);         Serial.print(".");        }  Serial.println("WiFi connected IP is");  Serial.println(WiFi.localIP()); }void parseUserData(String content)  // Json數(shù)據(jù)解析并串口打印.可參考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);                       //通過(guò)串口打印出需要的信息 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);//設(shè)置服務(wù)器連接超時(shí)時(shí)間}void loop() {                            if(client.connect("api.seniverse.com", 80)==1)              //連接服務(wù)器并判斷是否連接成功,若成功就發(fā)送GET 請(qǐng)求數(shù)據(jù)下發(fā)         {                                           //換成你自己在心知天氣申請(qǐng)的私鑰//改成你所在城市的拼音   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"); //向心知天氣的服務(wù)器發(fā)送請(qǐng)求。                    String status_code = client.readStringUntil('\r');        //讀取GET數(shù)據(jù),服務(wù)器返回的狀態(tài)碼,若成功則返回狀態(tài)碼200   Serial.println(status_code);         if(client.find("\r\n\r\n")==1)                            //跳過(guò)返回的數(shù)據(jù)頭,直接讀取后面的JSON數(shù)據(jù),     {      String json_from_server=client.readStringUntil('\n');  //讀取返回的JSON數(shù)據(jù)      Serial.println(json_from_server);      parseUserData(json_from_server);                      //將讀取的JSON數(shù)據(jù),傳送到JSON解析函數(shù)中進(jìn)行顯示。     }  }else                                          {    Serial.println("connection failed this time");   delay(5000);                                            //請(qǐng)求失敗等5秒  }      client.stop();                                            //關(guān)閉HTTP客戶端,采用HTTP短鏈接,數(shù)據(jù)請(qǐng)求完畢后要客戶端要主動(dòng)斷開https://blog.csdn.net/huangjin0507/article/details/52396580delay(5000);         }
(四)實(shí)際演示;
6.jpg
我們可以清楚的看到ESP8266成功的讀取到了當(dāng)前天氣數(shù)據(jù),并通過(guò)串口打印了出來(lái)。
(五)總結(jié)
本次教程只是做了一個(gè)走馬觀花式的粗略演示(有錯(cuò)誤也請(qǐng)各位指出,相互交流),無(wú)論是其中的HTTP協(xié)議還是JSON解析都可以再引出一大波知識(shí)點(diǎn),這些都需要各位自己去搜索資料學(xué)習(xí)。 接下來(lái)我會(huì)更新一些ESP8266使用HTTP和MQTT協(xié)議與ONENET交互的教程(樓主作為懶癌晚期患者,就隨緣吧)。

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:481073 發(fā)表于 2020-6-12 09:29 | 顯示全部樓層
問(wèn)下能提供源碼嗎,最近在學(xué)習(xí)這個(gè)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表