基于ESP32-S2模块制作天气时钟
使用esp32-S2进行oled显示、wifi连接、时间天气获取
标签
嵌入式系统
显示
网络与通信
2022寒假在家练
qiqiqi
更新2022-03-04
福州大学
2223

项目介绍

本次完成的项目为2022寒假在家练中的项目6制作一个本地气象台/温度计,利用OLED显示,显示当前本地的时间、温度和气象信息

设计思路(框图)

初始化

FiAXxlvukzl4RTWgYeyYT-WXa0d5

主循环

Fp-fXig3-taOOGEPN4HE_zLafytr

按键扫描

FhFb6CKFJIoz-gXUhIDcZNHTbShq

简单的硬件介绍

ESP32-S2-MINI-1:采用PCB板载天线,配置4MB SPI flash,采用的 ESP32-S2FN4 芯片。

使用4个按键采用上拉电阻,分别对应io1、io2、io3、io6四个io口

Fg59AHfVSADicZ6D_dmhYEFhrBo3FnwRhTF5PBeTFlmCdt-TqWUmEjnA

oled屏幕使用io33、io34、io35、io36四个io口

Fu5cwU3l7_1bX-ggzupOhQ4VFH2sFhxhxmDxDuBDYNtwpbzLANNTRKcg

实现的功能及图片展示

WIFI连接:

 

FrZun2VzoQzsxQpbWnN18TLfkz5G

时间显示:

FrOciBM_XPuQFkyTHWlhKeMl-Fc-

当前天气显示:Flo7ekn50UH-xRGTu3k7V0PWz4MJ

天气预报:

Fgz3GKL-digRQQIgbl1uhg9y99Ll

数据更新:

Fri3s3dTgtge8Qg_vpKGVsRddzkh

主要代码片段及说明

调用头文件,初始化变量。这部分主要是使用一些arduino的库,以及制作用于显示的字库和图库。

#include <WiFi.h>
#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <ArduinoJson.h>
WiFiClient client;

//时间日期更新
#define NTP1  "ntp1.aliyun.com"
#define NTP2  "ntp2.aliyun.com"
#define NTP3  "ntp3.aliyun.com"

