esp8266加0.91寸oled显示屏制作天气时钟

前言

上两周做了个客制化键盘,将esp8266改在键盘里面了显示始终天气等信息,演示视频看我B站视频:200块改的键盘,没错,你是来听歌的,五分钟剪的视频
键盘制作教程在最后的参考资料里,自行查看。

之前在网上参考的教程代码都好古老了,一堆问题,而且断网后就会卡在一个界面,天气、时钟是一直在同步网络的,断网后就啥也没了。
最近将代码改了下,包括如下功能:

  1. 自动同步时间,断网后程序自动计时
  2. 自动循环播放
  3. 开机连上wifi后,同步三天天气信息,断网后展示断网前最新一次数据
  4. 最后加上了我手写的文字,哈哈哈哈,可以自己根据代码改。用PCtoLCD2002自己手写或者图片都行

效果展示

请添加图片描述
请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

代码

/**********************************************************************
 * 项目:客制化键盘嵌入ESP8266
 * 硬件:适用于NodeMCU ESP8266 + 0.91寸 128*32 oled显示屏
 * 功能:连接WiFi后时钟+心知天气+手写文字,优化和改动了很多bug
 * 作者:米奇罗(茂茂)
 * 参考:Nemo_ssc  bilibili UID:12772522
 * 日期:2021/12/04
 **********************************************************************/
//----------------------调用库头文件---------------------
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
#include <math.h>
#include "DHT.h"
#include <DNSServer.h>
#include <ESP8266WebServer.h>
DNSServer dnsServer;
ESP8266WebServer server(80);



U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
int sta = 0;

//---------------wifi连接/API用户名密码信息----------------
const char *ssid = "CMCC-qD";          //WiFi名
const char *password = "nxzks6qu";  //WiFi密码

const char* HOST = "api.seniverse.com";
const char* APIKEY = "";        //API KEY 心知天气私钥
const char* CITY = "shenzhen";  //城市全拼
const char* LANGUAGE = "zh-Hans";//zh-Hans 简体中文 
//-------------------------------------------------------

//-----------------------天气参数-------------------------
typedef struct
{
    String date_m;
    String date_d;
    int code_day;
    int high;
    int low;
    int wind_direction_degree;
    int wind_scale;
    int humidity;
}weather_date; //天气信息的结构体

weather_date day0,day1,day2;
weather_date day0_new,day1_new,day2_new;//联网前最新数据
//-------------------------------------------------------

//-----------------------定义常量-------------------------
int Click = 0;  //轻触开关引脚
int beep = 13;  //蜂鸣器引脚
const unsigned long HTTP_TIMEOUT = 5000;  //http访问请求
WiFiClient client;
HTTPClient http;


static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,阿里云
const int timeZone = 8;                                //时区,北京时间为+8
WiFiUDP Udp;
unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口
time_t getNtpTime();
boolean isNTPConnected = false;

String response_ws;  //json返回天气信息
String GetUrl;  //心知天气url请求
//------------------------------------------------------------------

//---------------------------位图信息--------------------------------
//24*24 钢铁侠logo
const unsigned char IronMan_24u[] U8X8_PROGMEM = {
0x00,0x3C,0x00,0x00,0xE7,0x00,0xC0,0xE7,0x03,0x70,0x66,0x0E,0x18,0x66,0x18,0x08,
0x7E,0x10,0x08,0x7E,0x10,0x0C,0x00,0x30,0x0E,0x00,0x70,0xEA,0x00,0x57,0xEA,0xC3,
0x57,0x2A,0x7E,0x54,0x2E,0x42,0x74,0xE8,0xC3,0x17,0x08,0x00,0x10,0x38,0x00,0x1C,
0xE8,0x7E,0x17,0x88,0xC3,0x11,0x08,0x81,0x10,0x38,0x7E,0x1C,0xE0,0x42,0x07,0x80,
0xC3,0x01,0x00,0x67,0x00,0x00,0x3C,0x00};

