本示例使用零知-ESP8266来获取天气信息,首先需要安装库:ArduinoJson-v5.13.5.zip(点击下载)
也可以在GitHub下载,注意要下载5.~版本
解压,安装到库
选择解压文件,安装
也可以解压直接复制到E:\lingzhi_library\lingzhi-build\libraries(你lingzhi_library存放的位置)这样就完成安装了
1、打开零知开源开发工具
/**
* Demo:
* 演示Http请求天气接口信息
* @date 2019/06/01
*/
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
//以下三个定义为调试定义
const char* AP_SSID = "zaixinjian2019"; // **********-- 使用时请修改为当前你的 wifi ssid
const char* AP_PSK = "2019zaixinjiancp"; // **********-- 使用时请修改为当前你的 wifi 密码
const char* HOST = "http://api.seniverse.com";
const char* APIKEY = "wcmquevztdy1jpca"; //API KEY
const char* CITY = "shenzhen";
const char* LANGUAGE = "zh-Hans";//zh-Hans 简体中文 会显示乱码
// 我们要从此网页中提取的数据的类型
struct WeatherData {
char city[16];//城市名称
char weather[32];//天气介绍(多云...)
char temp[16];//温度
char udate[32];//更新时间
};
HTTPClient http;
//get请求url
String GetUrl="http://api.seniverse.com/v3/weather/now.json"
"?key=wcmquevztdy1jpca&location=shenzhen&language=zh-Hans";
String response;
WeatherData weatherData;//结构体实例化
void setup() {
// put your setup code here, to run once:
WiFi.mode(WIFI_STA); //设置esp8266 工作模式:客户端模式
Serial.begin(115200);
Serial.print("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("");
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP());
//设置超时
http.setTimeout(5000);
//设置请求url
http.begin(GetUrl);
//以下为设置一些头 其实没什么用 最重要是后端服务器支持
http.setUserAgent("esp8266");//用户代理版本
http.setAuthorization("esp8266","yssy");//用户校验信息
}
void loop() {
//心知天气 发送http get请求
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
//判断请求是否成功
if (httpCode == HTTP_CODE_OK) {
//读取响应内容
response = http.getString();
Serial.println("Get the data from Internet!");
Serial.println(response);
//解析响应内容
if (parseUserData(response, &weatherData)) {
//打印响应内容
printUserData(&weatherData);
}
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(10000);//每10s调用一次
}
/**
* @Desc 解析数据 Json解析
* 数据格式如下:
* {
* "results": [
* {
* "location": {
* "id": "WX4FBXXFKE4F",
* "name": "北京",
* "country": "CN",
* "path": "北京,北京,中国",
* "timezone": "Asia/Shanghai",
* "timezone_offset": "+08:00"
* },
* "now": {
* "text": "多云",
* "code": "4",
* "temperature": "23"
* },
* "last_update": "2017-09-13T09:51:00+08:00"
* }
* ]
*}
*/
bool parseUserData(String content, struct WeatherData* weatherData) {
// -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小
// 如果你使用StaticJsonBuffer时才需要
// const size_t BUFFER_SIZE = 1024;
// 在堆栈上分配一个临时内存池
// StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替
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;
}
// 打印从JSON中提取的数据
void printUserData(const struct WeatherData* weatherData) {
Serial.println("Print parsed data :");
Serial.print("City : ");
Serial.print(weatherData->city);
Serial.print(", \t");
Serial.print("Weather : ");
Serial.print(weatherData->weather);
Serial.print(",\t");
Serial.print("Temp : ");
Serial.print(weatherData->temp);
Serial.print(" C");
Serial.print(",\t");
Serial.print("Last Updata : ");
Serial.print(weatherData->udate);
Serial.println("\r\n");
}
2、验证代码,上传程序,打开调试 结果如下