开源天气时钟项目删减和更新
Posted perseverance52
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开源天气时钟项目删减和更新相关的知识,希望对你有一定的参考价值。
开源天气时钟项目删减和更新
-
📌原项目开源地址:
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以上是关于开源天气时钟项目删减和更新的主要内容,如果未能解决你的问题,请参考以下文章
基于Lua框架下的合宙ESP32C3+1.54‘’Eink墨水屏天气时钟项目