专栏中心

EEPW首页 > 专栏 > Arduino ESP8266可以进行天气预报了

Arduino ESP8266可以进行天气预报了

发布人:Linux嵌入式 时间:2023-01-03 来源:工程师 发布文章

学习完ESP8266的网络相关操作后,就可以做个小实践来巩固所学的知识,同时对网络协议也会更加的理解。

获取天气信息采用的是心知天气提供的API接口,这也是目前比较受大家欢迎的一个平台。该实践的整个流程如下:

1. 进入心知天气官网注册账号,申请免费版本的数据API接口建立自己的项目之后获取秘钥。



2. 找到心知天气的接口文档,了解其请求地址,请求格式以及参数代表的含义,同时对其返回的数据格式进行分析。


3. 对接口了解之后下一步就要进行程序的设计,我们先来看一下实现的流程图,有了流程图之后我们思路就会变的清晰起来。


在向服务器发送数据请求时会用到HTTP的相关知识,在编程前我们先了解一下HTTP协议的相关知识。

HTTP协议又称为超文本传输协议(HyperText Transfer Protocol, HTTP)是分布式、协作式、超媒体系统应用之间的通信协议,是万维网(worldwideweb)交换信息的基础。它允许将超文本标记语言(HTML)文档从Web服务器传送到Web浏览器。HTML是一种用于创建文档的标记语言,这些文档包含相关信息的链接。可以通过单击一个链接来访问其他文档、图像或多媒体对象,并获得关于链接项的附加信息。