//128*32 手写句子
const unsigned char yiyan_12832[] U8X8_PROGMEM ={
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,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,0x10,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x60,0x00,0x01,0x00,0x00,0xE0,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x20,0x80,0x00,0x01,0x00,0x00,0x00,0x06,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x30,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x04,0x00,0x0F,0x00,0x00,0x00,0x04,0xC0,0x41,0x10,0x00,0x00,0x00,0x00,0x00,
0x08,0xE4,0xE0,0x01,0x08,0x38,0x00,0x04,0xE0,0x78,0xA0,0x00,0x3E,0x00,0x00,0x06,
0x04,0x38,0xB8,0x00,0x08,0x00,0x00,0x84,0x80,0x0F,0xE4,0x00,0x00,0x00,0x0F,0x0C,
0x20,0x0E,0x80,0x00,0x08,0x00,0x30,0x04,0xC1,0x01,0x64,0x00,0x84,0x00,0x18,0x0C,
0xA0,0x13,0x80,0x04,0x08,0x00,0x6C,0x04,0x70,0x3F,0x2C,0x00,0xC4,0x43,0x10,0x68,
0xE0,0x90,0xC0,0x04,0x08,0x00,0x54,0x04,0x40,0x00,0xE0,0x0C,0x64,0x42,0x18,0x38,
0x70,0x51,0x50,0x04,0x28,0x20,0x5C,0x00,0x44,0x03,0xFC,0x1F,0x3C,0x4E,0x14,0x0E,
0xC0,0x50,0x60,0x07,0xC8,0x20,0x4C,0x04,0xE4,0x01,0x62,0x10,0x36,0x4A,0x12,0x0A,
0x40,0x20,0x20,0x0D,0x89,0x20,0x7C,0x04,0xA2,0x1A,0x30,0x10,0x36,0x4D,0x19,0x1B,
0x70,0x20,0x30,0xCE,0x04,0x23,0x30,0x04,0x31,0x0F,0x38,0x0F,0xBC,0x47,0x0D,0x11,
0x50,0x70,0x28,0x3E,0x04,0x62,0x00,0x84,0xC1,0x03,0x2C,0xBD,0x9C,0x41,0x07,0x13,
0x48,0x54,0x2C,0x0C,0x00,0x40,0x00,0x08,0xE0,0x05,0x34,0xE7,0x00,0x00,0x00,0x1A,
0x58,0x5C,0x20,0x06,0x00,0x00,0x00,0x08,0xC0,0x0C,0x1C,0x00,0x00,0x00,0x00,0x0E,
0x70,0xC0,0x60,0x00,0x00,0x00,0x00,0x08,0x60,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x98,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x08,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1C,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBB,0xB6,0x08,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x99,0x92,0x08,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x98,0xDF,0x06,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB4,0x03
};


//下面是天气图标和对应心知天气的天气代码
//Sunny = 0 晴
const unsigned char Sunny[] U8X8_PROGMEM ={
0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,
0x30,0xC0,0x00,0x03,0x70,0x00,0x80,0x03,0xE0,0x00,0xC0,0x01,0xC0,0xE0,0xC1,0x00,
0x00,0xF8,0x07,0x00,0x00,0xFE,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xFF,0x3F,0x00,
0x00,0xFF,0x3F,0x00,0x80,0xFF,0x7F,0x00,0x8F,0xFF,0x7F,0x3C,0x8F,0xFF,0x7F,0x3C,
0x80,0xFF,0x7F,0x00,0x80,0xFF,0x7F,0x00,0x00,0xFF,0x3F,0x00,0x00,0xFE,0x1F,0x00,
0x00,0xFE,0x1F,0x00,0x00,0xFC,0x0F,0x00,0xC0,0xF0,0xC3,0x00,0xE0,0x00,0xC0,0x01,
0x70,0x00,0x80,0x03,0x30,0x00,0x00,0x03,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,
0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00                                            
};
//Cloudy = 4 多云
const unsigned char Cloudy[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,
0x00,0x80,0x3F,0x00,0x00,0xE6,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x80,0xFF,0xFF,0x00,
0x80,0xFF,0xFF,0x01,0xC0,0xFF,0xFF,0x01,0xC0,0xFF,0xFF,0x03,0xE0,0xFF,0xFF,0x07,
0xF0,0xFF,0xFF,0x0F,0xF8,0xFF,0x07,0x0F,0xF8,0xFF,0x71,0x0F,0xF8,0xFF,0xFE,0x0E,
0xF8,0x7F,0xFE,0x08,0xF0,0x7F,0xFF,0x07,0xE0,0x1F,0xFF,0x0F,0xC0,0xEF,0xFF,0x1F,
0x80,0xE7,0xFF,0x1F,0x00,0xF0,0xFF,0x3F,0x1C,0xF0,0xFF,0x3F,0x3C,0xF0,0xFF,0x1F,
0x7E,0xF0,0xFF,0x1F,0x7F,0xE0,0xFF,0x0F,0x3E,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00                                            
};
//Overcast = 9 阴
const unsigned char Overcast[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xF3,0xFF,0x00,
0xC0,0xFF,0xFF,0x01,0xE0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x03,
0xF0,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0x07,0xFC,0xFF,0xFF,0x0F,0xFE,0xFF,0xFF,0x1F,
0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0x3F,
0xFF,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x0F,0xF8,0xFF,0xFF,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00                                      
};
//Shower = 10 阵雨
const unsigned char Shower[] U8X8_PROGMEM ={
0x00,0x00,0x70,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0xFE,0x07,0x00,0x00,0xF8,0x0F,
0x00,0xC0,0xE3,0x1F,0x00,0xF0,0xCF,0x1F,0xC0,0xF9,0x9F,0x3F,0xE0,0xFF,0xBF,0x3F,
0xF0,0xFF,0x3F,0x3F,0xF0,0xFF,0x7F,0x1F,0xF0,0xFF,0x7F,0x1E,0xF8,0xFF,0xFF,0x1C,
0xFC,0xFF,0xFF,0x09,0xFE,0xFF,0xFF,0x03,0xFE,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0x07,
0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0x03,0xFE,0xFF,0xFF,0x03,
0xFC,0xFF,0xFF,0x01,0xF0,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x20,0x00,
0x60,0x60,0x30,0x00,0x60,0x60,0x30,0x00,0x30,0x30,0x18,0x00,0x30,0x30,0x18,0x00,
0x18,0x18,0x0C,0x00,0x08,0x08,0x04,0x00                                           
};
//Thundershower = 11 雷阵雨
const unsigned char Thundershower[] U8X8_PROGMEM ={
0x00,0x00,0x0E,0x00,0x00,0xC0,0x3F,0x00,0x00,0xE0,0xFF,0x00,0xC0,0xFF,0xFF,0x01,
0xE0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x03,0xF0,0xFF,0xFF,0x03,
0xF0,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0x07,0xFC,0xFF,0xFF,0x0F,0xFE,0xFF,0xFF,0x1F,
0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,
0xFE,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x07,0xF0,0xFF,0xFF,0x01,
0x00,0xF0,0x01,0x00,0x60,0xF0,0xC1,0x00,0x60,0xF0,0xC0,0x00,0x60,0x78,0xC0,0x00,
0x30,0xFC,0x60,0x00,0x30,0x70,0x60,0x00,0x10,0x30,0x20,0x00,0x10,0x18,0x20,0x00,
0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00                                           
};
//Rain_L = 13 小雨
const unsigned char Rain_L[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0x3F,0x00,0x00,0xE0,0xFF,0x00,
0xC0,0xFF,0xFF,0x01,0xE0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x03,
0xF0,0xFF,0xFF,0x03,0xF0,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x0F,
0xFE,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,
0xFF,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x07,
0xE0,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x10,0x00,0x00,
0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00                                            
};
//Rain_M = 14 中雨
const unsigned char Rain_M[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0x3F,0x00,0x00,0xE0,0xFF,0x00,
0xC0,0xFF,0xFF,0x01,0xE0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x03,
0xF0,0xFF,0xFF,0x03,0xF0,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x0F,
0xFE,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,
0xFF,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x07,
0xE0,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0C,0x0C,0x00,0x00,0x04,0x04,0x00,0x00,0x06,0x06,0x00,0x00,0x02,0x02,0x00,
0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00                                   
};
//Rain_H = 15 大雨
const unsigned char Rain_H[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0x3F,0x00,0x00,0xE0,0xFF,0x00,
0xC0,0xFF,0xFF,0x01,0xE0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x01,0xF0,0xFF,0xFF,0x03,
0xF0,0xFF,0xFF,0x03,0xF0,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x0F,
0xFE,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x1F,
0xFF,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x07,
0xE0,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x60,0x60,0x60,0x00,0x20,0x20,0x20,0x00,0x30,0x30,0x30,0x00,0x10,0x10,0x10,0x00,
0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00                                            
};
//Foggy = 30 雾
const unsigned char Foggy[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0xC0,0xFF,0x00,0x00,0xF0,0xFF,0x01,0x00,
0xF8,0xFF,0x03,0x00,0xFC,0xFF,0x07,0x00,0xFC,0xFF,0x0F,0x00,0xFE,0xFF,0xFF,0x01,
0xFE,0xFF,0xFF,0x07,0xFE,0xFF,0xFF,0x0F,0xFE,0xFF,0xFF,0x0F,0xFE,0xFF,0xFF,0x1F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x1F,
0xFE,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x1F,0xFE,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x1F,
0xFE,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00                                            
};
//Haze = 31 霾
const unsigned char Haze[] U8X8_PROGMEM ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0xE0,0x00,0x1C,0x0E,0xE0,0x00,0x1C,
0x0E,0xE0,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xF0,0x03,0xF0,0x01,0xF8,0x0F,0xFC,0x07,0x1C,0x1E,0x0E,0x0E,
0x0E,0x38,0x07,0x1C,0x06,0x30,0x03,0x18,0x07,0xF0,0x03,0x38,0x03,0xE0,0x01,0x30,
0x03,0xE0,0x01,0x30,0x07,0x30,0x03,0x38,0x06,0x38,0x07,0x18,0x0E,0x1C,0x0E,0x1C,
0x1C,0x0F,0x1C,0x0F,0xF8,0x07,0xF8,0x03,0xF0,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0xE0,0x00,0x1C,0x0E,0xE0,0x00,0x1C,
0x0E,0xE0,0x00,0x1C,0x00,0x00,0x00,0x00                                            
};



