ESP8266使用WiFi模組呼叫心知天氣API獲取天氣資料
阿新 • • 發佈:2021-10-25
ESP8266使用WiFi模組呼叫心知天氣API獲取天氣資料
安裝 ArduinoJson 庫
儘量使用 ArduinoJson 5.x 版本,因為 6.x 版本有很大的改動。
申請“心知天氣”的個人APIKEY
註冊成功後選擇免費版
去免費版裡面複製自己的私鑰
把程式碼中的可變選項替換成自己的私鑰、網路名稱和密碼,程式碼如下:
#include<ESP8266WiFi.h> #include<ArduinoJson.h> const char* ssid ="******";//輸入熱點名稱 const char* password ="*****";//輸入熱點密碼 const char* host ="api.seniverse.com"; const char* APIKEY ="*********";//輸入自己申請的知心天氣私鑰 const char* city ="hangzhou";//可根據需要改為其餘城市的拼音 const char* language ="zh-Hans"; const unsigned long BAUD_RATE=115200; const unsigned long HTTP_TIMEOUT=5000; const size_t MAX_CONTENT_SIZE=1000; struct WeatherData{//儲存天氣資料的結構體,可根據需要自行新增成員變數 char city[16]; char weather[32]; char temp[16]; char udate[32]; }; WiFiClient client;//建立了一個網路物件 char response[MAX_CONTENT_SIZE]; char endOfHeaders[]="\r\n\r\n"; //初始化 void setup() { Serial.begin(BAUD_RATE); wifiConnect();//連線WiFi client.setTimeout(HTTP_TIMEOUT); } void loop() { while(!client.connected()){ if(!client.connect(host,80)){//嘗試建立連線 Serial.println("connection...."); delay(500); } } //連線成功,傳送GET請求 if(sendRequest(host,city,APIKEY)&&skipResponseHeaders()) { //傳送http請求 並且跳過響應頭 clrEsp8266ResponseBuffer();//清除快取 readReponseContent(response,sizeof(response));//從HTTP伺服器響應中讀取正文 WeatherData weatherData; if(parseUserData(response,&weatherData)){//判斷Json資料包是否分析成功 printUserData(&weatherData);//輸出讀取到的天氣資訊 } stopConnect(); delay(5000); } } //WiFi連線 void wifiConnect(){ WiFi.mode(WIFI_STA);//設定esp8266工作模式 Serial.print("Connecting to"); Serial.println(ssid); WiFi.begin(ssid,password);//連線WiFi WiFi.setAutoConnect(true); while(WiFi.status()!=WL_CONNECTED){//該函式返回WiFi的連線狀態 delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); delay(500); Serial.println("IP address:"); Serial.println(WiFi.localIP()); } //傳送http請求 bool sendRequest(const char* host,const char* cityid,const char* apiKey){ String GetUrl="/v3/weather/now.json?key="; GetUrl+=APIKEY; GetUrl+="&location="; GetUrl+=city; GetUrl+="&language="; GetUrl+=language; GetUrl+="&unit=c "; client.print(String("GET ")+GetUrl+"HTTP/1.1\r\n"+"Host:"+host+"\r\n"+"Connection:close\r\n\r\n"); Serial.println("creat a request:"); Serial.println(String("GET ")+GetUrl+"HTTP/1.1\r\n"+"Host:"+host+"\r\n"+"Connection:close\r\n\r\n"); delay(1000); return true; } //跳過響應頭 bool skipResponseHeaders(){ bool ok=client.find(endOfHeaders); if(!ok){ Serial.println("No response of invalid response!"); } return ok; } //讀取響應的正文資訊 void readReponseContent(char* content,size_t maxSize){ size_t length=client.readBytes(content,maxSize); delay(100); Serial.println("Get the data from Internet"); content[length]=0; Serial.println(content);//輸出讀取到的資料 Serial.println("Read data Over!"); client.flush();//重新整理客戶端 } //分析 Json 資料包 bool parseUserData(char* content,struct WeatherData* weatherData){ DynamicJsonBuffer jsonBuffer;//建立一個動態緩衝區例項 JsonObject&root=jsonBuffer.parseObject(content);//根據需要解析的資料來計算緩衝區的大小 if(!root.success()){ Serial.println("JSON parsing failed!"); return false; } //複製資料包中所需的字串 strcpy(weatherData->city,root["results"][0]["location"]["name"]); strcpy(weatherData->weather,root["results"][0]["now"]["text"]); strcpy(weatherData->temp,root["results"][0]["now"]["temperature"]); strcpy(weatherData->udate,root["results"][0]["last_update"]); return true; } //串列埠輸出 void printUserData(const struct WeatherData* weatherData){ Serial.println("Print parsed data:"); Serial.print("City:"); Serial.print(weatherData->city); Serial.print(" Weather:"); Serial.print(weatherData->weather); Serial.print(" Temp:"); Serial.print(weatherData->temp); Serial.print("℃"); Serial.print(" UpdateTime:"); Serial.println(weatherData->udate); } //停止客戶端訪問 void stopConnect(){ Serial.println("Disconnect"); client.stop();//停止客戶端訪問 } //清除快取 void clrEsp8266ResponseBuffer(void){ memset(response,0,MAX_CONTENT_SIZE); }
程式碼還需課後多理解一下。這樣就能使用ESP8266的WiFi模組呼叫心知天氣API獲取天氣資料了。