U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ 10, /* dc=*/ 33, /* reset=*/ 34);
//天气图库
static const unsigned char PROGMEM tianqi[][480] ={};
//字库
static const unsigned char PROGMEM zifu[][32] ={};
//℃
static const unsigned char PROGMEM wendu[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x48,0xF8,0x01,0x48,0x0C,0x16,0x48,0x06,0x18,0x30,0x03,0x18,0x00,0x01,0x10,0x80,0x01,0x10,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x00,0x01,0x00,0x00,0x03,0x00,0x00,0x03,0x08,0x00,0x06,0x04,0x00,0x1C,0x03,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//填写WIFI入网信息
const char* ssid     = "Tenda_VIP";     // WIFI账户
const char* password = "ldm65098"; // WIFI密码

//心知天气连接数据
String City = "quanzhou";//城市
String My_Key = "S5X21lPnr_Rnl4SH7";//密码
const IPAddress host(116,62,81,138);//心知天气IP地址
uint16_t port=80;//端口号
String get_date="";  //接收到的数据
String inputTime=""; //整理完的数据

//三天天气
String url_1 = "/v3/weather/daily.json?key=" + My_Key +"&location=" + City + "&language=zh-Hans&unit=c&start=-1&days=5";//请求URL
String urlDat_1 = "key=" + My_Key +"&location=" + City + "&language=zh-Hans&unit=c&start=-1&days=5";//请求数据
//当前天气
String url_2 = "/v3/weather/now.json?key=" + My_Key +"&location=" + City + "&language=zh-Hans&unit=c";//请求URL
String urlDat_2 = "key=" + My_Key +"&location=" + City + "&language=zh-Hans&unit=c";//请求数据

//天气数据
//今天
int day_0_code_day;
int day_0_code_night;
int day_0_high;
int day_0_low;
//明天
int day_1_code_day;
int day_1_code_night;
int day_1_high;
int day_1_low;
//后天
int day_2_code_day;
int day_2_code_night;
int day_2_high;
int day_2_low;
//当前天气
int now_code_day;
int now_temperature;

//模式
int Mode=1;
int Mode_3=0;
//按键
int KEY_UP;
int KEY1=1;
int KEY2=1;
unsigned int timenow;//当前时间
unsigned int timelast;//定时更新时间
int i=0;
int change=0;

程序初始化,连接网络,然后从心知天气api获取所需的天气数据。

void setup() {
  u8g2.begin();   //选择U8G2模式
  Serial.begin(115200);   //初始化调试串口
  //初始化按键
  pinMode(1,INPUT);
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(6,INPUT);
  Serial.println();
  //WIFI连接
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while(WiFi.status()!=WL_CONNECTED)
  {
    u8g2.clearBuffer();         // 清除内部缓冲区
    u8g2.setFont(u8g2_font_ncenB12_tf); // choose a suitable font
    u8g2.drawStr(0,20,"Connecting...");
    u8g2.sendBuffer();
    Serial.println("连接中...");
    delay(400);
  }
  u8g2.clearBuffer();         // 清除内部缓冲区
  u8g2.setFont(u8g2_font_ncenB14_tf); // choose a suitable font
  u8g2.drawStr(4,40,"Connected!");
  u8g2.sendBuffer();
  Serial.println("WiFi connected!");
  //获取时间
  configTime(8*3600,0,NTP1,NTP2,NTP3);
  //获取天气
  get_weather(url_1,urlDat_1);
  get_weather(url_2,urlDat_2);
  delay(100);
}

程序主循环,四个按键实现6种功能,按键1为当前时间日期显示;按键2为城市的当前天气;按键3为今明后3天的天气预报,按下切换;按键4为数据更新,理论上数据5分钟更新一次,但按下按键4可以对数据立即更新。

void loop() {
  if((millis()-timelast)>=300000)//5分钟更新一次天气数据
  {
    timelast=millis();
    get_weather(url_1,urlDat_1);
    get_weather(url_2,urlDat_2);
  }
  scan_key();//按键扫描
  //模式实现
  if(Mode==1){
    if((millis()-timenow)>=1000)//1s
    {
      u8g2.clearBuffer();         // 清除内部缓冲区
      timenow=millis();
      draw_time();
      u8g2.sendBuffer();   
    }
  }
  else if(Mode==3){
    if((millis()-timenow)>=5000)//5s
    {
      timenow=millis();
      mode_3();
    }
  }
  //u8g2.drawStr(0,20,"This is EHANG!");
  delay(20);  
}

按键扫描。可能因为冬天天气导致静电较多,因此使用按键中断常常导致按下一次按键程序却识别多次且随机性重启。因为程序功能对实时性要求不强,所以使用按键扫描。当按键按下后识别低电平,只有系统再次识别到高电平才能使下次识别到的低电平有效,实现按下一次识别一次,避免按键3因识别次数不对导致显示错误。

void scan_key()
{
  if(digitalRead(1)&&digitalRead(2)&&digitalRead(3)&&digitalRead(6))//按键复位
  {
    delay(20);
    if(digitalRead(1)&&digitalRead(2)&&digitalRead(3)&&digitalRead(6))
      KEY_UP=1;
  }
  else
  {
    if(KEY_UP)
    {
      delay(20);
      if(digitalRead(1)==0)//当前时间
      {
        KEY1=1;
        Mode=1;
        timenow=0;
        Serial.println(1);
      }
      else if(digitalRead(2)==0)//当前天气
      {
        KEY2=1;
        Mode=2;
        mode_2();
        timenow=0;
        Serial.println(2);
      }
      else if(digitalRead(3)==0)//今、明、后天选择
      {
        Mode=3;
        change=1;
        Serial.println("3");
        Mode_3++;
        if(Mode_3>2)
        Mode_3=0;
        if(KEY1==1||KEY2==1)
        {
          KEY1=0;
          KEY2=0;
          Mode_3=0;
        }
        timenow=0;
        Serial.println(Mode_3);
      }
      else if(digitalRead(6)==0)//数据更新
      {
        u8g2.clearBuffer();         // 清除内部缓冲区
        u8g2.setFont(u8g2_font_ncenB14_tf); // choose a suitable font
        u8g2.drawStr(16,40,"Updating!");
        u8g2.sendBuffer();
        get_weather(url_1,urlDat_1);
        get_weather(url_2,urlDat_2);
        timenow=0;
        Serial.println(4);
        delay(300);  
        mode_2();
      }
      KEY_UP=0;
    }
  }
}

模式2——当前天气

void mode_2()
{
  u8g2.clearBuffer();         // 清除内部缓冲区
  u8g2.setFont(u8g2_font_ncenB24_tf); 
  draw_weather(now_code_day);
  u8g2.setCursor(62, 25);  //
  u8g2.print(now_temperature);   
  u8g2.drawXBMP(100,0,24,24,wendu);
  u8g2.drawXBMP(61+16,30,16,16,zifu[57]);//泉
  u8g2.drawXBMP(61+32,30,16,16,zifu[58]);//州
  u8g2.sendBuffer();  
}

模式3—— 今、明、后天天气

void mode_3()
{
//  get_weather();
  u8g2.clearBuffer();         // 清除内部缓冲区
  u8g2.setFont(u8g2_font_ncenB12_tf); 
  //显示
  if(change)
  {
  //(今)天白天
    u8g2.drawXBMP(61+16,32,16,16,zifu[45]);//天
    u8g2.drawXBMP(61+32,32,16,16,zifu[46]);//白
    u8g2.drawXBMP(61+48,32,16,16,zifu[45]);//天
  //最低温
    u8g2.drawXBMP(70,0,16,16,zifu[48]);
    u8g2.drawXBMP(70+16,0,16,16,zifu[50]);
    u8g2.drawXBMP(70+32,0,16,16,zifu[51]);
    if(Mode_3==0)
    {
    u8g2.drawXBMP(61,32,16,16,zifu[42]);//今
    //温度
      u8g2.setCursor(70, 30);  //
      u8g2.print(day_0_low);   
      u8g2.drawXBMP(100,16,16,16,zifu[52]);
    //白天天气
      draw_weather(day_0_code_day);
    }
    else if(Mode_3==1)
    {
    u8g2.drawXBMP(61,32,16,16,zifu[43]);//明
    //温度
      u8g2.setCursor(70, 30);  //
      u8g2.print(day_1_low);   
      u8g2.drawXBMP(100,16,16,16,zifu[52]);
    //白天天气
      draw_weather(day_1_code_day);
    }
    else if(Mode_3==2)
    {
    u8g2.drawXBMP(61,32,16,16,zifu[44]);//后
    //温度
      u8g2.setCursor(70, 30);  //
      u8g2.print(day_2_low);   
      u8g2.drawXBMP(100,16,16,16,zifu[52]);
    //白天天气
      draw_weather(day_2_code_day);
    }
    
    change=!change;
  }
  else
  {
  //(今)天夜间
    u8g2.drawXBMP(61+16,32,16,16,zifu[45]);//天
    u8g2.drawXBMP(61+32,32,16,16,zifu[47]);//夜
    u8g2.drawXBMP(61+48,32,16,16,zifu[53]);//间
  //最高温
    u8g2.drawXBMP(70,0,16,16,zifu[48]);
    u8g2.drawXBMP(70+16,0,16,16,zifu[49]);
    u8g2.drawXBMP(70+32,0,16,16,zifu[51]);
  
    if(Mode_3==0)
    {
    u8g2.drawXBMP(61,32,16,16,zifu[42]);//今
    //温度
      u8g2.setCursor(70, 30);  //
      u8g2.print(day_0_high);   
      u8g2.drawXBMP(100,16,16,16,zifu[52]);
    //夜间天气
      draw_weather(day_0_code_night);
    }
    else if(Mode_3==1)
    {
    u8g2.drawXBMP(61,32,16,16,zifu[43]);//明
    //温度
      u8g2.setCursor(70, 30);  //
      u8g2.print(day_1_high);   
      u8g2.drawXBMP(100,16,16,16,zifu[52]);
    //夜间天气
      draw_weather(day_1_code_night);
    }
    else if(Mode_3==2)
    {
    u8g2.drawXBMP(61,32,16,16,zifu[44]);//后
    //温度
      u8g2.setCursor(70, 30);  //
      u8g2.print(day_2_high);   
      u8g2.drawXBMP(100,16,16,16,zifu[52]);
    //夜间天气
      draw_weather(day_2_code_night);
    }
    
    change=!change;
  }
  u8g2.sendBuffer();  
}

获取心知天气

void get_weather(String url,String urlDat)
{
  if (!client.connect(host,port)) 
  {
      Serial.println("服务器连接失败");
      return;
  }    
  // 发送请求报文
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +  //请求行  请求方法 + 请求地址 + 协议版本
               "Host: " + host + "\r\n" +                //请求头部
               "Connection: close\r\n" +                //处理完成后断开连接
               "\r\n" +                                 //空行
               urlDat);                                 //请求数据            
  delay(100);  
  if(client.available()) //接收数据
  {          
      String line =client.readString();
//      get_date=line;
      int t = line.indexOf("{");//找时间
      int m = line.lastIndexOf("}]}");
      inputTime = line.substring(t, m + 3); //把含有时间的数据取出进行处理
  }
  Serial.println(inputTime);
  if(url==url_1)
    json_parsing_1(inputTime);
  else
    json_parsing_2(inputTime);
  client.stop();      //断开与服务器连接以节约资源
}