//------------------------------------------------------------------
//---------------------------setup函数-------------------------------
//------------------------------------------------------------------
void setup()
{
    u8g2.begin();  //启用u8g2库
    u8g2.enableUTF8Print();

    //开机画面
    u8g2.clearBuffer();
    u8g2.drawXBMP( 4 , 4 , 24 , 24 , IronMan_24u);
    u8g2.setFont(u8g2_font_luBIS08_tr); 
    u8g2.drawStr(34, 23,"I'm Iron Man !"); 
    
    u8g2.sendBuffer();

    WiFi.begin(ssid, password);                  // 启动网络连接
    Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
    Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
    
    int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
    while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
        delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
        Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
    }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                                // 这个读秒是通过变量i每隔一秒自加1来实现的。                                              
    Serial.println("");                          // WiFi连接成功后
    Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
    Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
    Serial.println(WiFi.localIP());

    //开机连上wifi后同步一次天气数据
    if (getJson_ws()){
        parseJson_ws(response_ws);
    }

    Udp.begin(localPort);
    setSyncProvider(getNtpTime);
    setSyncInterval(300); //每300秒同步一次时间
    //dht.begin();
}




//------------------------------------------------------------------
//-----------------------NTP_clock----------------------------------
//------------------------------------------------------------------
const int NTP_PACKET_SIZE = 48;     // NTP时间在消息的前48个字节里
byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区

time_t getNtpTime()
{
  IPAddress ntpServerIP;          // NTP服务器的地址

  while (Udp.parsePacket() > 0);  // 丢弃以前接收的任何数据包
  Serial.println("Transmit NTP Request");
  // 从池中获取随机服务器
  WiFi.hostByName(ntpServerName, ntpServerIP);
  Serial.print(ntpServerName);
  Serial.print(": ");
  Serial.println(ntpServerIP);
  sendNTPpacket(ntpServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500)
  {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE)
    {
      Serial.println("Receive NTP Response");
      isNTPConnected = true;
      Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
      unsigned long secsSince1900;
      // 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
      secsSince1900 = (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      Serial.println(secsSince1900);
      Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-("); //无NTP响应
  isNTPConnected = false;
  return 0; //如果未得到时间则返回0
}


// 向给定地址的时间服务器发送NTP请求
void sendNTPpacket(IPAddress &address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011; // LI, Version, Mode
  packetBuffer[1] = 0;          // Stratum, or type of clock
  packetBuffer[2] = 6;          // Polling Interval
  packetBuffer[3] = 0xEC;       // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}
void NTP_CLOCK(time_t prevDisplay)  //oled输出时分秒,没有十位的补0
{
    server.handleClient();
    dnsServer.processNextRequest();
    // if (timeStatus() != timeNotSet)
    // {
    if (now() != prevDisplay)
    { //时间改变时更新显示
        prevDisplay = now();
        int hours, minutes, seconds;
        hours = hour();
        minutes = minute();
        seconds = second();
        Serial.printf("%d:%d:%d\n", hours, minutes, seconds);

        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_freedoomr10_tu); // choose a suitable font
        u8g2.setCursor(90, 15);
        if (isNTPConnected)
        {
            u8g2.print("UTC+8");
        }else{
            u8g2.print("NoNet");
        }

        String currentTime_hm = "";
        String currentTime_s = "";
        if (hours < 10)
            currentTime_hm += 0;
        currentTime_hm += hours;
        currentTime_hm += ":";
        if (minutes < 10)
            currentTime_hm += 0;
        currentTime_hm += minutes;
        //currentTime += ":";
        if (seconds < 10)
            currentTime_s += 0;
        currentTime_s += seconds;
        u8g2.setFont(u8g2_font_freedoomr25_tn); // choose a suitable font
        u8g2.setCursor(0, 30);
        u8g2.print(currentTime_hm);  // write something to the internal memory
        u8g2.setFont(u8g2_font_freedoomr10_tu); // choose a suitable font
        u8g2.setCursor(90, 30);
        u8g2.print(currentTime_s);  // write something to the internal memory
        u8g2.sendBuffer();
    }
    //}

    //delay(15000);
}




void NTP_DAY()  //oled输出年月日+星期
{
    int years, months, days, weekdays;
    years = year();
    months = month();
    days = day();
    weekdays = weekday();
    Serial.printf("%d/%d/%d Weekday:%d\n", years, months, days, weekdays);
    String currentDay = "";
    if (months < 10)
      currentDay += 0;
    currentDay += months;
    currentDay += "/";
    if (days < 10)
      currentDay += 0;
    currentDay += days;
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_ncenB12_tr);
    u8g2.setCursor(0, 15);
    u8g2.print(years);
    u8g2.setCursor(0, 31);
    u8g2.print(currentDay);
    u8g2.setFont(u8g2_font_logisoso24_tr);
    u8g2.setCursor(60, 31);
    if (weekdays == 1)
      u8g2.print("SUN");
    else if (weekdays == 2)
      u8g2.print("MON");
    else if (weekdays == 3)
      u8g2.print("TUS");
    else if (weekdays == 4)
      u8g2.print("WED");
    else if (weekdays == 5)
      u8g2.print("THU");
    else if (weekdays == 6)
      u8g2.print("FRI");
    else if (weekdays == 7)
      u8g2.print("SAT");
    u8g2.sendBuffer();

    delay(10000);
}

//------------------------------------------------------------------
//------------------------weather_station---------------------------
//----------------------------api test------------------------------
//https://api.seniverse.com/v3/weather/now.json?key=SuQDmnIsehmcwH7cx&location=beijing&language=zh-Hans&unit=c
//https://api.seniverse.com/v3/weather/daily.json?key=SuQDmnIsehmcwH7cx&location=beijing&language=zh-Hans&unit=c&start=0&days=5
bool getJson_ws()  //构建并发出获取天气数据的请求,获得json数据
{
    bool s = false;
    GetUrl = "http://" + String(HOST) + "/v3/weather/daily.json?key=";
    GetUrl += APIKEY;
    GetUrl += "&location=";
    GetUrl += CITY;
    GetUrl += "&language=";
    GetUrl += LANGUAGE;
    GetUrl += "&unit=c&start=0&days=3";
    http.setTimeout(HTTP_TIMEOUT);
    http.begin(client,GetUrl);
    int httpCode = http.GET();
    if (httpCode > 0){
        if (httpCode == HTTP_CODE_OK){
            response_ws = http.getString();
            //Serial.println(response_ws);
            s = true;
        }
    }else{
        Serial.printf("[HTTP] GET JSON failed, error: %s\n", http.errorToString(httpCode).c_str());
        s = false;
    }
    http.end();
    return s;
}

bool parseJson_ws(String json)  //对心知天气的json数据解析,采用arduinojson v6库
{
    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) + 810;
    DynamicJsonDocument doc(capacity);  //根据json数据结构计算所需要的内存大小
    deserializeJson(doc, json);  //反序列化json数据
    JsonObject results_0 = doc["results"][0];
    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"]; // "2020-06-20"
    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"]; // "4"
    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"]; // "4"
    const char* results_0_daily_0_high = results_0_daily_0["high"]; // "28"
    const char* results_0_daily_0_low = results_0_daily_0["low"]; // "20"
    const char* results_0_daily_0_rainfall = results_0_daily_0["rainfall"]; // "0.0"
    const char* results_0_daily_0_precip = results_0_daily_0["precip"]; // ""
    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"]; // "16.20"
    const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"]; // "3"
    const char* results_0_daily_0_humidity = results_0_daily_0["humidity"]; // "72"

    JsonObject results_0_daily_1 = results_0_daily[1];  //明天的天气数据
    const char* results_0_daily_1_date = results_0_daily_1["date"]; // "2020-06-21"
    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"]; // "9"
    const char* results_0_daily_1_high = results_0_daily_1["high"]; // "27"
    const char* results_0_daily_1_low = results_0_daily_1["low"]; // "20"
    const char* results_0_daily_1_rainfall = results_0_daily_1["rainfall"]; // "0.0"
    const char* results_0_daily_1_precip = results_0_daily_1["precip"]; // ""
    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"]; // "135"
    const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"]; // "16.20"
    const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"]; // "3"
    const char* results_0_daily_1_humidity = results_0_daily_1["humidity"]; // "68"

    JsonObject results_0_daily_2 = results_0_daily[2];  //后天的天气数据
    const char* results_0_daily_2_date = results_0_daily_2["date"]; // "2020-06-22"
    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"]; // "14"
    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"]; // "13"
    const char* results_0_daily_2_high = results_0_daily_2["high"]; // "26"
    const char* results_0_daily_2_low = results_0_daily_2["low"]; // "23"
    const char* results_0_daily_2_rainfall = results_0_daily_2["rainfall"]; // "10.0"
    const char* results_0_daily_2_precip = results_0_daily_2["precip"]; // ""
    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"]; // "127"
    const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"]; // "25.20"
    const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"]; // "4"
    const char* results_0_daily_2_humidity = results_0_daily_2["humidity"]; // "71"
    
    const char* results_0_last_update = results_0["last_update"];  //数据更新时间
    
    String date0 = results_0_daily_0_date;  //将日期取出处理
    String date1 = results_0_daily_1_date;  
    String date2 = results_0_daily_2_date; 
    
    day0_new.date_m = date0.substring(5, 7);  //日期字符串切片
    day0_new.date_d = date0.substring(8, 10);
    day0_new.code_day = atoi(results_0_daily_0_code_day);//获取今天天气信息
    day0_new.high = atoi(results_0_daily_0_high);  //最高温度
    day0_new.low = atoi(results_0_daily_0_low);  //最低温度
    day0_new.wind_direction_degree = atoi(results_0_daily_0_wind_direction_degree);  //风向
    day0_new.wind_scale = atoi(results_0_daily_0_wind_scale);  //风力等级
    day0_new.humidity = atoi(results_0_daily_0_humidity);  //湿度
    
    day1_new.date_m = date1.substring(5, 7);
    day1_new.date_d = date1.substring(8, 10);
    day1_new.code_day = atoi(results_0_daily_1_code_day);//获取明天天气信息
    day1_new.high = atoi(results_0_daily_1_high);
    day1_new.low = atoi(results_0_daily_1_low);
    day1_new.wind_direction_degree = atoi(results_0_daily_1_wind_direction_degree);
    day1_new.wind_scale = atoi(results_0_daily_1_wind_scale);
    day1_new.humidity = atoi(results_0_daily_1_humidity);

    day2_new.date_m = date2.substring(5, 7);
    day2_new.date_d = date2.substring(8, 10);
    day2_new.code_day = atoi(results_0_daily_2_code_day);//获取后天天气信息
    day2_new.high = atoi(results_0_daily_2_high);
    day2_new.low = atoi(results_0_daily_2_low);
    day2_new.wind_direction_degree = atoi(results_0_daily_2_wind_direction_degree);
    day2_new.wind_scale = atoi(results_0_daily_2_wind_scale);
    day2_new.humidity = atoi(results_0_daily_2_humidity);

    if (client.connect(HOST, 80))
    {
        Serial.println(" Success!");
        day0 = day0_new;
        day1 = day1_new;
        day2 = day2_new;
    }
    return true;
}


void yiyan()  //oled输出一句话
{
    u8g2.clearBuffer();
    u8g2.drawXBMP( 0 , 0 , 128 , 32 , yiyan_12832);
    u8g2.sendBuffer();
    delay(15000);
}

void display_today()  //oled显示今天的天气信息
{   
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_lubB08_tr); 
    u8g2.setCursor(34, 15);
    u8g2.print(day0.low);
    u8g2.setCursor(49, 15);
    u8g2.print("-");
    u8g2.setCursor(54, 15);
    u8g2.print(day0.high);
    u8g2.setCursor(68, 15);
    u8g2.print("C");

    u8g2.drawLine(87, 5, 87, 31);

    u8g2.setCursor(94, 15);
    u8g2.print(day0.humidity);
    u8g2.setCursor(110, 15);
    u8g2.print("%");
    //u8g2.setCursor(80, 31);
    //u8g2.print(day0.wind_direction_degree);
    
    String Direction;  //将风向角度简化为风向文字信息
    if (day0.wind_direction_degree == 0)
    {
        Direction = "N";
    }
    else if (day0.wind_direction_degree == 90)
    {
        Direction = "E";
    }
    else if (day0.wind_direction_degree == 180)
    {
        Direction = "S";
    }
    else if (day0.wind_direction_degree == 270)
    {
        Direction = "W";
    }
    else if ((day0.wind_direction_degree>0) && (day0.wind_direction_degree<90))
    {
        Direction = "EN";
    }
    else if ((day0.wind_direction_degree>90) && (day0.wind_direction_degree<180))
    {
        Direction = "ES";
    }
    else if ((day0.wind_direction_degree>180) && (day0.wind_direction_degree<270))
    {
        Direction = "WS";
    }
    else if ((day0.wind_direction_degree>270) && (day0.wind_direction_degree<360))
    {
        Direction = "WN";
    }
    u8g2.setCursor(94, 31);
    u8g2.print(Direction);

    u8g2.setFont(u8g2_font_tenstamps_mn);
    u8g2.setCursor(110, 31);
    u8g2.print(day0.wind_scale);

    
    switch(day0.code_day)  //将天气代码转化为天气图标和字符显示
    {
        case 0:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Sunny );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Sunny");
            break;
        case 4:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Cloudy );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Cloudy");
            break;
        case 9:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Overcast );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Overcast");
            break;
        case 10:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Shower );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Shower");
            break;
        case 11:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Thundershower );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Thunder");
            break;
        case 13:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_L );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"L-Rain");
            break;
        case 14:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_M );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"M-Rain");
            break;
        case 15:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_H );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"H-Rain");
            break;
        case 30:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Foggy );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Foggy");
            break;
        case 31:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Haze );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Haze");
            break;    
    }
    
    u8g2.sendBuffer();
    Serial.println(day0.code_day);
}

