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獲取天氣數據了。