json数据解析

void json_parsing_1(String lalala)//今、明、后天天气
{

  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 3*JSON_OBJECT_SIZE(14) + 820;
  DynamicJsonBuffer jsonBuffer(capacity);
  const char* json = lalala.c_str();
//  Serial.println(json);
  JsonObject& root = jsonBuffer.parseObject(json);
  
  JsonObject& results_0 = root["results"][0];
  
  JsonObject& results_0_location = results_0["location"];
  const char* results_0_location_id = results_0_location["id"]; // "WSKMS3KBE2JM"
  const char* results_0_location_name = results_0_location["name"]; // "泉州"
  const char* results_0_location_country = results_0_location["country"]; // "CN"
  const char* results_0_location_path = results_0_location["path"]; // "泉州,泉州,福建,中国"
  const char* results_0_location_timezone = results_0_location["timezone"]; // "Asia/Shanghai"
  const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00"
  
  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"]; // "2022-01-22"
  const char* results_0_daily_0_text_day = results_0_daily_0["text_day"]; // "大雨"
  const char* results_0_daily_0_code_day = results_0_daily_0["code_day"]; // "15"
  const char* results_0_daily_0_text_night = results_0_daily_0["text_night"]; // "小雨"
  const char* results_0_daily_0_code_night = results_0_daily_0["code_night"]; // "13"
  const char* results_0_daily_0_high = results_0_daily_0["high"]; // "14"
  const char* results_0_daily_0_low = results_0_daily_0["low"]; // "15"
  const char* results_0_daily_0_rainfall = results_0_daily_0["rainfall"]; // "22.24"
  const char* results_0_daily_0_precip = results_0_daily_0["precip"]; // "0.99"
  const char* results_0_daily_0_wind_direction = results_0_daily_0["wind_direction"]; // "东"
  const char* results_0_daily_0_wind_direction_degree = results_0_daily_0["wind_direction_degree"]; // "90"
  const char* results_0_daily_0_wind_speed = results_0_daily_0["wind_speed"]; // "23.4"
  const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"]; // "4"
  const char* results_0_daily_0_humidity = results_0_daily_0["humidity"]; // "94"

  day_0_code_day=atoi(results_0_daily_0_code_day);
  day_0_code_night=atoi(results_0_daily_0_code_night);
  day_0_high=atoi(results_0_daily_0_high);
  day_0_low=atoi(results_0_daily_0_low);

  JsonObject& results_0_daily_1 = results_0_daily[1];
  const char* results_0_daily_1_date = results_0_daily_1["date"]; // "2022-01-23"
  const char* results_0_daily_1_text_day = results_0_daily_1["text_day"]; // "多云"
  const char* results_0_daily_1_code_day = results_0_daily_1["code_day"]; // "4"
  const char* results_0_daily_1_text_night = results_0_daily_1["text_night"]; // "小雨"
  const char* results_0_daily_1_code_night = results_0_daily_1["code_night"]; // "13"
  const char* results_0_daily_1_high = results_0_daily_1["high"]; // "19"
  const char* results_0_daily_1_low = results_0_daily_1["low"]; // "14"
  const char* results_0_daily_1_rainfall = results_0_daily_1["rainfall"]; // "1.28"
  const char* results_0_daily_1_precip = results_0_daily_1["precip"]; // "0.41"
  const char* results_0_daily_1_wind_direction = results_0_daily_1["wind_direction"]; // "东北"
  const char* results_0_daily_1_wind_direction_degree = results_0_daily_1["wind_direction_degree"]; // "45"
  const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"]; // "23.4"
  const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"]; // "4"
  const char* results_0_daily_1_humidity = results_0_daily_1["humidity"]; // "93"

  day_1_code_day=atoi(results_0_daily_1_code_day);
  day_1_code_night=atoi(results_0_daily_1_code_night);
  day_1_high=atoi(results_0_daily_1_high);
  day_1_low=atoi(results_0_daily_1_low);

  JsonObject& results_0_daily_2 = results_0_daily[2];
  const char* results_0_daily_2_date = results_0_daily_2["date"]; // "2022-01-24"
  const char* results_0_daily_2_text_day = results_0_daily_2["text_day"]; // "小雨"
  const char* results_0_daily_2_code_day = results_0_daily_2["code_day"]; // "13"
  const char* results_0_daily_2_text_night = results_0_daily_2["text_night"]; // "多云"
  const char* results_0_daily_2_code_night = results_0_daily_2["code_night"]; // "4"
  const char* results_0_daily_2_high = results_0_daily_2["high"]; // "16"
  const char* results_0_daily_2_low = results_0_daily_2["low"]; // "14"
  const char* results_0_daily_2_rainfall = results_0_daily_2["rainfall"]; // "2.86"
  const char* results_0_daily_2_precip = results_0_daily_2["precip"]; // "0.51"
  const char* results_0_daily_2_wind_direction = results_0_daily_2["wind_direction"]; // "东北"
  const char* results_0_daily_2_wind_direction_degree = results_0_daily_2["wind_direction_degree"]; // "45"
  const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"]; // "15.3"
  const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"]; // "3"
  const char* results_0_daily_2_humidity = results_0_daily_2["humidity"]; // "90"

  day_2_code_day=atoi(results_0_daily_2_code_day);
  day_2_code_night=atoi(results_0_daily_2_code_night);
  day_2_high=atoi(results_0_daily_2_high);
  day_2_low=atoi(results_0_daily_2_low);
  
  const char* results_0_last_update = results_0["last_update"]; // "2022-01-22T08:00:00+08:00"
}