void weather_station0()  //获取解析json,显示今天天气
{   
    if (getJson_ws()){
        parseJson_ws(response_ws);
    }
    
    display_today();
    delay(15000);
}
/*
void weather_station1()  //并列显示三天日期和最高/低温度信息
{
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_lubB08_tr); 
    u8g2.setCursor(7, 15);
    u8g2.print(day0.date_m);
    u8g2.setCursor(21, 15);
    u8g2.print("/");
    u8g2.setCursor(29, 15);
    u8g2.print(day0.date_d);
    
    u8g2.setCursor(7, 31);
    u8g2.print(day0.low);
    u8g2.setCursor(22, 31);
    u8g2.print("-");
    u8g2.setCursor(27, 31);
    u8g2.print(day0.high);

    u8g2.drawLine(45, 5, 45, 31);
    
    u8g2.setCursor(49, 15);
    u8g2.print(day1.date_m);
    u8g2.setCursor(63, 15);
    u8g2.print("/");
    u8g2.setCursor(71, 15);
    u8g2.print(day1.date_d);

    u8g2.setCursor(49, 31);
    u8g2.print(day1.low);
    u8g2.setCursor(64, 31);
    u8g2.print("-");
    u8g2.setCursor(69, 31);
    u8g2.print(day1.high);

    u8g2.drawLine(87, 5, 87, 31);

    u8g2.setCursor(91, 15);
    u8g2.print(day2.date_m);
    u8g2.setCursor(105, 15);
    u8g2.print("/");
    u8g2.setCursor(113, 15);
    u8g2.print(day2.date_d);
    
    u8g2.setCursor(91, 31);
    u8g2.print(day2.low);
    u8g2.setCursor(106, 31);
    u8g2.print("-");
    u8g2.setCursor(111, 31);
    u8g2.print(day2.high);  
      
    u8g2.sendBuffer();

    delay(3000);
}

void weather_station2()  //并列显示三天天气图标
{   
    u8g2.clearBuffer();
    switch(day0.code_day)
    {
        case 0:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Sunny  );
            break;
        case 4:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Cloudy );
            break;
        case 9:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Overcast );
            break;
        case 10:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Shower );
            break;
        case 11:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Thundershower );
            break;
        case 13:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Rain_L );
            break;
        case 14:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Rain_M );
            break;
        case 15:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Rain_H );
            break;
        case 30:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Foggy );
            break;
        case 31:
            u8g2.drawXBMP( 7 , 1 , 30 , 30 , Haze );
            break;
    }  
    switch(day1.code_day)
    {
        case 0:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Sunny  );
            break;
        case 4:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Cloudy );
            break;
        case 9:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Overcast );
            break;
        case 10:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Shower );
            break;
        case 11:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Thundershower );
            break;
        case 13:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Rain_L );
            break;
        case 14:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Rain_M );
            break;
        case 15:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Rain_H );
            break;
        case 30:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Foggy );
            break;
        case 31:
            u8g2.drawXBMP( 49 , 1 , 30 , 30 , Haze );
            break;
    }
    switch(day2.code_day)
    {
        case 0:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Sunny  );
            break;
        case 4:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Cloudy );
            break;
        case 9:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Overcast );
            break;
        case 10:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Shower );
            break;
        case 11:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Thundershower );
            break;
        case 13:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Rain_L );
            break;
        case 14:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Rain_M );
            break;
        case 15:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Rain_H );
            break;
        case 30:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Foggy );
            break;
        case 31:
            u8g2.drawXBMP( 91 , 1 , 30 , 30 , Haze );
            break;
    }
    u8g2.sendBuffer();


    delay(3000);
}


*/

