EPS32实操之【获取网络请求】
1.实现效果
实现一个访问查询实时天气的一个功能,通过串口发送查询指令然后能够查询当前的实时天气,并且通过串口打印出来。具体实现是通过获取网络请求这个功能来实现的。
需要用到一个拉取天气的API,这里使用的是“聚合数据”免费的API,如下所示
具体的申请方法很简单,这里不再赘述,我们可以先测试一下这个API
,直接点击测试
,然后进入测试
可以看到,我们返回了一个JSON
文件,我们通过解析这个文件,就能得到我们需要查询的内容。
2.WiFi连接API
首先我们要让ESP32
开发板能够连接上Wifi,
Arduino 已经集成了 Wi-Fi 模块,因此我们可以直接使用该模块。模块包含热点 AP 模式和客户端 STA 模式,热点 AP 是指电脑或手机端直接连接 ESP32 发出的热点实现连接,如果电脑连接模块 AP 热点,这样电脑就不能上网,因此在使用电脑端和模块进行网络通信时,一般情况下都是使用 STA 模式。也就是电脑和设备同时连接到相同网段的路由器上。下面是一些 ESP32 Arduino 库中常用的 Wi-Fi 相关函数的介绍:
WiFi.begin(ssid, password)
:该函数用于连接到 Wi-Fi 网络。需要提供要连接的网络的 SSID 和密码作为参数。WiFi.disconnect()
:该函数用于断开当前的 Wi-Fi 连接。WiFi.status()
:该函数返回当前 Wi-Fi 连接的状态。返回值可能是以下之一:WL_CONNECTED
:已连接到 Wi-Fi 网络。WL_DISCONNECTED
:未连接到 Wi-Fi 网络。WL_IDLE_STATUS
:Wi-Fi 处于空闲状态。WL_NO_SSID_AVAIL
:未找到指定的 Wi-Fi 网络。
WiFi.localIP()
:该函数返回 ESP32 设备在 Wi-Fi 网络中分配的本地 IP 地址。WiFi.macAddress()
:该函数返回 ESP32 设备的 MAC 地址。WiFi.scanNetworks()
:该函数用于扫描周围可用的 Wi-Fi 网络。它返回一个整数,表示扫描到的网络数量。可以使用其他函数(如WiFi.SSID()
和WiFi.RSSI()
)来获取每个网络的详细信息。WiFi.SSID(networkIndex)
:该函数返回指定索引的扫描到的 Wi-Fi 网络的 SSID。WiFi.RSSI(networkIndex)
:该函数返回指定索引的扫描到的 Wi-Fi 网络的信号强度(RSSI)。
3.HTTP请求API
当我们在浏览器中输入网址或者使用应用程序时,我们实际上是向服务器发出请求。HTTP 请求是客户端(如浏览器)与服务器之间通信的方式,用于获取或发送 Web 资源。这些资源可以是文本文件、图像、脚本等,客户端通过 HTTP 协议发起请求,服务器返回相应的响应。HTTP 请求通常由以下几个部分组成:请求行:包含请求方法、请求 URL 和 HTTP 协议版本,例如
GET https://www.baidu.com/content-search.xml HTTP/1.1
GET
是请求方法,https://www.baidu com/
是 URL 地址,HTTP/1.1
指定了协议版本。HTTP 协议版本一般都是 HTTP/1.1
,URL 是你要访问的地址,而请求方法除了 GET 还有 POST、PUT、DELETE 经常使用的 4 个请求方式,以及一些其他的请求方法。请求头:包含与请求相关的信息,例如浏览器类型、请求时间等。请求体:包含请求所需的数据。我们虽然可以对任意网址发送网络请求,但是这样毫无意义,比如,我想要获取某个地区的天气状况,就需要调用相对应的接口,也就是 API。
想要发送 HTTP 请求,我们就需要用到 HTTPClient 库。HTTPClient 库是一个用于 Arduino 的 HTTP 客户端库,它提供了一组函数来轻松地发送 HTTP 请求并处理服务器响应。HTTPClient 库基于 ESP-IDF 的 HTTP 客户端实现,并在Arduino框架下进行了封装,使其易于使用。以下是 HTTPClient 库的一些常用功能和函数:
HTTPClient http
;:创建 HTTPClient 对象。http.begin(url)
:指定要发送请求的 URL。http.addHeader(name, value)
:添加 HTTP 头部。http.setAuthorization(username, password)
:设置 HTTP 基本身份验证的用户名和密码。http.setTimeout(timeout):设置请求超时时间(以毫秒为单位)。http.GET()
:发送 GET 请求,并返回一个 HTTP 状态码。http.POST(payload)
:发送 POST 请求,并将 payload 作为请求正文。http.responseStatusCode()
:获取响应的状态码。http.responseHeaders()
:获取响应的头部。http.responseBody()
:获取响应的正文。http.getString()
:获取响应正文作为字符串。http.getStream()
:获取响应正文作为流对象。http.end()
:关闭连接并释放资源。我们从 Web 服务获取的是 JSON 数据,要想解析 JSON 数据,可以使用 Arduino 的ArduinoJSON
库。ArduinoJSON
库使您能够解析和生成 JSON 数据,以及在 Arduino 上处理 JSON 格式的数据。
4.实现天气拉取
明白了上述的预备知识,我们就可以编写程序了,main.cpp
的内容如下
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "T-CPE1250S-4A7A";
const char* password = "9876543210";
// 定义
String url = "http://apis.juhe.cn/simpleWeather/query";
String city = "你想查询的城市名称";
String key = "你申请的API Key";
void wifi_connect(){
// 连接 WiFi
WiFi.begin(ssid, password);
Serial.print("正在连接 Wi-Fi");
// 检测是否连接成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("连接成功");
Serial.print("IP 地址:");
Serial.println(WiFi.localIP());
}
void get_weather_once() {
// 创建 HTTPClient 对象
HTTPClient http;
// 发送GET请求
http.begin(url + "?city=" + city + "&key=" + key);
// 发送请求并获取响应
int httpCode = http.GET();
// 处理响应
if (httpCode == HTTP_CODE_OK) {
// 获取响应正文
String response = http.getString();
Serial.println("响应数据");
Serial.println(response);
// 创建 DynamicJsonDocument 对象
DynamicJsonDocument doc(1024);
// 解析 JSON 数据
deserializeJson(doc, response);
// 从解析后的 JSON 文档中获取值
unsigned int temp = doc["result"]["realtime"]["temperature"].as<unsigned int>();
String info = doc["result"]["realtime"]["info"].as<String>();
int aqi = doc["result"]["realtime"]["aqi"].as<int>();
String wind_dirct = doc["result"]["realtime"]["direct"].as<String>();
String wind_power = doc["result"]["realtime"]["power"].as<String>();
Serial.printf("温度: %d\n", temp);
Serial.printf("天气: %s\n", info);
Serial.printf("空气指数: %d\n", aqi);
Serial.printf("风向: %s, 风力: %s \n", wind_dirct.c_str(), wind_power.c_str());
}
else {
Serial.printf("HTTP 请求失败,错误码: %d\n", httpCode);
}
}
void setup() {
Serial.begin(9600);
wifi_connect();
}
void loop() {
// 检查是否有可用的串口输入数据
if (Serial.available() > 0) {
// 读取串口输入数据
String input = Serial.readString();
// 根据需要处理输入数据,例如判断指令或参数等
input.trim();
if (input == "query"){ // 串口输入quer,则读取一次当前天气
// 调用获取天气的函数
get_weather_once();
}
}
}
最后我们打开串口监视器,输入query
,然后就能查询一次天气结果了,效果如下: