目录
硬件电路部分
一、材料清单:
二、接线图
软件编写部分
一、获取天气
(1)连接WiFi
(2)发送HTTP请求
(3)解析JSON数据
二、OLED显示
硬件电路部分
一、材料清单:
ESP32
SSD1306 OLED显示屏
面包板
杜邦线
二、接线图

GND--->GND
VCC--->VIN
D0--->D14
D1--->D27
RES--->D26
DC--->D25
CS--->D33
软件编写部分
一、获取天气
(1)连接WiFi
想要获取某地区的实时天气,需要先让ESP32联网。
可以连接手机热点,有木有连上一目了然 ^u^
/* 包含Arduino自带的头文件WiFi.h */
#include <WiFi.h>
const char* ssid = "WiFi名";
const char* password = "WiFi密码";
void setup()
{
/* 开始连接WiFi */
WiFi.begin(ssid,password);
/* 等待WiFi连接成功*/
while(WiFi.status()!=WL_CONNECTED){};
}
void loop()
{}
连接成功后就可以通过发送HTTP请求来获取实时天气数据啦!!
(2)发送HTTP请求
这里向高德的API接口发送HTTP请求。首先注册一个账号并申请Key,然后根据文档中提供的URL、请求方式及参数发送请求。

/* Arduino自带头文件 */
#include <WiFi.h>
/* Arduino自带头文件 */
#incldue <HTTPClient.h>
const char* ssid = "这里填写WiFi名";
const char* password = "这里填写WiFi密码";
/* 将文档中的URL以及请求参数保存到变量中
注意删除"?parameters",以便填写请求参数 */
String url = "https://restapi.amap.com/v3/weather/weatherInfo";
// 北京市东城区的adcode
String adcode = "110101";
String key = "这里填写你申请到的Key";
String extensions = "base";
String output = "JSON";
void setup()
{
/* 开始连接WiFi */
WiFi.begin(ssid,password);
/* 等待WiFi连接成功*/
while(WiFi.status()!=WL_CONNECTED){};
/* 创建 HTTPClient 对象 */
HTTPClient http;
/* 指定要发送请求的URL */
http.begin(url+"city="+adcode+"&key="+key+"&extensions="+extensions+"&output="+output);
/* GET请求,函数返回状态码 */
int http_code=http.GET();
/* 获取响应数据的字符串格式 */
String response=http.getString();
/* 关闭连接 */
http.end();
}
void loop()
{}
(3)解析JSON数据
此时获取的响应数据是JSON格式,而且是全部的数据,所以我们还需要对获取到的数据进行一些处理。 那么什么是JSON格式呢?(请看下面这篇博客了解详情^ ^
JSON简介与解析方法(超级详细)-CSDN博客
所以我们需要从JSON键值对中获取它最关键的“值”!!
那如果我们只想获取lives对象下的province、city、 weather和temperature的值该怎么做呢?

简单来说就是添加库“ArduinoJson”,然后创建对象存储需要解析的JSON数据

/* 需要的响应数据 */
String province; //省份
String city; //城市
String weather; //天气
String temperature; //温度
/* Arduino自带头文件 */
#include <WiFi.h>
/* Arduino自带头文件 */
#incldue <HTTPClient.h>
/* 需要下载的头文件 */
#include <ArduinoJson.h>
const char* ssid = "这里填写WiFi名";
const char* password = "这里填写WiFi密码";
/* 将文档中的URL以及请求参数保存到变量中
注意删除"?parameters",以便填写请求参数 */
String url = "https://restapi.amap.com/v3/weather/weatherInfo";
String adcode = "110101";
String key = "这里填写你申请到的Key";
String extensions = "base";
String output = "JSON";
/* 需要的响应数据 */
String province;
String city;
String weather;
String temperature;
void setup()
{
/* 开始连接WiFi */
WiFi.begin(ssid,password);
/* 等待WiFi连接成功*/
while(WiFi.status()!=WL_CONNECTED){};
/* 创建 HTTPClient 对象 */
HTTPClient http;
/* 指定要发送请求的URL */
http.begin(url+"city="+adcode+"&key="+key+"&extensions="+extensions+"&output="+output);
/* GET请求,函数返回状态码 */
int http_code=http.GET();
/* 获取响应数据的字符串格式 */
String response=http.getString();
/* 关闭连接 */
http.end();
/* 创建 DynamicJsonDocument 对象 */
DynamicJsonDocument doc(1024);
/* 解析Json 数据 */
deserializeJson(doc,response);
// 用串口打印数据会发现lives是一个数组,[0]是数组下标
province=doc["lives"][0]["province"].as<String>();
city=doc["lives"][0]["city"].as<String>();
weather=doc["lives"][0]["weather"].as<String>();
temperature=doc["lives"][0]["temperature"].as<String>();
}
void loop()
{}
好啦!!这下终于完成获取天气部分啦!! ^ ^
二、OLED显示
为了方便显示汉字,OLED显示采用U8G2库。首先添加库

注意根据自己的OLED型号选择正确的构造器,我使用的是U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI (SSD1306芯片,大小128*64,四线,SPI通信)
通常,使用以下框架控制OLED显示
oled.begin(); //初始化
oled.clearBuffer(); // 清空显示缓冲区
/* 绘制图形、显示英文数字等 */
oled.sendBuffer(); // 显示缓冲区内容
如果要显示汉字则需要使能UTF8,设置能显示汉字的字体
oled.begin(); //初始化
oled.enableUTF8Print();
oled.setFont(u8g2_font_wqy12_t_gb2312); //设置字体
oled.setFontDirection(0); //设置字体方向
oled.clearBuffer(); // 清空显示缓冲区
/* 绘制图形、显示汉字、英文和数字等 */
oled.sendBuffer(); // 显示缓冲区内容
/* Arduino自带头文件 */
#include <WiFi.h>
/* Arduino自带头文件 */
#incldue <HTTPClient.h>
/* 需要下载的头文件 */
#include <ArduinoJson.h>
#include <U8g2lib.h>
#define D0 14
#define D1 27
#define RES 26
#define DC 25
#define CS 33
const char* ssid = "这里填写WiFi名";
const char* password = "这里填写WiFi密码";
/* 将文档中的URL以及请求参数保存到变量中
注意删除"?parameters",以便填写请求参数 */
String url = "https://restapi.amap.com/v3/weather/weatherInfo";
String adcode = "110101";
String key = "这里填写你申请到的Key";
String extensions = "base";
String output = "JSON";
/* 需要的响应数据 */
String province;
String city;
String weather;
String temperature;
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI oled(U8G2_R0,D0,D1,CS,DC,RES);
void setup()
{
/* 开始连接WiFi */
WiFi.begin(ssid,password);
/* 等待WiFi连接成功*/
while(WiFi.status()!=WL_CONNECTED){};
/* 创建 HTTPClient 对象 */
HTTPClient http;
/* 指定要发送请求的URL */
http.begin(url+"city="+adcode+"&key="+key+"&extensions="+extensions+"&output="+output);
/* GET请求,函数返回状态码 */
int http_code=http.GET();
/* 获取响应数据的字符串格式 */
String response=http.getString();
/* 关闭连接 */
http.end();
/* 创建 DynamicJsonDocument 对象 */
DynamicJsonDocument doc(1024);
/* 解析Json 数据 */
deserializeJson(doc,response);
// 用串口打印数据会发现lives是一个数组,[0]是数组下标
province=doc["lives"][0]["province"].as<String>();
city=doc["lives"][0]["city"].as<String>();
weather=doc["lives"][0]["weather"].as<String>();
temperature=doc["lives"][0]["temperature"].as<String>();
/*--------------------------OLED显示部分----------------------------------*/
oled.begin();
oled.enableUTF8Print();
}
void loop()
{
oled.setFont(u8g2_font_wqy12_t_gb2312);
oled.setFontDirection(0);
oled.clearBuffer();
oled.setCursor(10,15);
oled.printf("城市:%s %s",province,city);
oled.setCursor(10,35);
oled.printf("天气:%s",weather);
oled.setCursor(10,55);
oled.printf("温度:%s C",temperature);
oled.sendBuffer();
delay(100);
}

恭喜!!成功显示实时天气啦!(^ ^) 接下来设计一个过场小动画吧!!(其实就是小进度条、、)
首先下载一个取模软件将你想要显示的图像保存为数组


将它用到之前我们提到的框架里面就好啦
/* Arduino自带头文件 */
#include <WiFi.h>
/* Arduino自带头文件 */
#incldue <HTTPClient.h>
/* 需要下载的头文件 */
#include <ArduinoJson.h>
#include <U8g2lib.h>
#define D0 14
#define D1 27
#define RES 26
#define DC 25
#define CS 33
const char* ssid = "这里填写WiFi名";
const char* password = "这里填写WiFi密码";
/* 将文档中的URL以及请求参数保存到变量中
注意删除"?parameters",以便填写请求参数 */
String url = "https://restapi.amap.com/v3/weather/weatherInfo";
String adcode = "110101";
String key = "这里填写你申请到的Key";
String extensions = "base";
String output = "JSON";
/* 需要的响应数据 */
String province;
String city;
String weather;
String temperature;
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI oled(U8G2_R0,D0,D1,CS,DC,RES);
const unsigned char b2[]={
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XE0,0X0F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3E,0XE0,0X03,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0X01,0X00,0X3C,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X60,0X00,0X00,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X18,0X00,0X00,0X80,0X03,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X0C,0X00,0X00,0X00,0X06,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0XF8,0X07,0X00,0X00,0X00,0X08,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0XFC,0X01,0X00,0X00,0X00,0X30,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0XFC,0X00,0X00,0X00,0X00,0X60,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0XFC,0X00,0X00,0X00,0X00,0XC0,0X07,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,0X80,0X3F,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X7F,0X00,0X00,0X00,0X00,0X00,0X7F,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X80,0X3F,0X00,0X00,0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X40,0X3E,0X00,0X00,0X00,0X00,0X00,0X76,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X60,0X3F,0X00,0X00,0X00,0X00,0X00,0X7C,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X20,0X1F,0X00,0X00,0X00,0X00,0X00,0XFC,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X30,0X1F,0X00,0X00,0X00,0X00,0X00,0XF8,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X10,0X1F,0X00,0X00,0X00,0X00,0X00,0XF0,0X01,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X18,0X1F,0X00,0X30,0X00,0X00,0X00,0XF0,0X03,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X08,0X0F,0X00,0X30,0X00,0X00,0X00,0XE0,0X03,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X0C,0X0F,0X00,0X38,0X00,0X00,0X00,0XE0,0X07,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X04,0X0F,0X00,0X34,0X00,0X20,0X00,0XC0,0X05,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X06,0X0F,0X00,0X16,0X00,0X70,0X00,0XC0,0X05,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X02,0X0E,0X00,0X11,0X00,0X50,0X00,0X80,0X08,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X03,0X0F,0X80,0X11,0X00,0XD0,0X00,0X80,0X08,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X01,0X07,0X40,0X10,0X00,0XF8,0X00,0X80,0X19,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X01,0X07,0X60,0X10,0X00,0X8C,0X00,0X00,0X11,0X00,0X00,0X00,
0X00,0X00,0X00,0X80,0X01,0X07,0X30,0X10,0X00,0X84,0X00,0X04,0X11,0X00,0X00,0X00,
0X00,0X00,0X00,0X80,0X80,0X07,0X18,0X10,0X00,0X06,0X01,0XFC,0X11,0X00,0X00,0X00,
0X00,0X00,0X00,0XC0,0X80,0X07,0X0C,0X10,0X00,0X03,0X01,0XFC,0X21,0X00,0X00,0X00,
0X00,0X00,0X00,0X40,0X80,0X07,0X06,0X10,0X00,0X01,0X01,0X3C,0X20,0X00,0X00,0X00,
0X00,0X00,0X00,0X40,0X80,0X07,0X01,0X10,0X80,0X00,0X02,0X3E,0X20,0X00,0X00,0X00,
0X00,0X00,0X00,0X60,0X80,0X87,0XC0,0X10,0XC0,0X00,0X02,0X1E,0X60,0X00,0X00,0X00,
0X00,0X00,0X00,0X20,0X80,0XE7,0XC0,0X10,0X60,0X00,0X06,0X1E,0X40,0X00,0X00,0X00,
0X00,0X00,0X00,0X30,0X00,0XB7,0XC0,0X10,0X30,0X08,0X04,0X1E,0X40,0X00,0X00,0X00,
0X00,0X00,0X00,0X10,0X00,0X9F,0XE0,0X10,0X18,0X1C,0X04,0X1E,0X40,0X00,0X00,0X00,
0X00,0X00,0X00,0X10,0X00,0X9F,0XE0,0X10,0X06,0X1C,0X0C,0X1F,0X40,0X00,0X00,0X00,
0X00,0X00,0X00,0X18,0X00,0X9E,0XE0,0XF0,0X03,0X1C,0X0C,0X0F,0XC0,0X00,0X00,0X00,
0X00,0X00,0X00,0X08,0X00,0X9E,0X40,0X60,0X00,0X1C,0X0C,0X0F,0X80,0X00,0X00,0X00,
0X00,0X00,0X00,0X0C,0X00,0X98,0X00,0X00,0X00,0X1C,0X8C,0X0F,0X80,0X00,0X00,0X00,
0X00,0X00,0X00,0X04,0X00,0X90,0X00,0X00,0X00,0X0C,0X9C,0X07,0X80,0X00,0X00,0X00,
0X00,0X00,0X00,0X04,0X00,0XB0,0X01,0X00,0X00,0X0C,0XB4,0X07,0X80,0X01,0X00,0X00,
0X00,0X00,0X00,0X06,0X00,0XB0,0X03,0X70,0X00,0X00,0XE6,0X03,0X00,0X01,0X00,0X00,
0X00,0X00,0X00,0X02,0X00,0XB0,0X06,0XD8,0X0F,0X00,0XE2,0X01,0X00,0X01,0X00,0X00,
0X00,0X00,0X00,0X02,0X00,0XF0,0X08,0X18,0X18,0X00,0XF2,0X00,0X00,0X01,0X00,0X00,
0X00,0X00,0X00,0X03,0X00,0X50,0X30,0X10,0X08,0X00,0X93,0X00,0X00,0X01,0X00,0X00,
0X00,0X00,0X00,0X01,0X00,0X10,0XC0,0XE0,0X07,0X80,0X8B,0X00,0X00,0X03,0X00,0X00,
0X00,0X00,0X00,0X01,0X00,0X10,0X80,0X0F,0X00,0X60,0X8D,0X00,0X00,0X02,0X00,0X00,
0X00,0X00,0X80,0X00,0X00,0X10,0XF0,0X78,0X00,0X0E,0X85,0X00,0X00,0X02,0X00,0X00,
0X00,0X00,0X80,0X00,0X00,0X10,0X58,0X80,0XFF,0X0D,0X83,0X00,0X00,0X02,0X00,0X00,
0X00,0X00,0X80,0X00,0X00,0X10,0XC4,0X80,0X80,0X11,0X81,0X00,0X00,0X02,0X00,0X00,
0X00,0X00,0X40,0X00,0X00,0X10,0XC6,0XC1,0X41,0X21,0X80,0X00,0X00,0X02,0X00,0X00,
0X00,0X00,0X40,0X00,0X00,0X10,0X23,0X63,0X63,0X63,0X80,0X00,0X00,0X06,0X00,0X00,
0X00,0X00,0X60,0X00,0X00,0X10,0X21,0X3E,0X1E,0XC2,0X80,0X00,0X00,0X04,0X00,0X00,
0X00,0X00,0X20,0X00,0X00,0X90,0X20,0X38,0X0E,0X82,0X80,0X00,0X00,0X04,0X00,0X00,
0X00,0X00,0X20,0X00,0X00,0XD0,0X31,0XF0,0X03,0X82,0X81,0X00,0X00,0X04,0X00,0X00,
0X00,0X00,0X30,0X00,0X00,0X70,0X13,0X18,0X06,0XC4,0X82,0X00,0X00,0X04,0X00,0X00,
0X00,0X00,0X10,0X00,0X00,0XF0,0X16,0X18,0X04,0X64,0X87,0X00,0X00,0X0C,0X00,0X00,
0X00,0X00,0X10,0X00,0X00,0XF8,0X0D,0X08,0X04,0XB4,0X8F,0X00,0X00,0X08,0X00,0X00,
0X00,0X00,0X18,0X00,0X00,0XFC,0X0B,0X0C,0X0C,0XD8,0X9F,0X00,0X00,0X18,0X00,0X00,
0X00,0X00,0X18,0X00,0X00,0XFE,0X0F,0X0C,0X08,0XE8,0XBF,0X00,0X00,0X10,0X00,0X00,
};
void setup()
{
/* 开始连接WiFi */
WiFi.begin(ssid,password);
/* 等待WiFi连接成功*/
while(WiFi.status()!=WL_CONNECTED){};
/* 创建 HTTPClient 对象 */
HTTPClient http;
/* 指定要发送请求的URL */
http.begin(url+"city="+adcode+"&key="+key+"&extensions="+extensions+"&output="+output);
/* GET请求,函数返回状态码 */
int http_code=http.GET();
/* 获取响应数据的字符串格式 */
String response=http.getString();
/* 关闭连接 */
http.end();
/* 创建 DynamicJsonDocument 对象 */
DynamicJsonDocument doc(1024);
/* 解析Json 数据 */
deserializeJson(doc,response);
// 用串口打印数据会发现lives是一个数组,[0]是数组下标
province=doc["lives"][0]["province"].as<String>();
city=doc["lives"][0]["city"].as<String>();
weather=doc["lives"][0]["weather"].as<String>();
temperature=doc["lives"][0]["temperature"].as<String>();
/*--------------------------OLED显示部分----------------------------------*/
oled.begin();
oled.enableUTF8Print();
// 要是想偷偷给自己开vip,就将i++改为i+=10 *笑*
for(int i=0;i<=104;i++)
{
oled.clearBuffer(); // 清空显示缓冲区
// (0,0)表示图像左上角在(0,0)的位置,128是从左到右的长度,64是从上到下的高度
oled.drawXBMP(0,0,128,64,b2);
// 画进度条框架
oled.drawFrame(10,40,108,15);
// 将计数器i作为实心长方形的长度,每次增加 1
oled.drawBox(12,42,i,11);
oled.sendBuffer(); // 显示缓冲区内容
}
}
void loop()
{
oled.setFont(u8g2_font_wqy12_t_gb2312);
oled.setFontDirection(0);
oled.clearBuffer();
oled.setCursor(10,15);
oled.printf("城市:%s %s",province,city);
oled.setCursor(10,35);
oled.printf("天气:%s",weather);
oled.setCursor(10,55);
oled.printf("温度:%s C",temperature);
oled.sendBuffer();
delay(100);
}
大功告成啦!!感谢观看!!