void json_parsing_2(String lalala)//当前天气
{
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210;
  DynamicJsonBuffer jsonBuffer(capacity);
  
  const char* json = lalala.c_str();
  
  JsonObject& root = jsonBuffer.parseObject(json);
  
  JsonObject& results_0 = root["results"][0];
  
  JsonObject& results_0_location = results_0["location"];
  const char* results_0_location_id = results_0_location["id"]; // "WX4FBXXFKE4F"
  const char* results_0_location_name = results_0_location["name"]; // "北京"
  const char* results_0_location_country = results_0_location["country"]; // "CN"
  const char* results_0_location_path = results_0_location["path"]; // "北京,北京,中国"
  const char* results_0_location_timezone = results_0_location["timezone"]; // "Asia/Shanghai"
  const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00"
  
  JsonObject& results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "阴"
  const char* results_0_now_code = results_0_now["code"]; // "9"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "1"

  now_code_day=atoi(results_0_now_code);
  now_temperature=atoi(results_0_now_temperature);

  const char* results_0_last_update = results_0["last_update"]; // "2022-01-24T14:11:44+08:00"
}

显示

//时间显示
void draw_time()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
  {
    Serial.println("Failed to obtain time");
    WiFi.disconnect(false);
    WiFi.mode(WIFI_STA);//开启网络  
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
      delay(500);
      Serial.print(".");
    }
    configTime(8*3600,0,NTP1,NTP2,NTP3);
  }
  u8g2.setFont(u8g2_font_ncenB18_tf); // choose a suitable font
  u8g2.setCursor(15, 23);  //时间
  u8g2.print(&timeinfo, "%T");     
  u8g2.setFont(u8g2_font_ncenB14_tf); // choose a suitable font
  draw_week(40,29,timeinfo.tm_wday);//星期
  u8g2.setCursor(15, 63);  //日期
  u8g2.print(&timeinfo, "%F"); 
