今天我就来记录一下之前做的一个小玩意ESP8266+OLED获取天气。
首先我使用的核心是ESP8266-12f开发板,某宝上面十几块钱就是下图的这块板子。这块板子的固件是NodeMCU固件,买回来的原装固件不要弄错了。开发环境用的是ArduinoIDE。前期工作准备好了我们就进入正题了。
这个问题其实对我们新手来说是非常关键的,这个小项目很久之前就想做了,但是苦于当时找不到天气资料的获取网站,所以一直迟迟没做。但在这里我找到了两个很好用的天气源API接口。首先推荐的第一个是心知天气。就是下面那个图标,此处放上官网网址进去之后可以免费注册。注册完之后可以获得免费查询的次数。申请步骤如下图。
申请完成之后可以看到自己的产品密匙什么的,见下图
这个时候就要去试试自己的API接口了。在浏览器中输入https://api.seniverse.com/v3/weather/now.jsonkey=上图的私钥&location=beijing&language=zh-Hans&unit=c 如下图可以直接通过浏览器来访问自己的API接口。以下是访问我们这边的城市的,如果亲想换成自己的城市可自行下载城市代号列表https://docs.seniverse.com/api/start/start.html
做完这一步就说明自己的API接口已经可以正常使用了。接下来讲述代码部分。
做这个项目之前我们前期准备工作还有提前装好ArduinoJson (V5版本的,我的是V5.13.3版本),ESP8266HTTPClient这两个库(装库在这里不在赘述)。
const char* ssid = "TP-LINK_03F6"; // 你的WiFi账号
const char* password = "zbdxdgdzsys306"; // 你的WIFI密码
void get_WIFI(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //等待wifi连接
delay(500);
Serial.println("Connecting.."); //重复打印 "Connecting..",直到连接成功
}
Serial.println("");
Serial.println("Connected to ");
Serial.println(ssid);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
串口打印了本地IP地址之后接下来我们准备用常用的HTTP协议来进行访问API端口的操作(操作之前记得装两个库)
其中用到了一个通信协议HTTP协议,其最重要的一个方法就是get方法得到服务器的反馈以及报文等等(其实HTTP1.0版本最重要的方法也就只有get和post方法了)。得到得到报文之后紧接着就是对报文进行处理。这个时候就是调用JSON这一些列办法了,至于有人会问这个JSON是什么,我这样和你们说吧,它只是一种死板的格式,你想要的信息包括在里面了。它的核心格式就是键值对。什么意思呢?举个例子你的档案上面肯定会写姓名那一栏然后紧跟着某某某,“姓名”就是相当于提示你接下来的信息是什么,其中的“某某某”才是你真的想要的信息。这个时候有人会问为什么不直接用字符串进行处理呢?实际上每次的报文长度都是不知道的,虽然格式是一样的但每次有用的信息可长可短,JSON有个动态方法能动态开辟你需要存放消息合适大小的内存来满足你的需要。还有一点JSON还要个核心思想就是万物皆对象,就是你可能传递过来的信息有很多种类型,但是JSON就会把所有的信息都当做是一个个对象,单独对其进行操作,所以很方便。推荐一个网站能帮你处理你的JSON格式信息https://arduinojson.org/assistant/ (访问有些慢,自行体会)。下面的代码是可以直接拿去用的,记得修改地址,每个人不一样。
#include
#include
String now_address="",now_weather="",now_temperature="";//用来存储报文得到的字符串
void get_weather(){
if (WiFi.status() == WL_CONNECTED) { //如果 Wi-Fi 连接成功
//此处往下是取得实况天气的程序
//心知API的网址,记得修改自己的密码!!!!!!!
http.begin("http://api.seniverse.com/v3/weather/now.json?key=你自己的密码&location=ez&language=zh-Hans&unit=c");
int httpget_now = http.GET(); //赋值
Serial.println("httpget_now:");
Serial.println(httpget_now);
if (httpget_now == HTTP_CODE_OK) { //检查一下是否为0,应该是去检查缓存区是否为空
Serial.println("that is ok");
String respone = http.getString();
Serial.println(respone);
/*数据解析:使用 https://arduinojson.org/assistant/ 一个工具可以直接生成程序,挑有用的复制就行*/
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210;
DynamicJsonBuffer doc(capacity);
JsonObject& root = doc.parseObject(respone);
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"]; // "CN"
const char* results_0_location_path = results_0_location["path"]; // "鄂州,鄂州,湖北,中国"
const char* results_0_location_timezone = results_0_location["timezone"]; // "Asia/Shanghai"
const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00"
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"]; // "0"
const char* results_0_now_temperature = results_0_now["temperature"]; // "37"
const char* results_0_last_update = results_0["last_update"]; // "2020-08-04T14:30:00+08:00"
//赋值,因为现在这些变量是在缓存区,一会将被清空
now_address=results_0_location_name; //北京
now_weather=results_0_now_text; //晴
now_temperature=results_0_now_temperature; //19
http.end();
delay(100);
}
}
}
到这里两个重要函数已经写好了,如果说大佬们需要查阅未来的几天的天气预报,建议大佬们看一下心知天气官网提供的手册,非常简单,如果自己实在不知道怎么写自己的网址的,强烈建议看看心知天气官网的文档,关于API端口的介绍,里面有现成的自己的网址可以直接复制。
下面附上全部代码
#include
#include
#include //版本为V5版本,最新的版本不适用下面的代码
String now_address="",now_weather="",now_temperature="";//用来存储报文得到的字符串
const char* ssid = "Xiaomi_8D09"; // 你的WiFi账号
const char* password = "你的密码"; // 你的WIFI密码
HTTPClient http; //开始登陆
void get_WIFI(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //等待wifi连接
delay(500);
Serial.print(".."); //重复打印 "Connecting..",直到连接成功
}
Serial.println(" ");
Serial.println("Connected to ");
Serial.println(ssid);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void get_weather(){
if (WiFi.status() == WL_CONNECTED) { //如果 Wi-Fi 连接成功
//此处往下是取得实况天气的程序
//心知API的网址,记得修改自己的密码!!!!!!!
http.begin("http://api.seniverse.com/v3/weather/now.json?key=你自己的密码&location=ez&language=zh-Hans&unit=c");
int httpget_now = http.GET(); //赋值
Serial.println("httpget_now:");
Serial.println(httpget_now);
if (httpget_now == HTTP_CODE_OK) { //检查一下是否为0,应该是去检查缓存区是否为空
Serial.println("that is ok");
String respone = http.getString();
Serial.println(respone);
/*数据解析:使用 https://arduinojson.org/assistant/ 一个工具可以直接生成程序,挑有用的复制就行*/
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210;
DynamicJsonBuffer doc(capacity);
JsonObject& root = doc.parseObject(respone);
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"]; // "CN"
const char* results_0_location_path = results_0_location["path"]; // "鄂州,鄂州,湖北,中国"
const char* results_0_location_timezone = results_0_location["timezone"]; // "Asia/Shanghai"
const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00"
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"]; // "0"
const char* results_0_now_temperature = results_0_now["temperature"]; // "37"
const char* results_0_last_update = results_0["last_update"]; // "2020-08-04T14:30:00+08:00"
//赋值,因为现在这些变量是在缓存区,一会将被清空
now_address=results_0_location_name; //北京
now_weather=results_0_now_text; //晴
now_temperature=results_0_now_temperature; //19
http.end();
delay(100);
}
}
}
void setup(){
get_WIFI();
}
void loop(){
get_weather();
Serial.println("now_address:");
Serial.println(now_address);
Serial.println("天气:");
Serial.println(now_weather);
Serial.println("温度:");
Serial.println(now_temperature);
delay(5000);
}
如有错误希望大佬指正!如果对你有帮助,希望能给个赞,写博客不易。