void weather_station1()  //显示明天天气
{
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_lubB08_tr); 
    u8g2.setCursor(34, 15);
    u8g2.print(day1.low);
    u8g2.setCursor(49, 15);
    u8g2.print("-");
    u8g2.setCursor(54, 15);
    u8g2.print(day1.high);
    u8g2.setCursor(68, 15);
    u8g2.print("C");

    u8g2.drawLine(87, 5, 87, 31);

    u8g2.setCursor(107, 15);
    u8g2.print(day1.date_m);

    

    u8g2.setFont(u8g2_font_tenstamps_mn);
    u8g2.setCursor(93, 31);
    u8g2.print(day1.date_d);

    
    switch(day1.code_day)  //将天气代码转化为天气图标和字符显示
    {
        case 0:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Sunny );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Sunny");
            break;
        case 4:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Cloudy );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Cloudy");
            break;
        case 9:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Overcast );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Overcast");
            break;
        case 10:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Shower );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Shower");
            break;
        case 11:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Thundershower );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Thunder");
            break;
        case 13:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_L );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"L-Rain");
            break;
        case 14:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_M );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"M-Rain");
            break;
        case 15:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_H );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"H-Rain");
            break;
        case 30:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Foggy );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Foggy");
            break;
        case 31:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Haze );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Haze");
            break;    
    }
    
    u8g2.sendBuffer();
    Serial.println(day1.code_day);


    delay(10000);
}