//  WiFi.disconnect(true);
}

//星期显示
void draw_week(int kong,int high,int date)
{
    u8g2.drawXBMP(kong+0,high,16,16,zifu[0]);    
    u8g2.drawXBMP(kong+16,high,16,16,zifu[1]); 
    u8g2.drawXBMP(kong+32,high,16,16,zifu[date+2]); 
}

//天气
void draw_weather(int Weather)
{
  u8g2.drawXBMP(0,2, 60, 60,tianqi[Weather]);
  switch(Weather)
  {
    case 0:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[9]);
      break;
        }
    case 1:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[9]);
      break;
        }
    case 2:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[9]);
      break;
        }
    case 3:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[9]);
      break;
        }
    case 4:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[11]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[12]);
      break;
        }
    case 5:{
      u8g2.drawXBMP(61,48,16,16,zifu[9]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[53]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[11]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[12]);
      break;
        }
    case 6:{
      u8g2.drawXBMP(61,48,16,16,zifu[9]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[53]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[11]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[12]);
      break;
        }
    case 7:{
      u8g2.drawXBMP(61,48,16,16,zifu[33]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[54]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[11]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[12]);
      break;
        }
    case 8:{
      u8g2.drawXBMP(61,48,16,16,zifu[33]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[54]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[11]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[12]);
      break;
        }
    case 9:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[13]);
      break;
        }
    case 10:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[14]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[21]);
      break;
        }
    case 11:{
      u8g2.drawXBMP(61+8,48,16,16,zifu[15]);
      u8g2.drawXBMP(61+24,48,16,16,zifu[14]);
      u8g2.drawXBMP(61+40,48,16,16,zifu[21]);
      break;
        }
    case 12:{
      u8g2.drawXBMP(61+8,48,16,16,zifu[15]);
      u8g2.drawXBMP(61+24,48,16,16,zifu[14]);
      u8g2.drawXBMP(61+40,48,16,16,zifu[21]);
      break;
        }
    case 13:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[16]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[21]);
      break;
        }
    case 14:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[17]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[21]);
      break;
        }
    case 15:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[18]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[21]);
      break;
        }
    case 16:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[19]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[21]);
      break;
        }
    case 17:{
      u8g2.drawXBMP(61+8,48,16,16,zifu[18]);
      u8g2.drawXBMP(61+24,48,16,16,zifu[19]);
      u8g2.drawXBMP(61+40,48,16,16,zifu[21]);
      break;
        }
    case 18:{
      u8g2.drawXBMP(61,48,16,16,zifu[20]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[18]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[19]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[21]);
      break;
        }
    case 19:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[55]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[21]);
      break;
        }
    case 20:{
      u8g2.drawXBMP(61+8,48,16,16,zifu[21]);
      u8g2.drawXBMP(61+24,48,16,16,zifu[56]);
      u8g2.drawXBMP(61+40,48,16,16,zifu[22]);
      break;
        }
    case 21:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[14]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[22]);
      break;
        }
    case 22:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[16]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[22]);
      break;
        }
    case 23:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[17]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[22]);
      break;
        }
    case 24:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[18]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[22]);
      break;
        }
    case 25:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[19]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[22]);
      break;
        }
    case 26:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[23]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[24]);
      break;
        }
    case 27:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[25]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[26]);
      break;
        }
    case 28:{
      u8g2.drawXBMP(61+8,48,16,16,zifu[26]);
      u8g2.drawXBMP(61+24,48,16,16,zifu[24]);
      u8g2.drawXBMP(61+40,48,16,16,zifu[30]);
      break;
        }
    case 29:{
      u8g2.drawXBMP(61,48,16,16,zifu[27]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[26]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[24]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[30]);
      break;
        }
    case 30:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[31]);
      break;
        }
    case 31:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[32]);
      break;
        }
    case 32:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[34]);
      break;
        }
    case 33:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[33]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[34]);
      break;
        }
    case 34:{
      u8g2.drawXBMP(61+16,48,16,16,zifu[35]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[34]);
      break;
        }
    case 35:{
      u8g2.drawXBMP(61,48,16,16,zifu[36]);
      u8g2.drawXBMP(61+16,48,16,16,zifu[37]);
      u8g2.drawXBMP(61+32,48,16,16,zifu[34]);
      u8g2.drawXBMP(61+48,48,16,16,zifu[30]);
      break;
        }
    case 36:{
      u8g2.drawXBMP(61+8,48,16,16,zifu[38]);
      u8g2.drawXBMP(61+24,48,16,16,zifu[39]);
      u8g2.drawXBMP(61+40,48,16,16,zifu[34]);
      break;
        }
    case 37:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[40]);
      break;
        }
    case 38:{
      u8g2.drawXBMP(61+24,48,16,16,zifu[41]);
      break;
        }
  } 
}

遇到的主要难题及解决方法

1、因为按键数量不够,所以按键3需控制天气中今、明、后天的选择,。最开始使用按键中断,但不知某种原因按下按键后按键发生多次中断,且程序一段时间后会自动重启,查询无果后改用按键扫描方式。因该按键需要控制多种选择,所以设置一个按键复位检测程序,当按键按下后,程序检测到低电平,执行一次按键程序,只有在松开按键后检测到高电平程序才能在下一次低电平时执行按键程序;

2、使用心知天气下载的天气图标生成oled图库,但是心知天气的图标像素不一,oled显示乱码,后来使用PS将图片的像素改为60*60后解决问题。

未来的计划或建议等

当前的程序今可以显示时间,后面可以加入音频播放器进行整点报时

加入TCP功能,通过手机对esp32进行音乐点播

 

附件下载
ESP32S2.zip
团队介绍
福州大学 电气工程与自动化学院 电气工程及其自动化
团队成员
李锦江
单片机小白
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号