在制作Arduino网页服务器或者网页客户端时,需要理解HTTP协议的大原理。HTTP(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,绝大多数的Web开发都是构建在HTTP协议之上Web应用。

当使用浏览器(客户端)访问一个网页时,大致经过了以下三步:

①用户输人****后,浏览器(客户端)会向服务器发出HTTP请求;

②服务器收到请求后会返回HTML形式的文本以响应请求;

③浏览器收到服务器返回的HTML文本后,将文本转换为网页显示出来。

当客户端访问网页时,会先发起HTTP请求。HTTP请求由三部分组成,分别

是请求行、请求报头空行和请求数据,格式如下图所示:


服务器响应消息HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

构造HTTP请求

在心知官方API文档中我们可知我们查询天气时需访问的接口为:请求方法为GET,所以我们在构造请求行是按上面的格式即可:

URL是:

/v3/weather/now.json?key=smtq3n0ixdggurox&location=beijing&language=zh-Hans&unit=c

协议版本为HTTP/1.1请求头部为:

Host:api.seniverse.com\r\n

Connection: keep-alive\r\n

我们只需要这几个,其他的网页和请求设备的描述我们不需要。

服务器返数据处理

当向服务器仿宋数据请求后,服务器会发给我们发送返回的数据,我们需要按照服务器返回的格式解析出数据即可,心知天气返回的数据是JSON格式的,在解析JSON数据时arduino给我们提供了一个JSON解析工具使用起来很方便,可以直接生成代码****为:

,所以我们在网页上访问服务器把返回的JSON格式的数据放在解析工具上即可生成代码,在写程序时,直接把分离JSON格式的数据传进去即可。在使用这个工具时需要注意的是JSON版本号要和Arduino安装的JSON库的版本号是一致的,否则编译会出错。

完整代码如下:

#include <ArduinoJson.h>

#include <ESP8266WiFi.h>

WiFiClient client;

DynamicJsonBuffer jsonBuffer(800);

const char * ssid = "ChinaNet-fbMA";

const char * pwd = "qwertyuiop";

const char * host = "api.seniverse.com";

const int httpPort = 80;

bool bConnected = false;

struct WeatherData {

char city[16];//城市名称

char weather[32];//天气介绍(多云...)

char temp[16];//温度

char udate[32];//更新时间

};

WeatherData weatherData;

const char* json = "{\"results\":[{\"location\":{\"id\":\"WTW3SJ5ZBJUY\",\"name\":\"上海\",\"country\":\"CN\",\"path\":\"上海,上海,中国\",\"timezone\":\"Asia/Shanghai\",\"timezone_offset\":\"+08:00\"},\"daily\":[{\"date\":\"2019-02-11\",\"text_day\":\"多云\",\"code_day\":\"4\",\"text_night\":\"阴\",\"code_night\":\"9\",\"high\":\"7\",\"low\":\"2\",\"precip\":\"\",\"wind_direction\":\"东北\",\"wind_direction_degree\":\"45\",\"wind_speed\":\"10\",\"wind_scale\":\"2\"},{\"date\":\"2019-02-12\",\"text_day\":\"中雨\",\"code_day\":\"14\",\"text_night\":\"小雨\",\"code_night\":\"13\",\"high\":\"9\",\"low\":\"4\",\"precip\":\"\",\"wind_direction\":\"东\",\"wind_direction_degree\":\"90\",\"wind_speed\":\"10\",\"wind_scale\":\"2\"},{\"date\":\"2019-02-13\",\"text_day\":\"小雨\",\"code_day\":\"13\",\"text_night\":\"中雨\",\"code_night\":\"14\",\"high\":\"10\",\"low\":\"7\",\"precip\":\"\",\"wind_direction\":\"东北\",\"wind_direction_degree\":\"45\",\"wind_speed\":\"10\",\"wind_scale\":\"2\"}],\"last_update\":\"2019-02-11T08:00:00+08:00\"}]}";

void setup() {

// put your setup code here, to run once:

Serial.begin(115200);

WiFi.disconnect();

WiFi.mode(WIFI_STA);

WiFi.begin(ssid, pwd);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

Serial.println("");

Serial.println("WiFi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());


}


void loop() {

// put your main code here, to run repeatedly:

String weather_data;

String line;

String url = "/v3/weather/daily.json?key=gske8kcghqz7cqiz&location=zhengzhou&language=zh-Hans&unit=c&start=0&days=3";

// if ( bConnected == false)

// {

if (!client.connect(host, httpPort))

{

Serial.println("connection failed");

delay(5000);

return;

}

bConnected = true;

Serial.println("connection ok");

Serial.print("Requesting URL: ");

Serial.println(url);

// This will send the request to the server

client.print(String("GET ") + url + " HTTP/1.1\r\n" +

"Host: " + host + "\r\n" +

"Connection: close\r\n\r\n");

Serial.print("向服务器发送的数据为:");

Serial.println(String("GET ") + url + " HTTP/1.1\r\n" +

"Host: " + host + "\r\n" +

"Connection: close\r\n\r\n");

delay(100);

// }


while (client.available()) {

line = client.readStringUntil('\r');

weather_data += line;

}

Serial.println(weather_data);

String json_weather_data;

int jsonIndex;


for (int i = 0; i < weather_data.length(); i++) {

if (weather_data[i] == '{') {

jsonIndex = i;

break;

}

}


// Get JSON data

json_weather_data = weather_data.substring(jsonIndex);

Serial.println();

Serial.println("json_weather_data: ");

Serial.println(json_weather_data);


JsonObject& root = jsonBuffer.parseObject(json_weather_data);

if (!root.success())

{

Serial.println("parseObject() failed");

return;

}

else

{

Serial.println("开始解析数据");

JsonObject& results_0 = root["results"][0];

JsonObject& results_0_location = results_0["location"];

const char* results_0_location_name = results_0_location["name"]; // "上海"

const char* results_0_location_country = results_0_location["country"]; // "CN"

const char* upd = results_0["last_update"];


JsonArray& results_0_daily = results_0["daily"];

JsonObject& results_0_daily_0 = results_0_daily[0];

const char* results_0_daily_0_date = results_0_daily_0["date"];

const char*
results_0_daily_0_text_day = results_0_daily_0["text_day"]; // "多云"

const char*
results_0_daily_0_text_night = results_0_daily_0["text_night"]; // "阴

const char* results_0_daily_0_high = results_0_daily_0["high"]; // "7"

const char* results_0_daily_0_low = results_0_daily_0["low"]; // "2"

const char*
results_0_daily_0_wind_direction = results_0_daily_0["wind_direction"]; // "东北"


Serial.println(results_0_location_name);

Serial.println(results_0_daily_0_date);

Serial.println(results_0_daily_0_text_day);

Serial.println(results_0_daily_0_text_night);

Serial.println(results_0_daily_0_high);

Serial.println(results_0_daily_0_low);

Serial.println(results_0_daily_0_wind_direction);


Serial.println(upd);

}

client.stop();

weather_data="";

Serial.println("closing connection");

delay(10000);

}


专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词: Arduino ESP8266

相关推荐

ArduinoISP, Hex & Bootloader

视频 2013-07-26

Arduino硬件模拟器 vs 实物零件:哪个更合适?

3D8S的“脱机运行”

视频 2013-07-26

使用Arduino和EMG的错误姿势和肌肉拉伤监测器,带实时蓝牙警报

动手玩转Arduino

Arduino最全的中文教程

高通收购Arduino带来了全新的氛围——UNO Q上的人工智能与信号处理

基于Arduino的双模科学计算器设计

二十年过去 Arduino已经远不止是Arduino了

什么是 Linduino

视频 2014-10-23

动手玩转Arduino

Arduino的教程

资源下载 2012-11-24

1 物联网与嵌入式开发

视频 2015-07-07

在 Ubuntu 12.04 上安装 Arduino IDE

视频 2013-07-26

基于arduino开发板的网络独立下载终端

高通收购Arduino,开源社区持怀疑态度

嵌入式系统 2025-11-03

高通收购硬件公司Arduino,深耕机器人领域

机器人 2025-10-10

Arduino UNO Q登陆DigiKey,现已开放预订

基于Portenta的农业和草坪管理

更多 培训课堂
更多 焦点
更多 视频

技术专区