void weather_station2()  //显示后天天气
{   
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_lubB08_tr); 
    u8g2.setCursor(34, 15);
    u8g2.print(day2.low);
    u8g2.setCursor(49, 15);
    u8g2.print("-");
    u8g2.setCursor(54, 15);
    u8g2.print(day2.high);
    u8g2.setCursor(68, 15);
    u8g2.print("C");

    u8g2.drawLine(87, 5, 87, 31);

    u8g2.setCursor(107, 15);
    u8g2.print(day2.date_m);

    

    u8g2.setFont(u8g2_font_tenstamps_mn);
    u8g2.setCursor(93, 31);
    u8g2.print(day2.date_d);

    
    switch(day2.code_day)  //将天气代码转化为天气图标和字符显示
    {
        case 0:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Sunny );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Sunny");
            break;
        case 4:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Cloudy );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Cloudy");
            break;
        case 9:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Overcast );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Overcast");
            break;
        case 10:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Shower );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Shower");
            break;
        case 11:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Thundershower );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Thunder");
            break;
        case 13:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_L );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"L-Rain");
            break;
        case 14:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_M );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"M-Rain");
            break;
        case 15:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Rain_H );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"H-Rain");
            break;
        case 30:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Foggy );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Foggy");
            break;
        case 31:
            u8g2.drawXBMP( 1 , 1 , 30 , 30 , Haze );
            u8g2.setFont(u8g2_font_luBIS08_tr); 
            u8g2.drawStr(33,30,"Haze");
            break;    
    }
    
    u8g2.sendBuffer();
    Serial.println(day2.code_day);


    delay(10000);
}


//------------------------------------------------------------------
//---------------------------loop函数--------------------------------
//------------------------------------------------------------------
time_t prevDisplay = 0;

void loop()  //主循环,循环
{
    
    if (sta>=0 && sta<=247){
        NTP_CLOCK(prevDisplay);//时间
    }else if(sta == 248){
        NTP_DAY();//日期
    }else if(sta == 249){
        weather_station0();//当天天气
    }else if(sta == 250){
        weather_station1();//明天天气
    }else if(sta == 251){
        weather_station2();//后天天气
    }else{
        yiyan();//手写文字
    }

    ++sta;

    if(sta==253){
        sta = 0;          
    }
    
    Serial.println(Click);
}

参考资料

  • 9
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
0.9OLED显示屏驱动是一种用于控制和驱动该尺OLED显示屏的设备或电路。OLED显示屏采用有机发光二极管作为发光材料,具有高对比度、快速响应、宽视角和薄型轻便等特点,适用于各种便携式设备和电子产品。 0.9OLED显示屏驱动的主要功能是将输入信号转化为显示图像,实现图像的显示和控制。它通常包括一个控制器、对应的驱动芯片和相关电路。控制器用于接收和解码输入信号,判断显示模式和内容,并发送相应的驱动信号给驱动芯片。驱动芯片则负责根据控制器发送的信号来控制OLED显示屏的亮度、对比度、色彩和像素点的亮灭。 0.9OLED显示屏驱动通过控制像素点的发光状态来显示不同的图像或文字。OLED显示屏一般由多个像素点组成,每个像素点由一个红、绿、蓝三个子像素点构成,或者采用白色和黑色两个子像素点的组合方式。驱动芯片通常采用PWM等方式对每个子像素点的驱动电压进行调节,以达到控制亮度和颜色的效果。 除了基本的驱动功能,0.9OLED显示屏驱动还可以支持触控功能、动态图像显示、多种显示模式切换等高级特性。当连接到相应的输入设备或者外部控制器时,可以实现用户与显示屏的交互和数据传输。 总之,0.9OLED显示屏驱动是一种专门用于控制和驱动0.9OLED显示屏的设备,它通过将输入信号转换为相应的驱动信号来控制OLED显示屏的亮度、对比度、色彩和像素点的亮灭,从而实现图像和文字的显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值