Arduino+ESP32SSD1306 OLED显示图像和天气

目录

硬件电路部分

一、材料清单:

二、接线图

软件编写部分

一、获取天气

(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);

  
}

大功告成啦!!感谢观看!!