目录
硬件电路部分
一、材料清单:
二、接线图
软件编写部分
一、获取天气
(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); }
大功告成啦!!感谢观看!!