开源天气时钟项目删减和更新
-
📌原项目开源地址:
https://gitee.com/liuzewen/ESP8266-SSD1306-Watch-mini
-
✨本文只针对Arduino IDE平台代码进行删减和更新。
-
📺按键菜单功能
-
🌼天气时钟功能整体架构描述
-
🔖代码中所使用的库,都可以在
Arduino IDE
管理库当中下载到。 -
TimeLib
库
-
ArduinoJson
库(直接安装最新的库)
-
U8g2
库
DS3231
📜其余库为自带库。(
ESP8266HTTPClient
、Wire
)
🌻API接口
- 📌老黄历免费API接口:天行数据密匙免费申请地址:
https://www.tianapi.com/
- ✨每天限制调用次数为:100次,每天更新频率不要高于15分钟每次。
- 📍心知天气免费API接口:
api.seniverse.com
🍁城市选择,可以自定义设定4个目标城市:设置方法如下:
void city_int(void){
strcpy(citys[0].city_name,"株洲");strcpy(citys[0].city_id,"zhuzhou");//第一个为OLED默认显示城市
strcpy(citys[1].city_name,"北京");strcpy(citys[1].city_id,"beijing");
strcpy(citys[2].city_name,"上海");strcpy(citys[2].city_id,"shanghai");
strcpy(citys[3].city_name,"长沙");strcpy(citys[3].city_id,"changsha");
}
- �
- 🎈哔哩哔哩站ID自己更换为自己的ID好即可。
🚩OLED接口说明
OLED 默认采用的是1.3寸的I2C接口,(SDA:D2,SCL:D1)保留0.96寸oled屏幕函数接口,启用相关函数即可。
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // 1.3寸,默认引脚:sda:D2,SCL:D1
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/D6, /* data=*/D5); // 1.3寸,指定引脚
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);//0.96寸,默认引脚
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); //0.96寸,指定引脚
⛳入网说明
- 🔖在
weather.h
头文件中,找到定义的地方,将WIFI信息修改成自己的WIFI信息。
#ifndef STASSID
#define STASSID "MERCURY_D268G"
#define STAPSK "pba5ayzk"
#endif
✅按键功能(强大)
- 🌿按键引脚定义
#define UP_KEY D3 //向上(递增)
#define M_KEY D5 //长按进入菜单设置界面,短按确认。
#define DOWN_KEY D6 //向下(递减)
#define WAKE_UP D7 //原来是控制RGB—WS2812,修改后没有配置,可以利用此引脚来接单总线外设例如DS18B20,DHT11
- 🌿功能画面显示可以通过按键来切换显示内容。
📓菜单功能一览表
📝主程序代码
/*
@功能:基于ESP8266的天气时钟
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <ArduinoJson.h>//点击这里会自动打开管理库页面: http://librarymanager/All#ArduinoJson
//#include <EEPROM.h>
#include <Ticker.h>//点击这里会自动打开管理库页面: http://librarymanager/All#Ticker
#include <math.h>
//#include <FastLED.h>
#include <WiFiUdp.h>
#include <TimeLib.h>//点击这里会自动打开管理库页面: http://librarymanager/All#TimeLib
#include <U8g2lib.h>//点击这里会自动打开管理库页面: http://librarymanager/All#U8g2
#include "weather.h"
#include <DS3231.h>//点击这里会自动打开管理库页面: http://librarymanager/All#DS3231
#include <Wire.h>
//引入字体
#include"font.h"
//视频播放服务器地址
//const char* badapple_Server = "192.168.0.113";//你的电脑IP,win+R后,输入ipconfig查看
//const int badapple_Port = 715;//上位机中默认端口
//short badapple_Status = 0;
//uint8_t badapple[1024]={}; //128 * 64 / 8 = 1024
//显示器定时关闭定时器
Ticker openDisplay;
//DS3231初始化
DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
//网络时钟定义
static const char ntpServerName[] = "time1.aliyun.com";//NTP服务器
const int timeZone = 8; //时区
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP 端口
time_t prevDisplay = 0; // when the digital clock was displayed
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // 1.3寸,默认引脚:sda:D2,SCL:D1
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/D6, /* data=*/D5); // 1.3寸,指定引脚
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);//0.96寸,默认引脚
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); //0.96寸,指定引脚
//天气WiFiClient
WiFiClient client;
//哔哩哔哩HTTPClient
HTTPClient bilibili_client1;
HTTPClient bilibili_client2;
//badapple的WiFiClient
//WiFiClient badapple_client;
void offDisplay();//关屏幕回调函数
uint8_t KEY_Scan(uint8_t mode);//按键扫描函数1
uint8_t KEY_Scan2(void);//按键扫描函数2
char *num_week(uint8_t dayofweek,int Mode);//计算星期
void page_int(char * name,uint8_t cur,uint8_t row,long time);//初始化所有页码
void gpio_int(void);//初始化IO口
void city_int(void);//初始化城市结构体数组
void OLED_int(void);//初始化0.96OLED
void bilibili_int(void);//初始化bilibili请求
void bilibili_http_get(void);//从http更新哔哩哔哩数据
void get_time(void);//获取时间到TIME_NOW,由TIME_MODE决定是DS3231时间还是NTP网络时间
void Desktop1(void);//桌面1(天气时钟)
void Desktop2(void);//桌面2(bilibili粉丝数)
void set_page(void);//设置界面
void update_time(void);//更新NTP时间到DS3231
void Http_NongLi();//获取农历json数据
bool autoConfig(void);//自动联网
//void smartConfig(void);//smartConfig智能配网
bool sendRequest(const char* host, const char* cityid, const char* apiKey); //发送连接
bool skipResponseHeaders(void);
void readReponseContent(char* content, size_t maxSize);
void stopConnect(void);//停止请求
void clrEsp8266ResponseBuffer(void);//清理缓存
bool parseUserData(char* content);//拷贝信息进userDatd内
void classified_weather(void);//对天气按照天气图标进行分类
void drawWeather(void);//画天气图标
void HariChord(int frame);//几何动画
void boot_animation(void);//开机动画
void print_firmware_information(void);//打印系统参数,固件版本信息
//void BasicOTAINT(void);//OTA无线升级初始化
void FONT_16_2(const unsigned char chr,int *point);//十六进制转数组
time_t getNtpTime(void);
void sendNTPpacket(IPAddress &address);
void setup(){
Serial.begin(BAUD_RATE);//串口初始化
print_firmware_information();//打印版本信息
WiFi.mode(WIFI_STA); //设置ESP32工作模式为无线终端模式
WiFi.begin(STASSID, STAPSK);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
WIFI_MODE =1;
Serial.println(WiFi.SSID().c_str());
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
gpio_int();//初始化IO口
city_int();//初始化城市列表
OLED_int();//初始化0.96OLED
delay(100);
boot_animation();//开机动画
ESP.wdtEnable(5000);//看门狗初始化
//配置网络
u8g2.begin(); //初始化OLED
Udp.begin(localPort);
setSyncProvider(getNtpTime);
setSyncInterval(300);
Wire.begin();//初始化IIC总线
//NTP网络时钟就绪
get_time();//获取一次网络时间,后面的农历json需要当前日期作为参数调用
bilibili_int();//初始化bilibili请求
//初始各标志位时间
LastWeatherTime = millis();//天气获取
LastRtcTime = millis();//时间刷新
DATA_UPDATA = 1;
LED_OFF;//关灯
delay(500);
Http_NongLi();//农历数据
DebugPrintln("*********************************初始化结束,进入loop函数!***********************************");
}
void loop(){
if(WIFI_MODE){
//检测client客户端是否连接
while (!client.connected()){
if (!client.connect(host, 80)){
LED_PWM;//闪灯
delay(300);
ESP.wdtFeed();// 喂 狗
}
}
//获取天气
if(millis()-LastWeatherTime >= WeatherDelay||DATA_UPDATA){
DATA_UPDATA = 0;
// if(RGB_KEY==1)
// u8g2.clearBuffer();
// u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
// u8g2.setCursor(16, 36);
// u8g2.print("更新信息中......");
// u8g2.sendBuffer();
LastWeatherTime = millis();
LED_ON;
delay(100);
LED_OFF;
if(Desktop_Mode == TIME_WEATHER){
if(sendRequest(host, citys[which_city-1].city_id, APIKEY) && skipResponseHeaders()){
clrEsp8266ResponseBuffer();
readReponseContent(response, sizeof(response));
parseUserData(response);//拷贝需要的信息进userData
classified_weather();
}
}
else if(Desktop_Mode == BILIBILI){
bilibili_http_get();//请求哔哩哔哩数据
}
}
}
//获取本地时间并显示
if(millis()-LastRtcTime >= RtcDelay){
LastRtcTime = millis();
get_time();
Battery_capacity = analogRead(ADC_PIN);//获取电量
switch (Desktop_Mode)
{
case TIME_WEATHER:
Desktop1();
break;
case BILIBILI:
Desktop2();
break;
default:
break;
}
}
//获取本地时间并显示
if(millis()- NongLiTime >= NongLiDelay){
Http_NongLi() ;
}
uint8_t KEY=KEY_Scan2();//扫描按键
switch(KEY){
case NO_KEY_PRES:
//无按键按下,直接跳出,加快运行时间
break;
case UP_KEY_PRES:
DebugPrintln("*************TIME_MODE切换***************");
/* 如果没有DS3231就不启用下面的语句 */
// if(TIME_MODE == DS3231_TIME_MODE)
// TIME_MODE = NTP_TIME_MODE;
// else
// TIME_MODE = DS3231_TIME_MODE;
break;
case M_KEY_PRES:
u8g2.setPowerSave(LOW);
openDisplay.once_ms(openOledTime, offDisplay);//定时器初始化
break;
case DOWN_KEY_PRES:
//判断是否需要获取网络时间更新到DS3231上
if(WIFI_MODE)
update_time();
break;
case WAKE_UP_PRES:
u8g2.setPowerSave(LOW);
openDisplay.once_ms(openOledTime, offDisplay);//定时器初始化
break;
case M_KEY_LONG_PRES:
set_page();
break;
case WAKE_UP_LONG_PRES:
set_page();
break;
}
ESP.wdtFeed();// 喂 狗
}
/*
@功能:定时关闭显示屏回调函数
*/
void offDisplay(){
DebugPrintln("************5s后关闭OLED***************");
u8g2.setPowerSave(HIGH);//关屏幕
}
/*
@功能:获取时间
@参数:0:DS3231_TIME_MODE
1:NTP_TIME_MODE
*/
void get_time(void){
// if(TIME_MODE){
prevDisplay = now();
TIME_NOW.years = year();
// Serial.print(TIME_NOW.years);
TIME_NOW.months = month();
// Serial.print(TIME_NOW.months);
TIME_NOW.days = day();
// Serial.print(TIME_NOW.days);
TIME_NOW.hours = hour();
TIME_NOW.minutes = minute();
TIME_NOW.seconds = second();
TIME_NOW.weeks = weekday();
/*
}else{
TIME_NOW.years = Clock.getYear()+2000;
TIME_NOW.months = Clock.getMonth(Century);
TIME_NOW.days = Clock.getDate();
TIME_NOW.hours = Clock.getHour(h12, PM);
TIME_NOW.minutes = Clock.getMinute();
TIME_NOW.seconds = Clock.getSecond();
TIME_NOW.weeks = Clock.getDoW();
}
*/
}
/*
@功能:按键处理函数1
@参数:mode
0:不支持连按
1:支持连按
@返回值:0:无按键按下
*/
uint8_t KEY_Scan(uint8_t mode){
uint8_t key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEYU==0||KEYM==0||KEYD==0||KEYW==0))
{
delay(4);//去抖动
key_up=0;
if(KEYU==0)return 1;
else if(KEYM==0)return 2;
else if(KEYD==0)return 3;
else if(KEYW==0)return 4;
}else if(KEYU==1||KEYM==1||KEYD==1||KEYW==1)key_up=1;
return 0;// 无按键按下
}
/*
@功能:按键处理函数2
@返回值:短按||长按 下某个按键
*/
uint8_t KEY_Scan2(void){
uint8_t KEY = KEY_Scan(0);
switch(KEY)
{
case UP_KEY_PRES:
up_pres_time = millis();
break;
case M_KEY_PRES:
m_pres_time = millis();
break;
case DOWN_KEY_PRES:
down_pres_time = millis();
break;
case WAKE_UP_PRES:
wake_pres_time = millis();
break;
}
while(KEYU==0||KEYM==0||KEYD==0||KEYW==0)
{
if(up_pres_time!=0 && millis()-up_pres_time >= key_long_pres_time){
KEY = UP_KEY_LONG_PRES;
}
else if(m_pres_time!=0 && millis()-m_pres_time >= key_long_pres_time){
KEY = M_KEY_LONG_PRES;
}
else if(down_pres_time!=0 && millis()-down_pres_time >= key_long_pres_time){
KEY = DOWN_KEY_LONG_PRES;
}
else if(wake_pres_time!=0 && millis()-wake_pres_time >= key_long_pres_time){
KEY = WAKE_UP_LONG_PRES;
}
ESP.wdtFeed();// 喂 狗
}
up_pres_time = 0;
m_pres_time = 0;
down_pres_time = 0;
wake_pres_time = 0;
return KEY;
}
/*
@功能:判断星期并赋值
*/
char week1[10],week2[8],week3[2],week4[4];
char *num_week(uint8_t dayofweek,int Mode){
switch(dayofweek)
{
case 1:
strcpy(week1,"Sunday");
strcpy(week2,"周日");
strcpy(week3,"Su");
strcpy(week4,"日");
break;
case 2:
strcpy(week1,"Monday");
strcpy(week2,"周一");
strcpy(week3,"Mo");
strcpy(week4,"一");
break;
case 3:
strcpy(week1,"Tuesday");
strcpy(week2,"周二");
strcpy(week3,"Tu");
strcpy(week4,"二");
break;
case 4:
strcpy(week1,"Wednesday");
strcpy(week2,"周三");
strcpy(week3,"We");
strcpy(week4,"三");
break;
case 5:
strcpy(week1,"Thursday");
strcpy(week2,"周四");
strcpy(week3,"Th");
strcpy(week4,"四");
break;
case 6:
strcpy(week1,"Friday");
strcpy(week2,"周五");
strcpy(week3,"Fr");
strcpy(week4,"五");
break;
case 7:
strcpy(week1,"Saturday");
strcpy(week2,"周六");
strcpy(week3,"Sa");
strcpy(week4,"六");
break;
default:
strcpy(week1,"NO");
strcpy(week2,"无");
strcpy(week3,"NO");
strcpy(week4,"无");
break;
}
switch(Mode)
{
case 1: return week1; break;
case 2: return week2; break;
case 3: return week3; break;
case 4: return week4; break;
}
}
/*
@功能:初始化翻页参数
*/
void page_int(char * name,uint8_t cur,uint8_t row,long time){
strcpy(set_up_page.name,name);
set_up_page.cursor = cur;
set_up_page.rows = row;
set_up_page.time = time;
}
/*
@功能:初始化IO口
*/
void gpio_int(void){
pinMode(LED,OUTPUT);
pinMode(WAKE_UP,INPUT_PULLUP);
pinMode(UP_KEY,INPUT_PULLUP);
pinMode(M_KEY,INPUT_PULLUP);
pinMode(DOWN_KEY,INPUT_PULLUP);
LED_OFF;//关灯
}
/*
@功能:初始化城市结构体数组
*/
void city_int(void){
strcpy(citys[0].city_name,"株洲");strcpy(citys[0].city_id,"zhuzhou");//第一个为OLED默认显示地点
strcpy(citys[1].city_name,"北京");strcpy(citys[1].city_id,"beijing");
strcpy(citys[2].city_name,"上海");strcpy(citys[2].city_id,"shanghai");
strcpy(citys[3].city_name,"长沙");strcpy(citys[3].city_id,"changsha");
}
/*
@功能:初始化0.96OLED
*/
void OLED_int(void){
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.setDisplayRotation(U8G2_R0);//设置显示器方向
U8G2_OLED_R = 0;//OLED方向标志位置0(水平)
u8g2.setContrast(OLED_Brightness);//设置OLED亮度
u8g2.setDrawColor(1);//设置绘制颜色
u8g2.setPowerSave(LOW);//默认屏幕亮
}
/*
@功能:初始化bilibili请求
*/
void bilibili_int(void){
//设置超时
bilibili_client1.setTimeout(HTTP_TIMEOUT);
bilibili_client2.setTimeout(HTTP_TIMEOUT);
//设置哔哩哔哩请求url
bilibili_client1.begin(client,String(bilibili_HOST) + "/x/relation/stat?vmid=" + String(bilibili_UID));//粉丝数
bilibili_client2.begin(client,String(bilibili_HOST) + "/x/space/upstat?mid=" + String(bilibili_UID));//播放量
}
/*
@功能:从http更新哔哩哔哩数据
*/
void bilibili_http_get(void){
// StaticJsonBuffer<1024> jsonBuffer;
// StaticJsonDocument<256> jsonBuffer;
int httpCode1 = bilibili_client1.GET();
if(httpCode1 > 0 && httpCode1==HTTP_CODE_OK)
{
String response = bilibili_client1.getString();
DebugPrintln(response);
// JsonObject& root = jsonBuffer.parseObject(response);
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, response);
//if (error) return;
BILI_NOW_DATE.follower = doc["data"]["follower"];
BILI_NOW_DATE.following = doc["data"]["following"];
}
bilibili_client1.end();
int httpCode2 = bilibili_client2.GET();
if(httpCode2 > 0 && httpCode2==HTTP_CODE_OK)
{
String response = bilibili_client2.getString();
DebugPrintln(response);
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, response);
//if (error) return;
BILI_NOW_DATE.view = doc["data"]["archive"]["view"];
BILI_NOW_DATE.likes = doc["data"]["likes"];
}
bilibili_client2.end();
}
void Http_NongLi() {
String nongli_line;
String DateAddress = "http://api.tianapi.com/txapi/lunar/index?key=";
DateAddress +=tianxingkey;
DateAddress +="&date=";
DateAddress +=String(TIME_NOW.years);
DateAddress +="-";
DateAddress +=String(TIME_NOW.months);
DateAddress +="-";
DateAddress +=String(TIME_NOW.days);
DebugPrintln(DateAddress.c_str());
WiFiClient client;
HTTPClient https;
if (https.begin(client, DateAddress))
{ // HTTPS
int httpCode = https.GET();
if (httpCode > 0)
{
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
{
String str0 = https.getString();
nongli_line = str0.substring(str0.lastIndexOf("lunardate"), str0.lastIndexOf(",\"lunar_festival"));
nongli_line = "{\"" + nongli_line + "}";
DebugPrintln(nongli_line.c_str());
} else {
Serial.println(" connection failed!");
}
/*json数据静态解析*/
StaticJsonDocument<48> doc;
DeserializationError error = deserializeJson(doc, nongli_line);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
// return "error";
}
// const char* lubarmonth = doc["lubarmonth"]; // "七月"
// const char* lunarday = doc["lunarday"]; // "十六"
const char* lunarday = doc["lunardate"]; // "2022-12-16"
// NongLiData = String(lubarmonth) + String(lunarday);
NongLiData = String(lunarday);
Serial.printf("农历: %s \r\n", NongLiData.c_str());
//断开客户端与服务器连接工作
client.stop();
https.end();
}
}
}
/*
@功能:桌面1
@参数:time_show:系统时间
userData:天气情况
*/
void Desktop1(void){
u8g2.clearBuffer();
//画天气图案(没有网络的话显示断网)
if(WIFI_MODE == 1)
drawWeather();
else
{
u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
u8g2.drawGlyph(0, 16, 197);
}
//显示 年-月-日
u8g2.setFont(u8g2_font_6x10_mf);
u8g2.setCursor(67, 11);
u8g2.print(TIME_NOW.years);
u8g2.drawStr(91,11,".");
u8g2.setCursor(97, 11);
if(TIME_NOW.months>=10)
u8g2.print(TIME_NOW.months);
else{
u8g2.print("0");
u8g2.setCursor(104,11);
u8g2.print(TIME_NOW.months);
}
u8g2.drawStr(109,11,".");
u8g2.setCursor(115, 11);
if(TIME_NOW.days>=10)
u8g2.print(TIME_NOW.days);
else{
u8g2.print("0");
u8g2.setCursor(123,11);
u8g2.print(TIME_NOW.days);
}
//显示 IP地址
// u8g2.drawStr(0,63,"IP:");
// u8g2.setCursor(22, 63);
// u8g2.print(WiFi.localIP());
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
String str = "农历:" + NongLiData;//农历内容显示
u8g2.setCursor(0,63);
u8g2.println(str.c_str());
//显示 星期(day of week)
u8g2.setFont(u8g2_font_wqy12_t_gb2312);
u8g2.setCursor(114, 63);
u8g2.print(num_week(TIME_NOW.weeks,4));
// u8g2.setCursor(112, 63);
// u8g2.print(num_week(TIME_NOW.weeks,2));
//显示 时-分-秒
u8g2.setFont(u8g2_font_inb21_mn);
u8g2.setCursor(3,42);
if(TIME_NOW.hours>=10)
u8g2.print(TIME_NOW.hours);
else{
u8g2.print("0");
u8g2.setCursor(23,42);
u8g2.print(TIME_NOW.hours);
}
u8g2.drawStr(42,40,":");
u8g2.setCursor(60,42);
if(TIME_NOW.minutes>=10)
u8g2.print(TIME_NOW.minutes);
else{
u8g2.print("0");
u8g2.setCursor(80,42);
u8g2.print(TIME_NOW.minutes);
}
u8g2.setFont(u8g2_font_ncenR12_tf);
u8g2.drawStr(100,42,":");
u8g2.setCursor(110,42);
if(TIME_NOW.seconds>=10)
u8g2.print(TIME_NOW.seconds);
else{
u8g2.print("0");
u8g2.setCursor(120,42);
u8g2.print(TIME_NOW.seconds);
}
//显示电量
//u8g2.drawRBox(100,18,(Battery_capacity*20)/1024,8,3);
u8g2.drawRBox(102,18,20,8,3);
u8g2.drawRBox(122,20,2,4,1);
u8g2.sendBuffer();
}
/*
@功能:桌面2(bilibili粉丝数)
*/
void Desktop2(void){
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.drawXBMP(36,-1, bilibili_bmp_x, bilibili_bmp_y, bilibili_bmp);
u8g2.setCursor(10, 16*2+1);
u8g2.print("粉丝数:");
u8g2.setCursor(70, 16*2+1);
u8g2.print(BILI_NOW_DATE.follower);
u8g2.setCursor(10, 16*3-1);
u8g2.print("点赞数:");
u8g2.setCursor(70, 16*3-1);
u8g2.print(BILI_NOW_DATE.likes);
u8g2.setCursor(10, 16*4-2);
u8g2.print("播放量:");
u8g2.setCursor(70, 16*4-2);
u8g2.print(BILI_NOW_DATE.view);
u8g2.sendBuffer();
}
/*
@功能:设置界面
*/
void set_page(void){
int8_t x,y;
bool x_r,y_r;
page_int("设置",1,12,millis());//初始化页
DebugPrintln("*************进入设置***************");
openDisplay.detach();//关定时器
u8g2.setPowerSave(LOW);//开显示屏
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_open_iconic_all_6x_t);
u8g2.drawGlyph(40,55,129);
u8g2.sendBuffer();
delay(1000);
while(true){
//防止光标位置错
//set_up_page.cursor = set_up_page.cursor<=1 ? 1:set_up_page.cursor;
set_up_page.cursor = set_up_page.cursor < 1 ? set_up_page.rows:set_up_page.cursor;
//set_up_page.cursor = set_up_page.cursor>=set_up_page.rows ? set_up_page.rows:set_up_page.cursor;
set_up_page.cursor = set_up_page.cursor > set_up_page.rows ? 1:set_up_page.cursor;
//刷新屏幕millis()-set_up_page.time >= set_up_page.refresh_time
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
uint8_t PAGE = (set_up_page.cursor%4 == 0 ? (set_up_page.cursor/4)-1:set_up_page.cursor/4);
switch(PAGE)
{
case 0:
u8g2.setCursor(20, 16*1-2);
u8g2.print(" 1.桌面设置");
u8g2.setCursor(20, 16*2-2);
u8g2.print(" 2.屏幕设置");
u8g2.setCursor(20, 16*3-2);
u8g2.print(" 3.网络信息");
u8g2.setCursor(20, 16*4-2);
u8g2.print(" 4.智能配网");
break;
case 1:
u8g2.setCursor(20, 16*1-2);
u8g2.print(" 5.时间设置");
u8g2.setCursor(20, 16*2-2);
u8g2.print(" 6.天气设置");
u8g2.setCursor(20, 16*3-2);
u8g2.print(" 7.刷新时间");
u8g2.setCursor(20, 16*4-2);
u8g2.print(" 8.版本信息");
break;
case 2:
u8g2.setCursor(20, 16*1-2);
u8g2.print(" 9.RGB点阵屏");
u8g2.setCursor(18, 16*2-2);
u8g2.print("10.视频播放");
u8g2.setCursor(18, 16*3-2);
u8g2.print("11.烧屏测试");
u8g2.setCursor(18, 16*4-2);
u8g2.print("12.退出设置");
break;
}
//显示光标
u8g2.setFont(u8g2_font_open_iconic_all_1x_t);
u8g2.drawGlyph(5, 16*(set_up_page.cursor%4==0? 4:set_up_page.cursor%4)-4,118);
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键2
if(KEY == WAKE_UP_LONG_PRES)
break;
else if(KEY == M_KEY_LONG_PRES)
break;
switch(KEY)
{
case UP_KEY_PRES:
set_up_page.cursor --;
break;
case M_KEY_PRES:
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(0,0);
u8g2.print(set_up_page.cursor);
u8g2.sendBuffer();
switch(set_up_page.cursor){
case 1:
while(true){
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();//重新赋值
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(24, 16*1-2);
u8g2.print(" 桌面");
u8g2.setCursor(20, 16*2-2);
u8g2.print(" 1.天气时钟");
u8g2.setCursor(20, 16*3-2);
u8g2.print(" 2.bilibili粉丝");
//显示光标
u8g2.setFont(u8g2_font_open_iconic_all_1x_t);
u8g2.drawGlyph(5, 16*(Desktop_Mode+1)-4,118);
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
if(KEY == DOWN_KEY_PRES){
Desktop_Mode ++;
Desktop_Mode = Desktop_Mode > 2 ? 2:Desktop_Mode;
}
if(KEY == UP_KEY_PRES){
Desktop_Mode --;
Desktop_Mode = Desktop_Mode < 1 ? 1:Desktop_Mode;
}
ESP.wdtFeed();// 喂 狗
}
u8g2.clearBuffer();
switch (Desktop_Mode)
{
case TIME_WEATHER:
u8g2.setFont(u8g2_font_cupcakemetoyourleader_tr);
u8g2.drawStr(50,36,"Weather");
u8g2.setFont(u8g2_font_open_iconic_all_6x_t);
u8g2.drawGlyph(0, 52, 187);//正无穷标志
break;
case BILIBILI:
u8g2.drawXBMP(32,-1, bilibili_head_x, bilibili_head_y, bilibili_head);
break;
default:
break;
}
u8g2.sendBuffer();
delay(1000);
DATA_UPDATA = 1;
break;
case 2://亮度设置搞定
while(true){
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();//重新赋值
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(0,27);
u8g2.print("屏幕亮度:");
u8g2.setCursor(64,27);
u8g2.print((OLED_Brightness*100)/255);
u8g2.setCursor((OLED_Brightness*100)/255>=100 ? 88:80,27);
u8g2.print("%");
u8g2.drawRBox(0,36,(OLED_Brightness*128)/255,16,5);
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
if(KEY == UP_KEY_PRES){
OLED_Brightness += 20;
OLED_Brightness = OLED_Brightness > 255 ? 255:OLED_Brightness;
u8g2.setContrast(OLED_Brightness);//设置OLED亮度
}
if(KEY == DOWN_KEY_PRES){
OLED_Brightness -= 20;
OLED_Brightness = OLED_Brightness < 21 ? 20:OLED_Brightness;
u8g2.setContrast(OLED_Brightness);//设置OLED亮度
}
ESP.wdtFeed();// 喂 狗
}
break;
case 3://已完成WIFI信息
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(36,16*1-2);
u8g2.print("WIFI信息");
u8g2.setCursor(0,16*2-2);
u8g2.print("SSID:");
u8g2.setCursor(37,16*2-2);
u8g2.print(WiFi.SSID().c_str());
u8g2.setCursor(0,16*3-2);
u8g2.print("PSWD:");
u8g2.setCursor(42,16*3-2);
u8g2.print(WiFi.psk().c_str());
u8g2.setCursor(0,16*4-2);
u8g2.print("IP:");
u8g2.setCursor(18,16*4-2);
u8g2.print(WiFi.localIP());
u8g2.sendBuffer();
while(true){
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
ESP.wdtFeed();// 喂 狗
}
break;
case 4://已完成配网
Get_SmartConfig = true;
goto TIAOCHU;
break;
case 5://时间模式完成
while(true){
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();//重新赋值
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(36,16*1-2);
u8g2.print("时间模式");
if(TIME_MODE==DS3231_TIME_MODE){
u8g2.setCursor(36,16*3-2);
u8g2.print("DS3231源");
}
else{
u8g2.setCursor(32,16*3-2);
u8g2.print("NTP网络源");
}
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
if(KEY == UP_KEY_PRES)
TIME_MODE = !TIME_MODE;
if(KEY == DOWN_KEY_PRES)
TIME_MODE = !TIME_MODE;
ESP.wdtFeed();// 喂 狗
}
break;
case 6:
while(true){
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();//重新赋值
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(0,16*2-2);
u8g2.print("城市名称:");
u8g2.setCursor(70,16*2-2);
u8g2.print(citys[which_city-1].city_name);
u8g2.setCursor(0,16*3-2);
u8g2.print("城市ID:");
u8g2.setCursor(55,16*3-2);
u8g2.print(citys[which_city-1].city_id);
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
if(KEY == UP_KEY_PRES){
which_city += 1;
which_city = which_city >= city_num ? city_num:which_city;
}
if(KEY == DOWN_KEY_PRES){
which_city -= 1;
which_city = which_city <= 1 ? 1:which_city;
}
ESP.wdtFeed();// 喂 狗
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(0,16*3-8);
u8g2.print("城市设置为:");
u8g2.setCursor(90,16*3-8);
u8g2.print(citys[which_city-1].city_name);
u8g2.sendBuffer();
delay(1000);
break;
case 7:
while(true){
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();//重新赋值
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(0,40);
u8g2.print("更新时间:");
u8g2.setCursor(WeatherDelay/(60*1000)>=10 ? 64:72,40);
u8g2.print(WeatherDelay/(60*1000));
u8g2.setCursor(80,40);
u8g2.print(WeatherDelay%(60*1000)==0 ? ".0":".5");
u8g2.setCursor(96,40);
u8g2.print("分钟");
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
if(KEY == UP_KEY_PRES){
WeatherDelay += 30*1000;
WeatherDelay = WeatherDelay >=10*60*1000 ? 10*60*1000:WeatherDelay;
}
if(KEY == DOWN_KEY_PRES){
WeatherDelay -= 30*1000;
WeatherDelay = WeatherDelay <=30*1000 ? 30*1000:WeatherDelay;
}
ESP.wdtFeed();// 喂 狗
}
break;
case 8://固件版本完成
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(36,16*1-2);
u8g2.print("版本信息");
u8g2.setCursor(0,16*2-2);
u8g2.print("固件版本:");
u8g2.setCursor(63,16*2-2);
u8g2.print(Firmware_version);
u8g2.setCursor(0,16*3-2);
u8g2.print("固件大小:");
u8g2.setCursor(63,16*3-2);
u8g2.print(ESP.getSketchSize()/1024);
u8g2.setCursor(84,16*3-2);
u8g2.print("KBytes");
while(true){
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
ESP.wdtFeed();// 喂 狗
}
break;
case 9://点阵开关完成
while(true){
if(millis()-set_up_page.time >= set_up_page.refresh_time){
set_up_page.time = millis();//重新赋值
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(0,40);
u8g2.print("RGB点阵屏:");
u8g2.setCursor(85,40);
if(RGB_KEY==1)
u8g2.print("-开-");
else
u8g2.print("-关-");
u8g2.sendBuffer();
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
if(KEY == UP_KEY_PRES){
RGB_KEY = !RGB_KEY;
}
if(KEY == DOWN_KEY_PRES){
RGB_KEY = !RGB_KEY;
}
ESP.wdtFeed();// 喂 狗
}
break;
/*
case 10:
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(36,40);
u8g2.print("视频播放");
u8g2.setCursor(88,40);
u8g2.sendBuffer();
while(true){
if(badapple_Status==0 && WiFi.status()==WL_CONNECTED){
badapple_Status=1;
badapple_client.connect(badapple_Server, badapple_Port);
}
while(badapple_client.available()){
badapple_client.read(badapple,1024);
delay(75);
u8g2.clearBuffer();
u8g2.drawXBMP(0, 0, 128, 64, badapple);
u8g2.sendBuffer();
ESP.wdtFeed();// 喂 狗
}
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
ESP.wdtFeed();// 喂 狗
}
badapple_client.stop();
break;
*/
case 11:
u8g2.clearBuffer();
u8g2.drawRBox(0,-1,128,64,3);
u8g2.sendBuffer();
delay(3000);
x = 0;
y = 0;
x_r = 1;
y_r = 1;
while(1){
if(x_r)x++;else x--;
if(y_r)y++;else y--;
if(x>=127-8)x_r = 0;
if(x<=0+8)x_r = 1;
if(y>=63-8)y_r = 0;
if(y<=0+8)y_r = 1;
u8g2.clearBuffer();
u8g2.drawDisc(x,y,5);
u8g2.drawCircle(x,y,8);
u8g2.sendBuffer();
ESP.wdtFeed();// 喂 狗
uint8_t KEY=KEY_Scan2();//扫描按键
if(KEY == M_KEY_PRES)
break;
}
for(int i = 0;i<=3;i++){
for (int frame=0; frame < 36; frame++)
{
HariChord(frame);
ESP.wdtFeed();// 喂 狗
}
for (int frame=(36-1); frame >= 0; frame--)
{
HariChord(frame);
ESP.wdtFeed();// 喂 狗
}
}
break;
case 12:
goto TIAOCHU;//goto语法跳出设置
break;
}
break;
case DOWN_KEY_PRES:
set_up_page.cursor ++;
break;
}
ESP.wdtFeed();// 喂 狗
}
TIAOCHU://goto语法
DebugPrintln("*************退出设置***************");
u8g2.firstPage();
do{
u8g2.setFont(u8g2_font_open_iconic_all_6x_t);
u8g2.drawGlyph(35,60,64);
}while (u8g2.nextPage());
delay(1000);
}
/*
@功能:网络时间获取更新
*/
void update_time(void){
prevDisplay = now();
Serial.println("***********更新时间***********");
Serial.print("网络时间是: ");
Serial.print(year());
Serial.print(".");
Serial.print(month());
Serial.print(".");
Serial.print(day());
Serial.print(" ");
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(":");
Serial.print(second());
Serial.print(" 星期");
Serial.println(num_week(weekday(),4));
Clock.setClockMode(false); // set to 24h
Clock.setYear(year()-2000);
Clock.setMonth(month());
Clock.setDate(day());
Clock.setDoW(weekday());
Clock.setHour(hour());
Clock.setMinute(minute());
Clock.setSecond(second());
}
/*
@功能:autoConfig 默认WIFI连网
@说明:自动连接20s超过之后自动进入无网络模式
*/
bool autoConfig(void){
WiFi.mode(WIFI_STA); // 设 置 esp8266 工 作 模 式
DebugPrint("联网至:");DebugPrintln(WiFi.SSID().c_str());DebugPrintln(WiFi.psk().c_str());
// WiFi.begin(config.stassid,config.stapsw);//连接指定的WIFI
WiFi.begin(ssid, password);
//WiFi.begin(WiFi.SSID().c_str(),WiFi.psk().c_str());//连接上次连接的WIFI
//WiFi.begin();
delay(500);// 刚 启 动 模 块 的 话 延 时 稳 定 一 下
u8g2.firstPage();
do{
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(30, 36);
u8g2.print("联网中......");
}while (u8g2.nextPage());
DebugPrint("AutoConfiging");
for(int index=0;index<100;index++){//连接20s
int wstatus = WiFi.status();
if (wstatus == WL_CONNECTED){
DebugPrintln("\nAutoConfig Success");
DebugPrint("SSID:");
DebugPrintln(WiFi.SSID().c_str());
DebugPrint("PSW:");
DebugPrintln(WiFi.psk().c_str());
return true;
}else{
DebugPrint(".");
delay(200);
LED_PWM;
}
}
DebugPrintln("自动联网->失败!");
u8g2.firstPage();
do{
u8g2.setFont(u8g2_font_wqy14_t_gb2312a);
u8g2.setCursor(16, 36);
u8g2.print("联网失败......");
}while (u8g2.nextPage());
return false;
}
/*
@功能:发送请求指令
*/
bool sendRequest(const char* host, const char* cityid, const char* apiKey){
// We now create a URI for the request
// 心 知 天 气
String GetUrl = "/v3/weather/now.json?key=";
GetUrl += apiKey;
GetUrl += "&location=";
GetUrl += cityid;
GetUrl += "&language=";
GetUrl += language;
// This will send the request to the server
client.print(String("GET ") + GetUrl + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
DebugPrintln("create a request:");
DebugPrintln(String("GET ") + GetUrl + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n");
delay(1000);
return true;
}
/*
@功能:Desc跳过HTTP头,使我们在响应正文的开头
*/
bool skipResponseHeaders(){
// HTTP headers end with an empty line
bool ok = client.find(endOfHeaders);
if(!ok){
DebugPrintln("No response or invalid response!");
}
return ok;
}
/*
@功能:Desc从HTTP服务器响应中读取正文
*/
void readReponseContent(char* content, size_t maxSize){
size_t length = client.readBytes(content, maxSize);
delay(100);
DebugPrintln("Get the data from Internet!");
content[length] = 0;
DebugPrintln(content);
DebugPrintln("Read data Over!");
client.flush();
//这句代码需要加上不然会发现每隔一次client.find会失败
}
//关闭与HTTP服务器连接
void stopConnect(){
client.stop();
}
void clrEsp8266ResponseBuffer(void){
memset(response, 0, MAX_CONTENT_SIZE);//清空
}
bool parseUserData(char* content){
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, content);
if (error) {
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
}
//复制我们感兴趣的字符串
strcpy(userData.city, doc["results"][0]["location"]["name"]);
strcpy(userData.weather_code, doc["results"][0]["now"]["code"]);
strcpy(userData.temp, doc["results"][0]["now"]["temperature"]);
return true;
}
/*
@功能:对所有天气情况按照显示图标进行分类
*/
void classified_weather(void){
if(strcmp(userData.weather_code,WEATHER_CODE_DAY_SUN) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_DAY_SUN1) == 0){
userData.weather = SUN_DAY;
}else if(strcmp(userData.weather_code,WEATHER_CODE_NIGHT_SUN) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_NIGHT_SUN2) == 0 ){
userData.weather = SUN_NIGHT;
}else if(strcmp(userData.weather_code,WEATHER_CODE_DAY_PARTLY_CLOUDY) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_NIGHT_PARTLY_CLOUDY)== 0){
userData.weather = SUN_CLOUD;
}else if(strcmp(userData.weather_code,WEATHER_CODE_CLOUDY) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_DAY_MOSTLY_CLOUDY) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_NIGHT_MOSTLY_CLOUDY) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_OVERCAST) == 0){
userData.weather = CLOUD;
}else if(strcmp(userData.weather_code,WEATHER_CODE_SHOWER) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_LIGHT_RAIN) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_MODERATE_RAIN) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_HEAVY_RAIN) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_STORM) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_HEAVY_STORM) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_SEVERE_STORM) == 0){
userData.weather = RAIN;
}else if(strcmp(userData.weather_code,WEATHER_CODE_THUNDERSHOWER) == 0
|| strcmp(userData.weather_code,WEATHER_CODE_THUNDERSHOWER_WITH_HAIL) == 0){
userData.weather = THUNDER;
}else{
userData.weather = CLOUD;
}
}
/*
@功能:绘制天气信息图标
*/
void drawWeather(void){
u8g2.setFont(u8g2_font_open_iconic_weather_2x_t);
switch(userData.weather)
{
case SUN_DAY:// 太 阳
u8g2.drawGlyph(0, 16, 69);
break;
case SUN_NIGHT:// 太 阳
u8g2.drawGlyph(0, 16, 66);
break;
case SUN_CLOUD:// 晴 间 多 云
u8g2.drawGlyph(0, 16, 65);
break;
case CLOUD:// 多 云
u8g2.drawGlyph(0, 16, 64);
break;
case RAIN:// 下 雨
u8g2.drawGlyph(0, 16, 67);
break;
case THUNDER:// 打 雷
u8g2.drawGlyph(0, 16, 67);
break;
}
u8g2.setFont(u8g2_font_9x15_t_symbols);// 绘 制 温 度
u8g2.setCursor(20, 13);
u8g2.print(userData.temp);
u8g2.print("°C");
}
/*
@功能:几何动画
*/
void HariChord(int frame)
{
int nFrames = 36;
u8g2.clearBuffer();
int n = 7;
int r = frame * 64 / nFrames;
float rot = frame * 2*PI / nFrames;
for (int i=0; i<(n-1); i++)
{
float a = rot + i * 2*PI / n;
int x1 = 64 + cos(a) * r;
int y1 = 32 + sin(a) * r;
for (int j=i+1; j<n; j++)
{
a = rot + j * 2*PI / n;
int x2 = 64 + cos(a) * r;
int y2 = 32 + sin(a) * r;
u8g2.drawLine(x1,y1, x2,y2);
}
ESP.wdtFeed();// 喂 狗
}
u8g2.sendBuffer();
}
/*
@功能:开机动画
*/
void boot_animation(){
//爱心眼睛
const static unsigned char FACE_Love[] 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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0xE0,0x07,0x3F,0xE0,0x00,0x0C,0xF0,0x81,0x0F,0x30,0x00,0x38,0xF0,0x8B,0x5F,0xE0,0x00,0x0C,0xF8,0xC2,0x1F,0x30,0x00,0x38,0xF8,0xD7,0xBF,0xE0,0x00,0x0C,0xFC,0xE5,0x2F,0x30,0x00,0x38,0xF8,0xFF,0xBF,0xE0,0x00,0x0C,0xFE,0xFF,0x5F,0x30,0x00,0x38,0xFC,0xFF,0x7F,0xE0,0x00,0x0C,0xFE,0xFF,0x5F,0x30,0x00,0x38,0xFC,0xFF,0xFF,0xE1,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xFC,0xFF,0xFF,0xE1,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xFC,0xFF,0xFF,0xE1,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xF8,0xFF,0xFF,0xE0,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xF8,0xFF,0xFF,0xE0,0x00,0x0C,0xFE,0xFF,0x7F,0x30,0x00,0x38,0xF8,0xFF,0xFF,0xE0,0x00,0x0C,0xFC,0xFF,0x3F,0x30,0x00,0x38,0xF0,0xFF,0x7F,0xE0,0x00,0x0C,0xF8,0xFF,0x1F,0x30,0x00,0x38,0xC0,0xFF,0x1F,0xE0,0x00,0x0C,0xF0,0xFF,0x0F,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xE0,0xFF,0x07,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0x7E,0x00,0x30,0x00,0x38,0x00,0xF8,0x00,0xE0,0x00,0x0C,0x00,0x3C,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x38,0x00,0x20,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
//睁眼
const static unsigned char FACE_Neutral[] 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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x41,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x00,0x38,0x01,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0x7F,0x00,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0x38,0x00,0x7F,0x06,0xE0,0x00,0x0C,0x80,0x3F,0x01,0x30,0x00,0x38,0x40,0x7F,0x17,0xE0,0x00,0x0C,0xC0,0xDF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x0C,0xA0,0xFF,0x05,0x30,0x00,0x38,0x00,0xFC,0x01,0xE0,0x00,0x0C,0x00,0xFF,0x00,0x30,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0x0C,0x80,0x3C,0x01,0x30,0x00,0x38,0x00,0x84,0x00,0xE0,0x00,0x0C,0x00,0x42,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
//闭眼
const static unsigned char FACE_Tired_middle[] 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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x03,0x00,0x80,0xFF,0xFF,0xFF,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x0F,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0x07,0x00,0x00,0x1F,0x00,0xE0,0x03,0x00,0xC0,0x07,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0xF0,0x00,0x00,0x00,0x0F,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x1C,0xD0,0xDF,0x0B,0x38,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xC0,0xFF,0x0B,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x03,0x30,0x00,0x38,0x80,0xFF,0x0F,0xE0,0x00,0x0C,0xD0,0xFF,0x0B,0x30,0x00,0x38,0x00,0xFF,0x07,0xE0,0x00,0x0C,0xC0,0xFF,0x03,0x30,0x00,0x38,0x40,0xFF,0x17,0xE0,0x00,0x0C,0x80,0xFF,0x01,0x30,0x00,0x38,0x00,0xFE,0x03,0xE0,0x00,0x1C,0xA0,0xFF,0x05,0x38,0x00,0x70,0x00,0xFC,0x01,0x70,0x00,0x1C,0x00,0xFF,0x00,0x38,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x3C,0x80,0x3C,0x01,0x3C,0x00,0xF0,0x00,0x84,0x00,0x78,0x00,0x38,0x00,0x42,0x00,0x1C,0x00,0xE0,0x01,0x00,0x00,0x3C,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0xC0,0x03,0x00,0x00,0x1E,0x00,0xF0,0x01,0x00,0x80,0x0F,0x00,0x80,0x1F,0x00,0xC0,0x0F,0x00,0xE0,0x07,0x00,0xE0,0x07,0x00,0x00,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x00,0xFF,0xFF,0xFF,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
u8g2.firstPage();
do{u8g2.drawXBMP(20,0,89,64,FACE_Neutral);}
while (u8g2.nextPage());
delay(400);
u8g2.firstPage();
do{u8g2.drawXBMP(20,0,89,64,FACE_Tired_middle);}
while (u8g2.nextPage());
delay(100);
u8g2.firstPage();
do{u8g2.drawXBMP(20,0,89,64,FACE_Neutral);}
while (u8g2.nextPage());
delay(400);
u8g2.firstPage();
do{u8g2.drawXBMP(20,0,89,64,FACE_Tired_middle);}
while (u8g2.nextPage());
delay(100);
u8g2.firstPage();
do{u8g2.drawXBMP(20,0,89,64,FACE_Neutral);}
while (u8g2.nextPage());
delay(400);
u8g2.firstPage();
do{u8g2.drawXBMP(20,0,89,64,FACE_Love);}
while (u8g2.nextPage());
delay(300);
}
/*
@功能:打印系统参数,固件版本信息
*/
void print_firmware_information(void){
FlashMode_t ideMode = ESP.getFlashChipMode();
String coreVersion = ESP.getCoreVersion();
Serial.println("\n");
Serial.print(F("Arduino Core For ESP8266 Version: "));
Serial.println(coreVersion);
Serial.printf("\nESP8266芯片id: %u \n\n", ESP.getChipId());
Serial.printf("天气时钟固件版本: %s \n\n", Firmware_version);
Serial.print("固件编译时间:");
Serial.print(__DATE__);
Serial.print(" ");
Serial.println(__TIME__);
Serial.println();
Serial.printf("固件大小: %u KBytes\n\n", ESP.getSketchSize()/1024);
Serial.printf("剩余可用固件空间: %u KBytes\n\n", ESP.getFreeSketchSpace()/1024);
Serial.printf("Flash real id: %08X\n\n", ESP.getFlashChipId());
Serial.printf("Flash 实际大小: %u KBytes\n\n", ESP.getFlashChipRealSize()/1024);
Serial.printf("IDE配置Flash大小: %u KBytes\n\n", ESP.getFlashChipSize()/1024);
Serial.printf("IDE配置Flash频率: %u MHz\n\n", ESP.getFlashChipSpeed()/1000000);
Serial.printf("Flash ide mode: %s\n\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" : ideMode == FM_DIO ? "DIO" : ideMode == FM_DOUT ? "DOUT" : "UNKNOWN"));
}
/*
@说明:十六进制转数组
*/
void FONT_16_2(const unsigned char chr,int *point){
int a=chr;
*point= a/128;
a=a-128*(*point);point++;
*point= a/64;
a=a-64*(*point);point++;
*point= a/32;
a=a-32*(*point);point++;
*point= a/16;
a=a-16*(*point);point++;
*point= a/8;
a=a-8*(*point);point++;
*point= a/4;
a=a-4*(*point);point++;
*point= a/2;
a=a-2*(*point);point++;
*point= a;
}
/*
@功能:获取网络时间部分代码
@说明:太复杂,不看~
*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime(void){
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
// get a random server from the pool
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");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");//没连接到NTP服务器
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
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;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
-
🛠开发板配置
-
📋 编译信息
使用 1.0 版本的库 ESP8266WiFi 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi
使用 1.2 版本的库 ESP8266HTTPClient 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266HTTPClient
使用 1.2 版本的库 ESP8266mDNS 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266mDNS
使用 1.0 版本的库 ArduinoOTA 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ArduinoOTA
使用 6.20.0 版本的库 ArduinoJson 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\ArduinoJson
使用 1.0 版本的库 EEPROM 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\EEPROM
使用 1.0 版本的库 Ticker 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Ticker
使用 1.6.1 版本的库 Time 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\Time
使用 2.33.15 版本的库 U8g2 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\U8g2
使用 1.1.0 版本的库 DS3231 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\DS3231
使用 1.0 版本的库 Wire 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Wire
使用 1.0 版本的库 SPI 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SPI
"C:\\Users\\Administrator\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.0.4-gcc10.3-1757bed/bin/xtensa-lx106-elf-size" -A "d:\\arduino\\MyHexDir/ESP8266_weather_arduino.ino.elf"
项目使用了 705548 字节,占用了 (67%) 程序存储空间。最大为 1044464 字节。
全局变量使用了35768字节,(43%)的动态内存,余留46152字节局部变量。最大为81920字节。
📚程序源码
🔖请使用源码的注意,自己申请免费的API接口,不要占用我的密钥,免得找出数据访问拥挤导致获取数据失败。
链接:https://pan.baidu.com/s/1h8IlAGmscO5xiBC61P2-GA
提取码:357u