//参考SHICHEN科技团队
//引入必要的头文件
#include <Arduino.h>
#include <U8g2lib.h>
#include <WiFi.h>
#include <SPI.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <DNSServer.h>
#include <FunctionalInterrupt.h>
WiFiUDP Udp;
unsigned int localPort = 7798; // 用于侦听UDP数据包的本地端口
int bu[4]={0,14,12,13}; //闹钟默认时间,D5,D6,D7
int no[3]={0,5,0}; //到点闹钟取消按键,暂定是震动+声音。D1
//暂没有亮灯及震动。
int bb=2; //BB响声。,D4
int gotoled=4; //当有设定闹钟是亮灯。D2
int gotoled2=0; //当有设定闹钟是亮灯。D3 已上拉,是要下拉-亮的。
//int gotoled3=15; //当有设定闹钟是亮灯。D8 已下拉,是要上拉+亮的。
int inputval=0;
int lz[4]={0,0,0,0}; //3个闹钟设置有效性。
int lzyn=1; //表示闹钟有效,当开始闹后是-1,在闹中间按取消时=0。表示停止闹,回复1为待命,当1分钟后再设置回1
String lz_str="";
int lz1[3]={0,6,30}; //设置闹钟时间6:45 现在是固定的。
int lz2[3]={0,14,20};
int lz3[3]={0,21,3};
int sstime[8]={0,0,0,0,0,0,0,0}; //记录实时时分秒。
long old_mill=0;
int uptime=0; //更新时间,实时天气,明天天气。一般至少超过1分钟更新。不必太密。
int upsstq=0;
int upmttq=0;
int gongval=0; //光敏值
int liangcs=0; //当碰到震动时显示屏时间或次数。即lzyn=0的时间。默认是10秒
//现在只接闹钟1、2。未接3。只接停闹1。
#define u8g2scl 3 //scl 真正用时改3与1后电脑串口会无提示啦,测试就用5,4。
#define u8g2sda 1
#define BUTTON1 bu[1]
#define BUTTON2 bu[2]
#define BUTTON3 bu[3]
#define BUTTON4 no[1]
//#define BUTTON5 no[2]
int ls007=0;
//网络校时的相关配置
static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,使用阿里云
int timeZone = 8; //时区设置,采用东8区
//保存断网前的最新数据
int results_0_now_temperature_int_old;
String results_0_now_text_str_old;
int results_0_daily_1_high_int_old;
int results_0_daily_1_low_int_old;
String results_0_daily_1_text_day_str_old;
String results_0_daily_1_text_night_str_old;
//函数声明
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
void oledClockDisplay();
void sendCommand(int command, int value);
void initdisplay();
void connectWiFi();
void parseInfo_now(WiFiClient client,int i);
void parseInfo_fut(WiFiClient client,int i);
//
boolean isNTPConnected = false;
const unsigned char xing[] U8X8_PROGMEM = {
0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00}; /*星*/
const unsigned char liu[] U8X8_PROGMEM = {
0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x20, 0x02, 0x20, 0x04, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x04, 0x20, 0x02, 0x20, 0x00, 0x00}; /*六*/
typedef struct
{ //存储配置结构体
int tz; //时间戳
} config_type;
config_type config;
WiFiClient clientNULL;
DNSServer dnsServer;
ESP8266WebServer server(80);
//----------WIFI连接配置----------
const char* ssid = "Tenda_JOUZY"; // 连接WiFi名(此处使用XXX为示例)
const char* password = "987654321"; // 连接WiFi密码(此处使用12345678为示例)
// 请将您需要连接的WiFi密码填入引号中
//----------天气API配置----------
const char* host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口
// 心知天气HTTP请求所需信息
String reqUserKey = "SJKrWBsUJbl2L0bAW"; // 私钥
String reqLocation = "guangzhou"; // 城市
String reqUnit = "c"; // 摄氏/华氏
//----------设置屏幕----------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE,u8g2scl,u8g2sda);
int sta = 0;
//----------初始化OLED----------
void initdisplay()
{
u8g2.begin();
u8g2.enableUTF8Print();
}
//----------用于获取实时天气的函数(0)----------
void TandW(){
String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
+ "&location=" + reqLocation +
"&language=zh-Hans&unit=" +reqUnit;
// 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes,0);
//延迟,需要低于20次/分钟
// delay(5000);
}
void display_1(int results_0_now_temperature_int,String results_0_now_text_str);//声明函数,用于显示温度、天气
//----------获取3天预报(1)----------
void threeday(){
// 建立心知天气API当前天气请求资源地址
String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
+ "&location=" + reqLocation + "&language=zh-Hans&unit=" +
reqUnit + "&start=0&days=3";
// 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes,1);
// delay(5000);
}
void clock_display(time_t prevDisplay){
server.handleClient();
dnsServer.processNextRequest();
if (timeStatus() != timeNotSet)
{
if (now() != prevDisplay)
{ //时间改变时更新显示
prevDisplay = now();
old_mill=millis();
oledClockDisplay(1); //对时。
}
}
else{
Serial.printf("无NTP对时 \n");
oledClockDisplay(0); //用原时间继续显示
}
}
// 按钮相关
class Button
{
public:
Button(uint8_t reqPin) : PIN(reqPin) {
pinMode(PIN, INPUT_PULLUP);
attachInterrupt(PIN, std::bind(&Button::isr, this), FALLING);
};
~Button() {
detachInterrupt(PIN);
}
void IRAM_ATTR isr() {
numberKeyPresses += 1;
pressed = true;
}
void checkPressed() {
if (pressed) {
// Serial.printf("LAI %u PIN %u \n",millis(),PIN);
// delay(1);
if (digitalRead(PIN) == HIGH) {
pressed = false;
return;
}
//以下按钮,只记录目标工作状态。然后由每秒屏幕显示同时确定显示内容,及是否加水及烧水,及散热等。
if (PIN != BUTTON4){
// ok_bb(1); //暂时按键也不D啦,感觉声音太大啦,反正有灯光。
}
if (PIN == BUTTON1 ) {
lz[1]=(1-lz[1]);
// digitalWrite(bb,lz[1]);
}
if (PIN == BUTTON2 ) {
lz[2]=(1-lz[2]);
digitalWrite(gotoled2,1-lz[2]); //灯指示灯2。
// digitalWrite(bb,LOW);
}
if (PIN == BUTTON3 ) {
lz[3]=(1-lz[3]);
// digitalWrite(gotoled3,lz[2]); //灯指示灯3。
}
if (PIN == BUTTON4 ) {
ls007=ls007+1;
if (ls007>3 || lzyn==1){
liangcs = 20000;
lzyn=0;
ls007=0;
}
}
// if (PIN == BUTTON5 ) {
// liangcs = 10000;
// lzyn=0;
// }
Serial.printf("按钮 pin %u has 时间 pressed %u times \n", PIN, numberKeyPresses);
pressed = false;
}
}
private:
const uint8_t PIN;
volatile uint32_t numberKeyPresses;
volatile bool pressed;
};
Button button1(BUTTON1);
Button button2(BUTTON2);
Button button3(BUTTON3);
Button button4(BUTTON4);
//Button button5(BUTTON5);
//按钮相关结束
void setup(){
Serial.begin(115200);
Serial.printf("jouzy_hhj2018.com \n");
initdisplay();
// 连接WiFi
u8g2.clearBuffer();
// u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(30, 14);
u8g2.print("智慧合和居");
u8g2.setCursor(20, 45);
u8g2.print("开心为您服务");
u8g2.sendBuffer();
connectWiFi();
Udp.begin(localPort);
setSyncProvider(getNtpTime);
setSyncInterval(300); //每300秒同步一次时间
pinMode(gotoled,OUTPUT);
pinMode(gotoled2,OUTPUT);
digitalWrite(gotoled2,HIGH); //灯指示灯2。
// pinMode(gotoled3,OUTPUT);
// digitalWrite(gotoled3,HIGH); //灯指示灯2。
pinMode(bb,OUTPUT);
digitalWrite(bb,HIGH); //灯指示灯。
}
time_t prevDisplay = 0; //当时钟已经显示
void loop(){
//以下是四个按钮:闹钟1,闹钟2,停闹1,闹钟3,。现在闹钟3无接线
button1.checkPressed();
button2.checkPressed();
button3.checkPressed();
button4.checkPressed();
// button5.checkPressed();
if (sta<5000 && (sta % 500) ==0){
clock_display(prevDisplay);
}else if(sta == 5000){
++upsstq;
if (upsstq==1){
TandW(); //实时天气
}else{
display_0(results_0_now_temperature_int_old,results_0_now_text_str_old);
}
if (upsstq>30){upsstq=0;}
}else{
if (sta==8000){
++upmttq;
if (upsstq==1){
threeday(); //明天天气
}else{
display_1(results_0_daily_1_high_int_old,results_0_daily_1_low_int_old,results_0_daily_1_text_day_str_old,results_0_daily_1_text_night_str_old);
}
if (upmttq>45){upmttq=0;}
}
}
++sta;
if(sta>11000){
sta = 0;
}
liangcs=liangcs-1;
if(liangcs<0){
liangcs = 0;
}
//每秒事情
if ((sta % 1000)==888 ){
gongval=analogRead(A0);
lz_str="闹钟";
if (lz[1]==1){
lz_str +=" ";
lz_str +=lz1[1];
lz_str +=":";
lz_str +=lz1[2];
}
if (lz[2]==1){
lz_str +=" ";
lz_str +=lz2[1];
lz_str +=":";
lz_str +=lz2[2];
}
if (lz[3]==1){
lz_str +=" ";
lz_str +=lz3[1];
lz_str +=":";
lz_str +=lz3[2];
}
gongval=analogRead(A0);
lz_str += " i"; //在闹后面显示亮度值,方便调试。暂不显示200以下为晚上
lz_str += gongval;
// lz_str += "x"; //灯状态
// lz_str += digitalRead(gotoled);
// lz_str += lzyn;
// lz_str += " y"; //在闹后面显示亮度值,方便调试。暂不显示200以下为晚上
// lz_str += ls007;
}
if ((sta % 1000)==888 && lzyn==(-1)){
ls007=0;
ok_bb(1);
}
//晚上关灯关屏
if (gongval<100 && lzyn==1){
digitalWrite(gotoled,LOW);
digitalWrite(gotoled2,HIGH);
u8g2.setPowerSave(1);
}else{
//但闹钟要有效
u8g2.setPowerSave(0);
// if ((lz[1]+lz[2]+lz[3])==0 || lzyn==0){
if ((lz[1]+lz[3])==0 ){
digitalWrite(gotoled,LOW);
}else{
if ((sta % 300)<150 && lzyn==(-1)){
digitalWrite(gotoled,LOW);
digitalWrite(gotoled2,HIGH);
}else{
digitalWrite(gotoled,HIGH);
digitalWrite(gotoled2,LOW);
}
}
if (lz[2]==0 ){
digitalWrite(gotoled2,HIGH);
}else{
if ((sta % 300)<150 && lzyn==(-1)){
digitalWrite(gotoled2,HIGH);
}else{
digitalWrite(gotoled2,LOW);
}
}
}
delay(1);
// Serial.printf("loop_good \n");
}
//无源蜂鸣器BB发声,bn是发几声【【【现在是用指示灯为BB,接口不够,但开不响,关响的哦】】
void ok_bb(int bn) {
int bbled=1; //bbled=0 表示一般拉高的BB,=1时是拉低的LED做BB。
int bbzt=0;
if (bbled==0){
int bbzt=1; //
}else{int bbzt=0;}
unsigned char i, j;
int cs = 0;
while (cs < bn)
{
cs++;
digitalWrite(bb, bbzt);
delay(150);
digitalWrite(bb, 1-bbzt);
delay(150);
// delay(100); //发BB声间隔时间
}
}
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes,int stat){
WiFiClient client;
// 建立http请求信息
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
Serial.println("");
Serial.print("Connecting to "); Serial.print(host);
// 尝试连接服务器
if (client.connect(host, 80)){
Serial.println(" Success!");
// 向服务器发送http请求信息
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest);
// 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response);
// 使用find跳过HTTP响应头
if (client.find("\r\n\r\n")) {
Serial.println("Found Header End. Start Parsing.");
}
if (stat == 0){
// 利用ArduinoJson库解析心知天气响应信息(实时数据)
parseInfo_now(client,1);
}else if(stat == 1){
parseInfo_fut(client,1);
}
}
else {
Serial.println(" connection failed!");
if (stat == 0){
// 利用ArduinoJson库解析心知天气响应信息(实时数据)
parseInfo_now(clientNULL,0);
}else if(stat == 1){
parseInfo_fut(clientNULL,0);
}
}
//断开客户端与服务器连接工作
client.stop();
}
// 连接WiFi
void connectWiFi(){
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.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
}
// 利用ArduinoJson库解析心知天气响应信息(实时)
void parseInfo_now(WiFiClient client,int i){
if(i==1){
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, client);
JsonObject results_0 = doc["results"][0];
JsonObject results_0_now = results_0["now"];
const char* results_0_now_text = results_0_now["text"]; // "Sunny"
const char* results_0_now_code = results_0_now["code"]; // "0"
const char* results_0_now_temperature = results_0_now["temperature"]; // "32"
const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00"
// 通过串口监视器显示以上信息
String results_0_now_text_str = results_0_now["text"].as<String>();
int results_0_now_code_int = results_0_now["code"].as<int>();
int results_0_now_temperature_int = results_0_now["temperature"].as<int>();
String results_0_last_update_str = results_0["last_update"].as<String>();
Serial.println(F("======Weahter Now======="));
Serial.print(F("Weather Now: "));
Serial.print(results_0_now_text_str);
Serial.print(F(" "));
Serial.println(results_0_now_code_int);
Serial.print(F("Temperature: "));
Serial.println(results_0_now_temperature_int);
Serial.print(F("Last Update: "));
Serial.println(results_0_last_update_str);
Serial.println(F("========================"));
display_0(results_0_now_temperature_int,results_0_now_text_str);
results_0_now_text_str_old = results_0_now_text_str;
results_0_now_temperature_int_old = results_0_now_temperature_int;
}
else{
display_0(results_0_now_temperature_int_old,results_0_now_text_str_old);
}
}
//----------输出实时天气----------
void display_0(int results_0_now_temperature_int,String results_0_now_text_str){
//显示输出
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(0, 14);
// u8g2.print("广州实时天气");
u8g2.print(lz_str);
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(3, 34);
u8g2.print("实");
u8g2.setCursor(3, 54);
u8g2.print("时");
u8g2.drawFrame(0,16,22,45);
u8g2.setFont(u8g2_font_logisoso32_tr);
u8g2.setCursor(20, 53);
u8g2.print(results_0_now_temperature_int);
u8g2.setFont(u8g2_font_logisoso16_tr);
u8g2.setCursor(64, 32);
u8g2.print("o");
u8g2.setFont(u8g2_font_logisoso16_tr);
u8g2.setCursor(66, 52);
u8g2.print("C");
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(80, 47);
// u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.print(results_0_now_text_str);
u8g2.sendBuffer();
}
// 利用ArduinoJson库解析心知天气响应信息(预测)
void parseInfo_fut(WiFiClient client,int i){
if(i==1){
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) + 860;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, client);
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"];
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"];
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"];
const char* results_0_daily_0_high = results_0_daily_0["high"];
const char* results_0_daily_0_low = results_0_daily_0["low"];
const char* results_0_daily_0_rainfall = results_0_daily_0["rainfall"];
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"];
const char* results_0_daily_0_wind_speed = results_0_daily_0["wind_speed"];
const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"];
const char* results_0_daily_0_humidity = results_0_daily_0["humidity"];
JsonObject results_0_daily_1 = results_0_daily[1];
const char* results_0_daily_1_date = results_0_daily_1["date"];
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"];
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"];
const char* results_0_daily_1_high = results_0_daily_1["high"];
const char* results_0_daily_1_low = results_0_daily_1["low"];
const char* results_0_daily_1_rainfall = results_0_daily_1["rainfall"];
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"];
const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"];
const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"];
const char* results_0_daily_1_humidity = results_0_daily_1["humidity"];
JsonObject results_0_daily_2 = results_0_daily[2];
const char* results_0_daily_2_date = results_0_daily_2["date"];
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"];
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"];
const char* results_0_daily_2_high = results_0_daily_2["high"];
const char* results_0_daily_2_low = results_0_daily_2["low"];
const char* results_0_daily_2_rainfall = results_0_daily_2["rainfall"];
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"];
const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"];
const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"];
const char* results_0_daily_2_humidity = results_0_daily_2["humidity"];
const char* results_0_last_update = results_0["last_update"];
// 从以上信息中摘选几个通过串口监视器显示
String results_0_daily_0_date_str = results_0_daily_0["date"].as<String>();
String results_0_daily_0_text_day_str = results_0_daily_0["text_day"].as<String>();
int results_0_daily_0_code_day_int = results_0_daily_0["code_day"].as<int>();
String results_0_daily_0_text_night_str = results_0_daily_0["text_night"].as<String>();
int results_0_daily_0_code_night_int = results_0_daily_0["code_night"].as<int>();
int results_0_daily_0_high_int = results_0_daily_0["high"].as<int>();
int results_0_daily_0_low_int = results_0_daily_0["low"].as<int>();
String results_0_last_update_str = results_0["last_update"].as<String>();
int results_0_daily_1_high_int = results_0_daily_1["high"].as<int>();
int results_0_daily_1_low_int = results_0_daily_1["low"].as<int>();
String results_0_daily_1_text_day_str = results_0_daily_1["text_day"].as<String>();
String results_0_daily_1_text_night_str = results_0_daily_1["text_night"].as<String>();
Serial.println(F("======Today Weahter ======="));
Serial.print(F("DATE: "));
Serial.println(results_0_daily_0_date_str);
Serial.print(F("Day Weather: "));
Serial.print(results_0_daily_0_text_day_str);
Serial.print(F(" "));
Serial.println(results_0_daily_0_code_day_int);
Serial.print(F("Night Weather: "));
Serial.print(results_0_daily_0_text_night_str);
Serial.print(F(" "));
Serial.println(results_0_daily_0_code_night_int);
Serial.print(F("High: "));
Serial.println(results_0_daily_0_high_int);
Serial.print(F("LOW: "));
Serial.println(results_0_daily_0_low_int);
Serial.print(F("Last Update: "));
Serial.println(results_0_last_update_str);
Serial.println(F("=============================="));
display_1(results_0_daily_1_high_int,results_0_daily_1_low_int,results_0_daily_0_text_day_str,results_0_daily_1_text_night_str);
results_0_daily_1_high_int_old=results_0_daily_1_high_int;
results_0_daily_1_low_int_old=results_0_daily_1_low_int;
results_0_daily_1_text_day_str_old=results_0_daily_1_text_day_str;
results_0_daily_1_text_night_str_old=results_0_daily_1_text_night_str;
}else{
display_1(results_0_daily_1_high_int_old,results_0_daily_1_low_int_old,results_0_daily_1_text_day_str_old,results_0_daily_1_text_night_str_old);
}
}
//----------预测明天天气----------
void display_1(int results_0_daily_1_high_int,int results_0_daily_1_low_int,String results_0_daily_1_text_day_str,String results_0_daily_0_text_night_str){
//显示输出
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(0, 14);
// u8g2.print("广州明天天气");
u8g2.print(lz_str);
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(3, 38);
u8g2.print("明天");
u8g2.drawFrame(0,20,38,25);
u8g2.setFont(u8g2_font_logisoso20_tr);
u8g2.setCursor(38, 42);
u8g2.print(results_0_daily_1_low_int);
u8g2.setCursor(73, 42);
u8g2.print("~");
u8g2.setCursor(90, 42);
u8g2.print(results_0_daily_1_high_int);
u8g2.setCursor(0, 62);
// u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.print("日:");
u8g2.setCursor(22, 62);
u8g2.print(results_0_daily_1_text_day_str);
u8g2.setCursor(63, 62);
u8g2.print("夜:");
u8g2.setCursor(86, 62);
u8g2.print(results_0_daily_0_text_night_str);
u8g2.sendBuffer();
}
/*-------- NTP 代码 ----------*/
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 oledClockDisplay(int yn) //yn 表示联接上网就1,没联接上就0并用原来日期+秒数
{
int years, months, days, hours, minutes, seconds, weekdays;
if (yn==1){
years = year();
months = month();
days = day();
hours = hour();
minutes = minute();
seconds = second();
weekdays = weekday();
// //保存到临时年月日时分钞星期
sstime[1]=years;
sstime[2]=months;
sstime[3]=days;
sstime[4]=hours;
sstime[5]=minutes;
sstime[6]=seconds;
sstime[7]=weekdays;
}else{
// //保存到临时年月日时分钞星期
int addsec=0;
addsec=((millis()-old_mill)/1000);
//年后秒数
int year_ms=(addsec+sstime[6]+(sstime[5]*60)+(sstime[4]*60*60));
years=sstime[1];
months=sstime[2];
days=sstime[3];
hours=(year_ms/3600);
minutes=((year_ms/60) % 60);
seconds=(year_ms % 60);
weekdays=sstime[7];
}
Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
//判断闹钟
if (((hours==lz1[1] && minutes==lz1[2] && lz[1]==1) ||
(hours==lz2[1] && minutes==lz2[2] && lz[2]==1) ||
(hours==lz3[1] && minutes==lz3[2] && lz[3]==1)
)&& lzyn==1){
ls007=0;
lzyn=(-1);
}
if (minutes != lz1[2] && minutes != lz2[2] && minutes != lz3[2] && liangcs == 0){
lzyn=1;
}
u8g2.clearBuffer();
// u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(0, 14);
Serial.printf("闹钟设置%d/%d/%d \n",lz[1],lz[2],digitalRead(no[2]));
u8g2.print(lz_str);
if (isNTPConnected)
{
if(timeZone>=0)
{
//原来固定显示时区
// u8g2.print("当前时间(UTC+");
// u8g2.print(timeZone);
// u8g2.print(")");
//现改闹钟时间
// u8g2.print("闹钟:早上06:45");
// u8g2.print("");
// u8g2.print("06:45");
}
else
{
// u8g2.print("当前时间(UTC");
// u8g2.print(timeZone);
// u8g2.print(")");
//现改闹钟时间
// u8g2.print("闹钟:晚上11:25");
// u8g2.print("");
// u8g2.print("06:45");
}
}
else{
u8g2.setCursor(0, 105);
u8g2.print("-无网"); //如果上次对时失败,则会显示无网络
}
String currentTime = "";
if (hours < 10)
currentTime += 0;
currentTime += hours;
currentTime += ":";
if (minutes < 10)
currentTime += 0;
currentTime += minutes;
currentTime += ":";
if (seconds < 10)
currentTime += 0;
currentTime += seconds;
String currentDay = "";
currentDay += years;
currentDay += "/";
if (months < 10)
currentDay += 0;
currentDay += months;
currentDay += "/";
if (days < 10)
currentDay += 0;
currentDay += days;
u8g2.setFont(u8g2_font_logisoso24_tr);
u8g2.setCursor(0, 44);
u8g2.print(currentTime);
u8g2.setCursor(0, 61);
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.print(currentDay);
u8g2.drawXBM(80, 48, 16, 16, xing);
u8g2.setCursor(95, 62);
u8g2.print("期");
if (weekdays == 1)
u8g2.print("日");
else if (weekdays == 2)
u8g2.print("一");
else if (weekdays == 3)
u8g2.print("二");
else if (weekdays == 4)
u8g2.print("三");
else if (weekdays == 5)
u8g2.print("四");
else if (weekdays == 6)
u8g2.print("五");
else if (weekdays == 7)
u8g2.drawXBM(111, 49, 16, 16, liu);
u8g2.sendBuffer();
}