自制WiFi天气温湿度时钟,Blinker esp-01(8266) 128*64 OLED屏-Arduino中文社区 - Powered by Discuz! Archiver

安少 发表于 2020-11-3 20:19

自制WiFi天气温湿度时钟,Blinker esp-01(8266) 128*64 OLED屏

本帖最后由 安少 于 2021-2-4 17:09 编辑

先看程序;作品在下面,可以慢慢看。
程序写的比较跳,初学着可能比较难理解,讲程序了一点一点抽出来将。

程序的编写借鉴了blinker的示例,单片机菜鸟 的OLED教程,526598 的天气信息提取,1812z的部分优化代码的方法/*********************************************************************************************************
日期:2021/01/28
功能:WiFi+DHT11+OLED+有源蜂鸣器+继电器 8266端
作者:安少
128X64OLED显示 DHT11获取温度 蜂鸣器蜂鸣 继电器工作
调用Blinker、ESP8266、ArduinoJson、DHT、u8g2库文件
*********************************************************************************************************/
#define BLINKER_WIFI //定义wifi模块
#define BLINKER_WITHOUT_SSL //非SSL加密通信接入,省堆栈
#define BLINKER_PRINT Serial //给debug打开串口
#define BLINKER_ESP_SMARTCONFIG //定义EspTouch/SmartConfig模式进行配网,可以用APP配网
#define BLINKER_ALIGENIE_SENSOR //连接天猫精灵,定义设备类型为传感器
#include <ESP8266WiFi.h> //包含ESP8266头文件,8266必须要使用的头文件
#include <ArduinoJson.h> //包含ArduinoJson头文件,用于解析从点灯获取到的天气数据
#include <Blinker.h> //包含Blinker头文件,用于连接点灯科技
#include <DHT.h> //包含DHT头文件,用于温湿度传感器获取数据
#include <U8g2lib.h> //包含u8g2头文件,用于OLED显示
#include <EEPROM.h> //包含EEPROM头文件,用于EEPROM存储

#ifdef U8X8_HAVE_HW_I2C          //定义OLED连接方式为I2C
#include <Wire.h>
#endif
#ifdef U8X8_HAVE_HW_SPI          //定义OLED连接方式为SPI
#include <SPI.h>
#endif

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 14, /* data=*/ 2);
//定义128X64四针OLED模块连接管脚io14、io2
#define DHTPIN 5 //定义DHT11模块连接管脚io5
#define DHTTYPE DHT11 //使用温度湿度模块的类型为DHT11
DHT dht(DHTPIN, DHTTYPE); //生成DHT对象,参数是引脚和DHT的类型

#define TEXTE_ip "tex-ip"
#define Slider_1 "ran-shuaxin"

/*********************************************************************************************************
定义全局变量

*********************************************************************************************************/
char auth[] = "***************"; //你的设备key

String location = "guangxi-jinchengjiangqu"; //定义天气地址

float humi_read = 0, temp_read = 0; //定义浮点型全局变量 储存传感器读取的温湿度数据

const int fmq1 = 13; //定义蜂鸣器引脚
const int xyd1 = 12; //定义小夜灯引脚
const int xyd2 = 04; //定义小夜灯辅助引脚

int a1 = 0; //用于开关OLED
int a2 = 0; //用于上电更新天气
int a3 = 0; //用于间隔更新天气
int a4 = 0; //用于联网更新天气

int b0 = 0; //用于OLED页面的
int b1 = 1;
int b2 = 1;
int b3 = 1;
int b4 = 1;

int c1 = 0; //用于蜂鸣器
int c2 = 0; //用于控制OLED
int c3 = 0; //用于小夜灯

int tian1 = 0;
int shi1= 0;
int fen1= 0;
int miao1 = 0;


int shua1 = 0;
int shua2 = 0;

char w_weather = ""; //天气
char w_temp    = ""; //室外温度
char w_humi    = ""; //室外湿度
char w_wind    = ""; //风向
char w_power   = ""; //风力

char a_aqi   = ""; //空气质量
char a_level = ""; //空气等级
char a_pm25= ""; //pm2.5
/*********************************************************************************************************
新建数据类型组件对象,作用:将数据传输到手机blinker app

*********************************************************************************************************/
BlinkerText Text_ip(TEXTE_ip);
BlinkerSlider Slider1(Slider_1);

BlinkerNumber HUMI("humi"); //定义湿度数据键名
BlinkerNumber TEMP("temp"); //定义温度数据键名
BlinkerNumber Number1("num-xinhao"); //定义信号强度键名

BlinkerButton Btn_time("btn-A1");
BlinkerButton Btn_temp_humi("btn-A2");
BlinkerButton Btn_wifi("btn-A3");
BlinkerButton Btn_Refresh("btn-A4");
BlinkerButton Btn_OLED("btn-A5");
BlinkerButton Btn_weather("btn-A6");
BlinkerButton Btn_air("btn-A7");
BlinkerButton Btn_fmq("btn-A8");
BlinkerButton Btn_xyd("btn-A9");

//BlinkerBridge BridgeDevice1(BRIDGE_1);
/*********************************************************************************************************
读取DHT11传感器的温湿度数据

*********************************************************************************************************/
void DHT11_1() {
float h = dht.readHumidity(); //读取DHT11传感器的湿度 并赋值给h
float t = dht.readTemperature(); //读取传感器的温度   并赋值给t
if (isnan(h) || isnan(t)) { //判断是否成功读取到温湿度数据
    BLINKER_LOG("读取温湿度失败!");
    if (a1 == 1) {
      Blinker.delay(2000);
    }
}
else { //成功读取到数据
    //打印
    // BLINKER_LOG("Humidity: ", h, " %");
    // BLINKER_LOG("Temperature: ", t, " *C");

    temp_read = t - 0.6;   //校准温度
    humi_read = h - 11;    //校准湿度
}
}
/*********************************************************************************************************
云存储回调函数

*********************************************************************************************************/
void dataStorage() {
Blinker.dataStorage("temp", temp_read);
Blinker.dataStorage("humi", humi_read);
}
/*********************************************************************************************************
天猫精灵温湿度回调函数

*********************************************************************************************************/
void aligenieQuery(int32_t queryCode) {
switch (queryCode) {
    case BLINKER_CMD_QUERY_ALL_NUMBER :
      BLINKER_LOG("AliGenie Query All");
      BlinkerAliGenie.temp(temp_read);
      BlinkerAliGenie.humi(humi_read);
      BlinkerAliGenie.print();
      break;
    case BLINKER_CMD_QUERY_TEMP_NUMBER :
      BlinkerAliGenie.temp(temp_read);
      BlinkerAliGenie.print();
      break;
    case BLINKER_CMD_QUERY_HUMI_NUMBER :
      BlinkerAliGenie.humi(humi_read);
      BlinkerAliGenie.print();
      break;
    default :
      BlinkerAliGenie.temp(20);
      BlinkerAliGenie.humi(20);
      BlinkerAliGenie.print();
      break;
}
}
/*********************************************************************************************************
获取DHT11状态并用OLED显示

*********************************************************************************************************/
void DTH11_OLED() {
String wendu;
wendu = String("") + "室内温度:" + temp_read + "°C";
String shidu;
shidu = String("") + "室内湿度:" + humi_read + "%RH";

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "2");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);
u8g2.setCursor(0, 25);
u8g2.print(wendu);

u8g2.setCursor(0, 40);
u8g2.print(shidu);
}
/*********************************************************************************************************
给一个地址获取天气数据
功能;通过地址参数获取天气信息延时一秒后在空气信息
输入参数:给 weather 输入地址参数
输入参数:给 aqi 输入地址参数
*********************************************************************************************************/
void tianqi() {
Blinker.weather(location);
Blinker.delay(1000);
Blinker.aqi(location);
}
/*********************************************************************************************************
开机更新天气信息
功能:开机等待五秒后获取天气信息
变量:a2 判断是否获取过天气信息
调用函数:tianqi();
运行流程:a2等于0则调用天气地址函数获取天气信息,否则不执行调用天气地址函数获取天气信息并跳出当前函数
*********************************************************************************************************/
void kjgxtq() {
if (a2 == 0) {
    Blinker.delay(5000);
    tianqi();
    BLINKER_LOG("开机是否更新天气", a2);
}
}
/*********************************************************************************************************
间隔更新天气信息
功能:间隔一定的时间后在获取天气信息
变量:a3 判断是否到达预定时间
变量:hour 获取当前小时
变量:min 获取当前分钟
调用函数:tianqi();
运行流程:a3等于对则调用天气地址函数获取天气信息,否则不执行调用天气地址函数获取天气信息并跳出当前函数
*********************************************************************************************************/
void jggxtq() {
int8_t hour = Blinker.hour();//时
int8_t min= Blinker.minute();//分

if (hour == 0) {
    a3 = 0;
}
if (hour == 4) {
    a3 = 4;
}
if (hour == 8) {
    a3 = 8;
}
if (hour == 10) {
    a3 = 10;
}
if (hour == 12) {
    a3 = 12;
}
if (hour == 14) {
    a3 = 14;
}
if (hour == 16) {
    a3 = 16;
}
if (hour == 18) {
    a3 = 18;
}
if (hour == 20) {
    a3 = 20;
}
if (hour == 22) {
    a3 = 22;
}
if (hour == a3) {
    if (min == 0) {
      tianqi();//间隔更新天气
      Blinker.delay(40000);
    }
}
}
/*********************************************************************************************************
天气回调函数

*********************************************************************************************************/
void weatherData(const String & data) {
//BLINKER_LOG("天气: ", data);
DynamicJsonDocument jsonBuffer(400);
DeserializationError error = deserializeJson(jsonBuffer, data);
JsonObject doc = jsonBuffer.as<JsonObject>();
if (data == '{') {
    strcpy(w_weather, jsonBuffer["weather"]); //天气
    strcpy(w_temp, jsonBuffer["temp"]); //室外温度
    strcpy(w_humi, jsonBuffer["humi"]); //室外湿度
    strcpy(w_wind, jsonBuffer["wind"]); //风向
    strcpy(w_power, jsonBuffer["power"]); //风力
}
else {
    //天气获取失败
    BLINKER_LOG("weatherData_error!");
    delay(1000);
    return;
}
}
/*********************************************************************************************************
获取天气信息并用OLED显示

*********************************************************************************************************/
void weather_OLED() {
String w_weather1;
w_weather1 = String("") + "天气预报:" + w_weather;
String w_temp1;
w_temp1 = String("") + "室外温度:" + w_temp + "°C";
String w_humi1;
w_humi1 = String("") + "室外湿度:" + w_humi + "%RH";

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "3");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);

u8g2.setCursor(0, 25);
u8g2.print(w_weather1);

u8g2.setCursor(0, 40);
u8g2.print(w_temp1);

u8g2.setCursor(0, 55);
u8g2.print(w_humi1);
}
void weather_OLED2() {
String w_wind1;
w_wind1 = String("") + "室外风向:" + w_wind;
String w_power1;
w_power1 = String("") + "室外风力:" + w_power + "级";

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "3");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);

u8g2.setCursor(0, 25);
u8g2.print(w_wind1);

u8g2.setCursor(0, 40);
u8g2.print(w_power1);
}
void w_OLED() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
weather_OLED();
u8g2.nextPage();
}
void w_OLED2() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
weather_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
空气质量回调函数

*********************************************************************************************************/
void airData(const String & data) {
//BLINKER_LOG("空气质量: ", data);
DynamicJsonDocument jsonBuffer(512);
DeserializationError error = deserializeJson(jsonBuffer, data);
JsonObject doc = jsonBuffer.as<JsonObject>();
if (data == '{') {
    strcpy(a_aqi, jsonBuffer["aqi"]); //空气质量
    strcpy(a_level, jsonBuffer["level"]); //空气等级
    strcpy(a_pm25, jsonBuffer["pm25"]); //pm2.5
    a2 = 1; a4 = 1;
}
else {
    BLINKER_LOG("airData_error!");
    //Serial.println(error.c_str());
    delay(1000);
    a2 = 1; a4 = 1;
    return;
}
}

/*********************************************************************************************************
获取空气信息并用OLED显示

*********************************************************************************************************/
void aqi_OLED() {
String a_aqi1;
a_aqi1 = String("") + "空气质量:" + a_aqi;
String a_level1;
a_level1 = String("") + "空气等级:" + a_level;
String a_pm251;
a_pm251 = String("") + "微颗粒物:" + a_pm25;

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "4");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);

u8g2.setCursor(0, 25);
u8g2.print(a_aqi1);

u8g2.setCursor(0, 40);
u8g2.print(a_level1);

u8g2.setCursor(0, 55);
u8g2.print(a_pm251);
}
/*********************************************************************************************************
获取WiFi状态并用OLED显示

*********************************************************************************************************/
void Wifi_OLED() {
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawHLine(0, 10, 128);
u8g2.drawHLine(0, 63, 128);
uint8 status; //记录连接状态
status = wifi_station_get_connect_status(); //获得连接的状态
if (status == STATION_GOT_IP) {
    u8g2.drawStr(0, 8, "Wifi");
    if (a4 == 0) {
      a2 = 0;
      BLINKER_LOG("联网是否更新天气", a4);
    }
}
else {
    u8g2.drawStr(0, 8, "----");
    a2 = 1;
    BLINKER_LOG("联网是否更新天气", a4);
}
}
/*********************************************************************************************************
获取ip并用OLED显示

*********************************************************************************************************/
void ip_OLED() {
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawHLine(0, 10, 128);
u8g2.drawHLine(0, 63, 128);
u8g2.drawStr(122, 8, "0");

u8g2.drawStr(0, 21, "SSID");
u8g2.drawStr(31, 21, ":");
u8g2.setCursor(34, 21);
u8g2.print(WiFi.SSID());

u8g2.drawStr(0, 31, "Pswd");
u8g2.drawStr(31, 31, ":");
u8g2.setCursor(34, 31);
u8g2.print(WiFi.psk());

u8g2.drawStr(0, 41, "GaIP");
u8g2.drawStr(31, 41, ":");
u8g2.setCursor(34, 41);
u8g2.print(WiFi.gatewayIP());

u8g2.drawStr(0, 51, "LoIP");
u8g2.drawStr(31, 51, ":");
u8g2.setCursor(34, 51);
u8g2.print(WiFi.localIP());

u8g2.drawStr(0, 61, "MAC");
u8g2.drawStr(29, 61, ":");
u8g2.setCursor(33, 61);
u8g2.print(WiFi.macAddress());

u8g2.setCursor(0, 8);
u8g2.print(WiFi.RSSI());
}
/*********************************************************************************************************
获取运行时间并用OLED显示

*********************************************************************************************************/
void yxsj_OLED() {
String fh; String tianbl; String shibl; String fenbl; String miaobl;

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "0");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);
u8g2.setCursor(0, 25);
u8g2.print("运行时间:");

time_t run_time = Blinker.runTime(); //获取运行时间,单位为秒
tian1 =run_time / 86400; //转化为天
shi1= (run_time - tian1 * 86400 ) / 3600; //转化为时
fen1= (run_time - tian1 * 86400 - shi1 * 3600) / 60; //转化为分
miao1 =run_time - tian1 * 86400 - shi1 * 3600 - fen1 * 60; //转化为秒
if (tian1 < 10) {
    tianbl = String("") + "0" + tian1;
}
else {
    tianbl = String("") + tian1;
}
if (shi1 < 10) {
    shibl = String("") + "0" + shi1;
}
else {
    shibl = String("") + shi1;
}
if (fen1 < 10) {
    fenbl = String("") + "0" + fen1;
}
else {
    fenbl = String("") + fen1;
}
if (miao1 < 10) {
    miaobl = String("") + "0" + miao1;
}
else {
    miaobl = String("") + miao1;
}

if (tian1 == 0 & shi1 == 0 & fen1 == 0) {
    fh = String("") + miaobl + "秒";
}
else if (tian1 == 0 & shi1 == 0 ) {
    fh = String("") + fenbl + "分" + miaobl + "秒";
}
else if (tian1 == 0) {
    fh = String("") + shibl + "时" + fenbl + "分" + miaobl + "秒";
}
else {
    fh = String("") + tianbl + "天" + shibl + "时" + fenbl + "分" + miaobl + "秒";
}
u8g2.setCursor(0, 40);
u8g2.print(fh);
}
void ip_OLED_0() {
u8g2.clearBuffer();
u8g2.firstPage();
ip_OLED();
time_OLED2();
DTH11_OLED2();
u8g2.nextPage();
}
void yxsj_OLED_0() {
u8g2.clearBuffer();
u8g2.firstPage();
yxsj_OLED();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
获取时间状态并用OLED显示

*********************************************************************************************************/
void time_OLED() {
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "1");
int16_t year = Blinker.year(); //年
if (year > 0) {
    time_1();
}
else {
    u8g2.setFont(u8g2_font_ncenB12_tr);
    u8g2.drawStr(10, 36, "Time not set"); //返回错误值
}
}
void time_1() {
String rq; String sj;
String monthbl; String mdaybl;
String hourbl; String minbl; String secbl;

int16_t year= Blinker.year(); //年
int8_tmonth = Blinker.month(); //月
int8_tmday= Blinker.mday(); //日
int8_twday= Blinker.wday(); //星期
int8_thour= Blinker.hour(); //时
int8_tmin   = Blinker.minute(); //分
int8_tsec   = Blinker.second(); //秒

if (month < 10) {
    monthbl = String("") + "0" + month;
}
else {
    monthbl = String("") + month;
}
if (mday < 10) {
    mdaybl = String("") + "0" + mday;
}
else {
    mdaybl = String("") + mday;
}

if (hour < 10) {
    hourbl = String("") + "0" + hour;
}
else {
    hourbl = String("") + hour;
}
if (min < 10) {
    minbl = String("") + "0" + min;
}
else {
    minbl = String("") + min;
}
if (sec < 10) {
    secbl = String("") + "0" + sec;
}
else {
    secbl = String("") + sec;
}

u8g2.setFont(u8g2_font_ncenB12_tr);
rq = String("") + year + "/"+ monthbl + "/" + mdaybl;
u8g2.setCursor(20, 26); //显示位置
u8g2.print(rq);
sj = String("") + hourbl + ":"+ minbl + ":" + secbl;
u8g2.setCursor(30, 44); //显示位置
u8g2.print(sj);

u8g2.setFont(u8g2_font_wqy13_t_gb2312b);
u8g2.setCursor(46, 60);
if (wday == 0) {
    u8g2.print("星期日");
}
if (wday == 1) {
    u8g2.print("星期一");
}
if (wday == 2) {
    u8g2.print("星期二");
}
if (wday == 3) {
    u8g2.print("星期三");
}
if (wday == 4) {
    u8g2.print("星期四");
}
if (wday == 5) {
    u8g2.print("星期五");
}
if (wday == 6) {
    u8g2.print("星期六");
}
}
/*********************************************************************************************************
OLED显示中间时间

*********************************************************************************************************/
void time_OLED2() {
u8g2.setFont(u8g2_font_ncenB08_tr);
int8_t hour = Blinker.hour(); //时
if (hour > -1) {
    time_2();
}
else {
    u8g2.drawStr(37, 8, "--:--"); //返回错误值
}
}
void time_2() {
String sj2; String hourbl2; String minbl2;
int8_t hour = Blinker.hour(); //时
int8_t min = Blinker.minute(); //分

if (hour < 10) {
    hourbl2 = String("") + "0" + hour;
}
else {
    hourbl2 = String("") + hour;
}
if (min < 10) {
    minbl2 = String("") + "0" + min;
}
else {
    minbl2 = String("") + min;
}

sj2 = String("") + hourbl2 + ":"+ minbl2 ;
u8g2.setCursor(37, 8); //显示位置
u8g2.print(sj2);
}
/*********************************************************************************************************
OLED显示右上角温度

*********************************************************************************************************/
void DTH11_OLED2() {
DHT11_1();
String wendu2;
wendu2 = String("") + temp_read + "*C";
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(75, 8);
u8g2.print(wendu2);
}
/*********************************************************************************************************
OLED第零屏显示,WiFi,ip

*********************************************************************************************************/
void OLED_0() {
ip_OLED_0();
yanshi();
Blinker.run();
yxsj_OLED_0();
}
/*********************************************************************************************************
OLED第一屏显示,时间

*********************************************************************************************************/
void OLED_1() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED();
DTH11_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
OLED第二屏显示,WiFi,温度

*********************************************************************************************************/
void OLED_2() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
DTH11_OLED();
time_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
OLED第三屏显示,天气

*********************************************************************************************************/
void OLED_3() {
w_OLED();
yanshi();
Blinker.run();
w_OLED2();
}
/*********************************************************************************************************
OLED第四屏显示,空气

*********************************************************************************************************/
void OLED_4() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
aqi_OLED();
u8g2.nextPage();
}
/*********************************************************************************************************
按键操作OLED显示WiFi

*********************************************************************************************************/
void Btn_wifi_callback(const String & state) {
//BLINKER_LOG("get button state3: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 2; b1 = 0; b2 = 0; b3 = 0; b4 = 0; //单独显示WiFi
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1; //恢复屏幕滚动显示
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示时间

*********************************************************************************************************/
void Btn_time_callback(const String & state) {
//BLINKER_LOG("get button state1: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 2; b2 = 0; b3 = 0; b4 = 0;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示温湿度

*********************************************************************************************************/
void Btn_temp_humi_callback(const String & state) {
//BLINKER_LOG("get button state2: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 0; b2 = 2; b3 = 0; b4 = 0;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示天气

*********************************************************************************************************/
void Btn_weather_callback(const String & state) {
//BLINKER_LOG("get button state3: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 0; b2 = 0; b3 = 2; b4 = 0;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示空气质量

*********************************************************************************************************/
void Btn_air_callback(const String & state) {
//BLINKER_LOG("get button state3: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 0; b2 = 0; b3 = 0; b4 = 2;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED屏幕滚动

*********************************************************************************************************/
void Btn_Refresh_callback(const String & state) {
//BLINKER_LOG("get button state4: ", state);
b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1; c2 = 0;
Blinker.vibrate();
fmq_1m();
dingshiguanbioled();
huidiaoneirong();
}
/*********************************************************************************************************
按键操作开关OLED屏幕

*********************************************************************************************************/
void Btn_OLED_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
    a1 = 0; c2 = 1; b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
    Blinker.vibrate();
    fmq_1m();
    huidiaoneirong();
    u8g2.setPowerSave(a1);
}
else if (state == "off") {
    a1 = 1; c2 = 1; b0 = 0; b1 = 0; b2 = 0; b3 = 0; b4 = 0;
    Blinker.vibrate();
    fmq_1m();
    huidiaoneirong();
    u8g2.setPowerSave(a1);
}
}
/*********************************************************************************************************
按键操作蜂鸣器

*********************************************************************************************************/
void Btn_fmq_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
    c1 = 1;
    Blinker.vibrate();
    digitalWrite(fmq1, LOW);
    Btn_fmq.icon("fal fa-bell-on");
    Btn_fmq.text("蜂鸣器打开");
    Btn_fmq.print("on");
}
else if (state == "off") {
    c1 = 0;
    Blinker.vibrate();
    digitalWrite(fmq1, HIGH);
    Btn_fmq.icon("fal fa-bell");
    Btn_fmq.text("蜂鸣器关闭");
    Btn_fmq.print("off");
}
}
/*********************************************************************************************************
按键操作小夜灯

*********************************************************************************************************/
void Btn_xyd_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
    c3 = 1;
    fmq_1m();
    Blinker.vibrate();
    digitalWrite(xyd1, HIGH);
    digitalWrite(xyd2, HIGH);
    huidiaoneirong();
}
else if (state == "off") {
    c3 = 0;
    fmq_1m();
    Blinker.vibrate();
    digitalWrite(xyd1, LOW);
    digitalWrite(xyd2, LOW);
    huidiaoneirong();
    Blinker.delay(50);
    digitalWrite(xyd2, HIGH);
}
}
/*********************************************************************************************************
切屏滑动条

*********************************************************************************************************/
void slider1_callback(int32_t value)
{
BLINKER_LOG("get slider value: ", value);
EEPROM.begin(4000);
EEPROM.write(2449, value);
Slider1.print(value);
EEPROM.end();
}

/*********************************************************************************************************
按键状态回调函数

*********************************************************************************************************/
void huidiaoneirong() {
if (b0 == 0) {
    Btn_wifi.icon("fal fa-wifi");
    Btn_wifi.text("WiFi信息");
    Btn_wifi.print("off");
}
if (b0 == 1) {
    Btn_wifi.icon("fal fa-wifi");
    Btn_wifi.text("WiFi信息");
    Btn_wifi.print("off");
}
if (b0 == 2) {
    Btn_wifi.icon("fal fa-wifi");
    Btn_wifi.text("显示WiFi信息");
    Btn_wifi.print("on");
}

if (b1 == 0) {
    Btn_time.text("时间");
    Btn_time.print("off");
}
if (b1 == 1) {
    Btn_time.text("时间");
    Btn_time.print("off");
}
if (b1 == 2) {
    Btn_time.text("显示时间");
    Btn_time.print("on");
}

if (b2 == 0) {
    Btn_temp_humi.text("温湿度");
    Btn_temp_humi.print("off");
}
if (b2 == 1) {
    Btn_temp_humi.text("温湿度");
    Btn_temp_humi.print("off");
}
if (b2 == 2) {
    Btn_temp_humi.text("显示温湿度");
    Btn_temp_humi.print("on");
}

if (b3 == 0) {
    Btn_weather.text("天气信息");
    Btn_weather.print("off");
}
if (b3 == 1) {
    Btn_weather.text("天气信息");
    Btn_weather.print("off");
}
if (b3 == 2) {
    Btn_weather.text("显示天气信息");
    Btn_weather.print("on");
}

if (b4 == 0) {
    Btn_air.text("空气信息");
    Btn_air.print("off");
}
if (b4 == 1) {
    Btn_air.text("空气信息");
    Btn_air.print("off");
}
if (b4 == 2) {
    Btn_air.text("显示空气信息");
    Btn_air.print("on");
}

if (c2 == 0 ) {
    if (a1 == 0 ) {
      Btn_OLED.icon("fas fa-toggle-on");
      Btn_OLED.text("屏幕自动打开");
      Btn_OLED.print("on");
    }
}
if (c2 == 0 ) {
    if (a1 == 1 ) {
      Btn_OLED.icon("fas fa-toggle-off");
      Btn_OLED.text("屏幕自动关闭");
      Btn_OLED.print("off");
    }
}
if (c2 == 1 ) {
    if (a1 == 0 ) {
      Btn_OLED.icon("fas fa-toggle-on");
      Btn_OLED.text("屏幕手动打开");
      Btn_OLED.print("on");
    }
}
if (c2 == 1 ) {
    if (a1 == 1 ) {
      Btn_OLED.icon("fas fa-toggle-off");
      Btn_OLED.text("屏幕手动关闭");
      Btn_OLED.print("off");
    }
}

if (c3 == 0 ) {
    Btn_xyd.icon("fal fa-lightbulb");
    Btn_xyd.text("小夜灯关闭");
    Btn_xyd.print("off");
}
if (c3 == 1 ) {
    Btn_xyd.icon("fal fa-lightbulb-on");
    Btn_xyd.text("小夜灯打开");
    Btn_xyd.print("on");
}

Blinker.delay(1000);
if (c1 == 0 ) {
    Btn_fmq.icon("fal fa-bell");
    Btn_fmq.text("蜂鸣器关闭");
    Btn_fmq.print("off");
}
if (c1 == 1 ) {
    Btn_fmq.icon("fal fa-bell-on");
    Btn_fmq.text("蜂鸣器打开");
    Btn_fmq.print("on");
}

Number1.icon("fal fa-wifi");
Number1.print(WiFi.RSSI());
Text_ip.print(WiFi.localIP().toString().c_str());

EEPROM.begin(4000);
int shua3 = EEPROM.read(2449);
shua2 = shua3;
Slider1.print(shua2);
EEPROM.end();

}

/*********************************************************************************************************
收到指令蜂鸣器响一声

*********************************************************************************************************/
void fmq_1m() {
c1 = 0;
digitalWrite(fmq1, LOW);
Blinker.delay(50);
digitalWrite(fmq1, HIGH);
}
/*********************************************************************************************************
滑动条存储在EEPROM的延时函数

*********************************************************************************************************/
void yanshi() {
EEPROM.begin(4000);
int shua3 = EEPROM.read(2449);
shua2 = shua3;
EEPROM.end();
shua1 = shua2 * 1000;
Blinker.delay(shua1);
}
/*********************************************************************************************************
OLED关闭后不显示内容

*********************************************************************************************************/
void shifouxianshi() {
if (a1 == 0) {
    if (b0 == 1) {
      OLED_0();
      yanshi();
      Blinker.run();
    }
    if (b0 == 2) {
      OLED_0();
      yanshi();
    }
    if (b1 == 1) {
      OLED_1();
      yanshi();
      Blinker.run();
    }
    if (b1 == 2) {
      OLED_1();
      yanshi();
    }
    if (b2 == 1) {
      OLED_2();
      yanshi();
      Blinker.run();
    }
    if (b2 == 2) {
      OLED_2();
      yanshi();
    }
    if (b3 == 1) {
      OLED_3();
      yanshi();
      Blinker.run();
    }
    if (b3 == 2) {
      OLED_3();
      yanshi();
    }
    if (b4 == 1) {
      OLED_4();
      yanshi();
      Blinker.run();
    }
    if (b4 == 2) {
      OLED_4();
      yanshi();
    }
}
if (a1 == 1) {
    b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
}
}
/*********************************************************************************************************
定时关闭OLED

*********************************************************************************************************/
void dingshiguanbioled() {
int8_t hour = Blinker.hour();//时
int8_t min= Blinker.minute();//分
if (hour < 7 ) { //小于7时自动关闭屏幕
    if (c2 == 0) {
      a1 = 1;
    }
}
if (hour <= -1 ) { //未获取到时间自动打开屏幕
    if (c2 == 0)   {
      a1 = 0;
    }
}
if (hour >= 7 ) { //等于、大于7时自动打开屏幕
    if (c2 == 0){
      a1 = 0;
    }
}

u8g2.setPowerSave(a1);

if (hour == 0 ) { //零点切换自动模式
    if (min < 2 ) {
      c2 = 0;
    }
}
if (hour == 7 ) { //七点切换自动模式
    if (min < 2 ) {
      c2 = 0;
    }
}
}
/*********************************************************************************************************
给blinkerapp回传数据

*********************************************************************************************************/
void heartbeat() {
HUMI.print(humi_read); //给blinkerapp回传湿度数据
TEMP.print(temp_read); //给blinkerapp回传温度数据
huidiaoneirong();
}
/*********************************************************************************************************
将设置代码放在此处,运行一次

*********************************************************************************************************/
void setup() {
//初始化端口
Serial.begin(115200);

Blinker.begin(auth); //初始化blinker
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();

pinMode(fmq1, OUTPUT); //蜂鸣器引脚设置为输出模式
pinMode(xyd1, OUTPUT); //小夜灯引脚设置为输出模式
pinMode(xyd2, OUTPUT); //小夜灯引脚设置为输出模式
digitalWrite(fmq1, HIGH); //蜂鸣器引脚高电平输出
digitalWrite(xyd1, LOW); //小夜灯引脚低电平输出
digitalWrite(xyd2, HIGH); //小夜灯引脚高电平输出

u8g2.begin(); //初始化OLED
u8g2.enableUTF8Print();
u8g2.clearBuffer();
u8g2.clearDisplay();
u8g2.setPowerSave(0);

dht.begin(); //初始化DHT传感器

Blinker.setTimezone(8.0);
Blinker.attachHeartbeat(heartbeat); //将传感器获取的数据传给blinker app上
Blinker.attachDataStorage(dataStorage); //注册回调函数,开启历史数据存储功能
BlinkerAliGenie.attachQuery(aligenieQuery); //天猫精灵回调函数,回调温湿度数据给天猫精灵
Blinker.attachWeather(weatherData); //注册回调函数,获取天气信息
Blinker.attachAir(airData); //注册回调函数,获取空气质量信息

Btn_time.attach(Btn_time_callback);
Btn_temp_humi.attach(Btn_temp_humi_callback);
Btn_wifi.attach(Btn_wifi_callback);
Btn_Refresh.attach(Btn_Refresh_callback);
Btn_OLED.attach(Btn_OLED_callback);
Btn_weather.attach(Btn_weather_callback);
Btn_air.attach(Btn_air_callback);
Btn_fmq.attach(Btn_fmq_callback);
Btn_xyd.attach(Btn_xyd_callback);
Slider1.attach(slider1_callback);
}
/*********************************************************************************************************
把主代码放在这里,重复运行
通过循环不断读取温湿度传感器获取的数据

*********************************************************************************************************/
void loop() {
Blinker.run(); //运行Blinker

DHT11_1(); //开机获取环境温度
kjgxtq(); //开机获取天气信息
jggxtq(); //间隔更新天气信息
dingshiguanbioled(); //定时关闭OLED
shifouxianshi(); //关闭屏幕后不运行显部分相关程序
}

安少 发表于 2020-11-3 20:26

主控:8266-12F
DHT11温湿度传感器
128*64OLED屏幕
蜂鸣器

安少 发表于 2020-11-4 01:06

设备的背面,分成了两块洞洞板,一块是负责供电和通过US B口输出5v给小夜灯供电,通过继电器控制,另一个块是主控板的背面。船型开关用的三档型,一档电池供电;中间挡关机;二档下载程序时用来给电池充电。用电池供电不能连接主控板下载程序会短路保护,同理,下载程序时不能用电池供电。

安少 发表于 2020-11-4 01:07

显示时间

安少 发表于 2020-11-4 01:08

显示DHT11获取到的温湿度

安少 发表于 2020-11-4 01:18

在WIFI信息页面,分成两部分显示,第一部分主要显示的是信号强度,WIFI名称,WIFI密码,路由器IP,设备IP,MAC地址;第二部分,显示的是随便运行时间。每一页的状态栏都会显示WIFI、时间、温度、页数这些简略信息。

安少 发表于 2020-11-4 01:24

天气页面,显示通过blinker获取到的天气信息,信息过多也是分成了两部分,基本的天气情况,温湿度,风力风向这些信息

安少 发表于 2020-11-4 01:28

空气质量页面,也是通过blinker获取到的信息,获取到的信息过多,我就保留了三条,空气质量、空气等级和微颗粒物(PM2.5)。

安少 发表于 2020-11-4 01:52

app界面设计:
一、设备回传的设备IP地址、信号强度、温湿度数据;这里的都是数据跟随心跳包刷新。
二、图表组件,看图就能明白意思。
三、OLED界面独立显示及开关按键、蜂鸣器、小夜灯开关。在程序里每个开关都是互锁的状态,让某一个页面单独显示,就会关闭其他页面;当然也可以通过自动按键来让屏幕滚动显示。
OLED屏幕的显示与不显示也可以通过按键控制;在程序里设定了,零点自动关闭和七点自动开启,但是避开这两时间点和手动操作互不影响。
关闭了屏幕,不仅屏幕不显示,APP单独显示页面的按键按下了不会让屏幕显示然后内容。
自动按钮会刷新一切,除了页面滚动,也会判断舒服需要开关屏幕,小夜灯和蜂鸣器除外。
蜂鸣器除了能一直响,在按下按键的时候也会有响声反馈。
每一次按下按键,蜂鸣器会响一声的同时也会给手机振动一次的指令。
小夜灯没啥说的就是一个普通的开关,只是电路用来高电平控制,一个io口输出的电压不够得用两个,讲程序了,在讲这个的逻辑。

安少 发表于 2021-3-17 18:35

/*********************************************************************************************************
日期:2021/03/12
功能:WiFi+DHT11+OLED+有源蜂鸣器+继电器 8266端
作者:安少
128X64OLED显示 DHT11获取温度 蜂鸣器蜂鸣 继电器工作
调用Blinker、ESP8266、ArduinoJson、DHT、u8g2库文件
更新:按键清除WiFi配置。
*********************************************************************************************************/
#define BLINKER_WIFI //定义wifi模块
//#define BLINKER_WITHOUT_SSL //非SSL加密通信接入,省堆栈(最新dev3.0默认不加密)
#define BLINKER_PRINT Serial //给debug打开串口
#define BLINKER_ESP_SMARTCONFIG //定义EspTouch/SmartConfig模式进行配网,可以用APP配网
#define BLINKER_ALIGENIE_SENSOR //连接天猫精灵,定义设备类型为传感器
#include <ESP8266WiFi.h> //包含ESP8266头文件,8266必须要使用的头文件
#include <ArduinoJson.h> //包含ArduinoJson头文件,用于解析从点灯获取到的天气数据
#include <Blinker.h> //包含Blinker头文件,用于连接点灯科技
#include <DHT.h> //包含DHT头文件,用于温湿度传感器获取数据
#include <U8g2lib.h> //包含u8g2头文件,用于OLED显示
#include <EEPROM.h> //包含EEPROM头文件,用于EEPROM存储

#ifdef U8X8_HAVE_HW_I2C          //定义OLED连接方式为I2C
#include <Wire.h>
#endif
#ifdef U8X8_HAVE_HW_SPI          //定义OLED连接方式为SPI
#include <SPI.h>
#endif

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 14, /* data=*/ 2);
//定义128X64四针OLED模块连接管脚io14、io2
#define DHTPIN 5 //定义DHT11模块连接管脚io5
#define DHTTYPE DHT11 //使用温度湿度模块的类型为DHT11
DHT dht(DHTPIN, DHTTYPE); //生成DHT对象,参数是引脚和DHT的类型

#define TEXTE_ip "tex-ip"
#define Slider_1 "ran-shuaxin"

/*********************************************************************************************************
定义全局变量

*********************************************************************************************************/
char auth[] = "***********"; //你的设备key

int location = 0000000; //定义天气地址,官网查询地址数字代码

float humi_read = 0, temp_read = 0; //定义浮点型全局变量 储存传感器读取的温湿度数据

const int fmq1 = 13; //定义蜂鸣器引脚
const int xyd1 = 12; //定义小夜灯引脚
const int xyd2 = 4; //定义小夜灯辅助引脚
const int wifirst = 16;//定义按键清除WiFi配置引脚

int a1 = 0; //用于开关OLED
int a2 = 0; //用于上电更新天气
int a3 = 0; //用于间隔更新天气
int a4 = 0; //用于联网更新天气

int b0 = 0; //用于OLED页面的
int b1 = 1;
int b2 = 1;
int b3 = 1;
int b4 = 1;

int c1 = 0; //用于蜂鸣器
int c2 = 0; //用于控制OLED
int c3 = 0; //用于小夜灯
int wifirstState = 0;//清除WiFi配置

int tian1 = 0;
int shi1= 0;
int fen1= 0;
int miao1 = 0;

int shua1 = 0;
int shua2 = 0;

char w_weather = ""; //天气
char w_temp    = ""; //室外温度
char w_humi    = ""; //室外湿度
char w_wind    = ""; //风向
char w_power   = ""; //风力

char a_aqi   = ""; //空气质量
char a_level = ""; //空气等级
char a_pm25= ""; //pm2.5
/*********************************************************************************************************
新建数据类型组件对象,作用:将数据传输到手机blinker app

*********************************************************************************************************/
BlinkerText Text_ip(TEXTE_ip);
BlinkerSlider Slider1(Slider_1);
BlinkerNumber HUMI("humi"); //定义湿度数据键名
BlinkerNumber TEMP("temp"); //定义温度数据键名
BlinkerNumber Number1("num-xinhao"); //定义信号强度键名

BlinkerButton Btn_time("btn-A1");
BlinkerButton Btn_temp_humi("btn-A2");
BlinkerButton Btn_wifi("btn-A3");
BlinkerButton Btn_Refresh("btn-A4");
BlinkerButton Btn_OLED("btn-A5");
BlinkerButton Btn_weather("btn-A6");
BlinkerButton Btn_air("btn-A7");
BlinkerButton Btn_fmq("btn-A8");
BlinkerButton Btn_xyd("btn-A9");
BlinkerButton Btn_WIFIEE("btn-A10");
/*********************************************************************************************************
读取DHT11传感器的温湿度数据

*********************************************************************************************************/
void DHT11_1() {
float h = dht.readHumidity(); //读取DHT11传感器的湿度 并赋值给h
float t = dht.readTemperature(); //读取传感器的温度   并赋值给t
if (isnan(h) || isnan(t)) { //判断是否成功读取到温湿度数据
    BLINKER_LOG("读取温湿度失败!");
    if (a1 == 1) {
      Blinker.delay(2000);
    }
}
else { //成功读取到数据
    //打印
    // BLINKER_LOG("Humidity: ", h, " %");
    // BLINKER_LOG("Temperature: ", t, " *C");

    temp_read = t - 0.6;   //校准温度
    humi_read = h - 11;    //校准湿度
}
}
/*********************************************************************************************************
云存储回调函数

*********************************************************************************************************/
void dataStorage() {
Blinker.dataStorage("temp", temp_read);
Blinker.dataStorage("humi", humi_read);
}
/*********************************************************************************************************
天猫精灵温湿度回调函数

*********************************************************************************************************/
void aligenieQuery(int32_t queryCode) {
switch (queryCode) {
    case BLINKER_CMD_QUERY_ALL_NUMBER :
      BLINKER_LOG("AliGenie Query All");
      BlinkerAliGenie.temp(temp_read);
      BlinkerAliGenie.humi(humi_read);
      BlinkerAliGenie.print();
      break;
    case BLINKER_CMD_QUERY_TEMP_NUMBER :
      BlinkerAliGenie.temp(temp_read);
      BlinkerAliGenie.print();
      break;
    case BLINKER_CMD_QUERY_HUMI_NUMBER :
      BlinkerAliGenie.humi(humi_read);
      BlinkerAliGenie.print();
      break;
    default :
      BlinkerAliGenie.temp(20);
      BlinkerAliGenie.humi(20);
      BlinkerAliGenie.print();
      break;
}
}

/*********************************************************************************************************
获取DHT11状态并用OLED显示

*********************************************************************************************************/
void DTH11_OLED() {
String wendu;
wendu = String("") + "室内温度:" + temp_read + "°C";
String shidu;
shidu = String("") + "室内湿度:" + humi_read + "%RH";

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "2");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);
u8g2.setCursor(0, 25);
u8g2.print(wendu);

u8g2.setCursor(0, 40);
u8g2.print(shidu);
}
/*********************************************************************************************************
给一个地址获取天气数据
功能;通过地址参数获取天气信息延时一秒后在空气信息
输入参数:给 weather 输入地址参数
输入参数:给 aqi 输入地址参数
*********************************************************************************************************/
void tianqi() {
Blinker.weather(location);
Blinker.delay(1000);
Blinker.aqi(location);
}
/*********************************************************************************************************
开机更新天气信息
功能:开机等待五秒后获取天气信息
变量:a2 判断是否获取过天气信息
调用函数:tianqi();
运行流程:a2等于0则调用天气地址函数获取天气信息,否则不执行调用天气地址函数获取天气信息并跳出当前函数
*********************************************************************************************************/
void kjgxtq() {
if (a2 == 0) {
    Blinker.delay(5000);
    tianqi();
    BLINKER_LOG("开机是否更新天气", a2);
}
}
/*********************************************************************************************************
间隔更新天气信息
功能:间隔一定的时间后在获取天气信息
变量:a3 判断是否到达预定时间
变量:hour 获取当前小时
变量:min 获取当前分钟
调用函数:tianqi();
运行流程:a3等于对则调用天气地址函数获取天气信息,否则不执行调用天气地址函数获取天气信息并跳出当前函数
*********************************************************************************************************/
void jggxtq() {
int8_t hour = Blinker.hour();//时
int8_t min= Blinker.minute();//分

if (hour == 0) {
    a3 = 0;
}
if (hour == 4) {
    a3 = 4;
}
if (hour == 8) {
    a3 = 8;
}
if (hour == 10) {
    a3 = 10;
}
if (hour == 12) {
    a3 = 12;
}
if (hour == 14) {
    a3 = 14;
}
if (hour == 16) {
    a3 = 16;
}
if (hour == 18) {
    a3 = 18;
}
if (hour == 20) {
    a3 = 20;
}
if (hour == 22) {
    a3 = 22;
}
if (hour == a3) {
    if (min == 0) {
      tianqi();//间隔更新天气
      Blinker.delay(40000);
    }
}
}
/*********************************************************************************************************
天气回调函数

*********************************************************************************************************/
void weatherData(const String & data) {
//BLINKER_LOG("天气: ", data);
DynamicJsonDocument jsonBuffer(400);
DeserializationError error = deserializeJson(jsonBuffer, data);
JsonObject doc = jsonBuffer.as<JsonObject>();
if (data == '{') {
    strcpy(w_weather, jsonBuffer["weather"]); //天气
    strcpy(w_temp, jsonBuffer["temp"]); //室外温度
    strcpy(w_humi, jsonBuffer["humi"]); //室外湿度
    strcpy(w_wind, jsonBuffer["wind"]); //风向
    strcpy(w_power, jsonBuffer["power"]); //风力
}
else {
    //天气获取失败
    BLINKER_LOG("weatherData_error!");
    delay(1000);
    return;
}
}
/*********************************************************************************************************
获取WiFi状态并在左上角显示

*********************************************************************************************************/
void Wifi_OLED() {
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawHLine(0, 10, 128);
u8g2.drawHLine(0, 63, 128);
uint8 status; //记录连接状态
status = wifi_station_get_connect_status(); //获得连接的状态
if (status == STATION_GOT_IP) {
    u8g2.drawStr(0, 8, "WiFi");
    if (a4 == 0) {
      a2 = 0;
      BLINKER_LOG("联网是否更新天气", a4);
    }
}
else {
    u8g2.drawStr(0, 8, "----");
    a2 = 1;
    BLINKER_LOG("联网是否更新天气", a4);
}
}
/*********************************************************************************************************
获取时间信息

*********************************************************************************************************/
void time_1() {
String rq; String sj;
String monthbl; String mdaybl;
String hourbl; String minbl; String secbl;

int16_t year= Blinker.year(); //年
int8_tmonth = Blinker.month(); //月
int8_tmday= Blinker.mday(); //日
int8_twday= Blinker.wday(); //星期
int8_thour= Blinker.hour(); //时
int8_tmin   = Blinker.minute(); //分
int8_tsec   = Blinker.second(); //秒

if (month < 10) {
    monthbl = String("") + "0" + month;
}
else {
    monthbl = String("") + month;
}
if (mday < 10) {
    mdaybl = String("") + "0" + mday;
}
else {
    mdaybl = String("") + mday;
}

if (hour < 10) {
    hourbl = String("") + "0" + hour;
}
else {
    hourbl = String("") + hour;
}
if (min < 10) {
    minbl = String("") + "0" + min;
}
else {
    minbl = String("") + min;
}
if (sec < 10) {
    secbl = String("") + "0" + sec;
}
else {
    secbl = String("") + sec;
}

u8g2.setFont(u8g2_font_ncenB12_tr);
rq = String("") + year + "/"+ monthbl + "/" + mdaybl;
u8g2.setCursor(20, 26); //显示位置
u8g2.print(rq);
sj = String("") + hourbl + ":"+ minbl + ":" + secbl;
u8g2.setCursor(30, 44); //显示位置
u8g2.print(sj);

u8g2.setFont(u8g2_font_wqy13_t_gb2312b);
u8g2.setCursor(46, 60);
if (wday == 0) {
    u8g2.print("星期日");
}
if (wday == 1) {
    u8g2.print("星期一");
}
if (wday == 2) {
    u8g2.print("星期二");
}
if (wday == 3) {
    u8g2.print("星期三");
}
if (wday == 4) {
    u8g2.print("星期四");
}
if (wday == 5) {
    u8g2.print("星期五");
}
if (wday == 6) {
    u8g2.print("星期六");
}
}
/*********************************************************************************************************
获取时间状态并用OLED显示

*********************************************************************************************************/
void time_OLED() {
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "1");
int16_t year = Blinker.year(); //年
if (year > 0) {
    time_1();
}
else {
    u8g2.setFont(u8g2_font_ncenB12_tr);
    u8g2.drawStr(10, 36, "Time not set"); //返回错误值
}
}
/*********************************************************************************************************
OLED显示中间时间

*********************************************************************************************************/
void time_2() {
String sj2; String hourbl2; String minbl2;
int8_t hour = Blinker.hour(); //时
int8_t min = Blinker.minute(); //分

if (hour < 10) {
    hourbl2 = String("") + "0" + hour;
}
else {
    hourbl2 = String("") + hour;
}
if (min < 10) {
    minbl2 = String("") + "0" + min;
}
else {
    minbl2 = String("") + min;
}

sj2 = String("") + hourbl2 + ":"+ minbl2 ;
u8g2.setCursor(37, 8); //显示位置
u8g2.print(sj2);
}
/*********************************************************************************************************
OLED显示中上时间

*********************************************************************************************************/
void time_OLED2() {
u8g2.setFont(u8g2_font_ncenB08_tr);
int8_t hour = Blinker.hour(); //时
if (hour > -1) {
    time_2();
}
else {
    u8g2.drawStr(37, 8, "--:--"); //返回错误值
}
}
/*********************************************************************************************************
OLED显示右上角温度

*********************************************************************************************************/
void DTH11_OLED2() {
DHT11_1();
String wendu2;
wendu2 = String("") + temp_read + "*C";
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(75, 8);
u8g2.print(wendu2);
}
/*********************************************************************************************************
获取天气信息并用OLED显示
功能:显示天气预报、室外温度、室外湿度信息
变量:w_weather1 将天气预报信息整合
变量:w_temp1 将室外温度信息整合
变量:w_humi1 将室外湿度信息整合
*********************************************************************************************************/
void weather_OLED() {
String w_weather1;
w_weather1 = String("") + "天气预报:" + w_weather;
String w_temp1;
w_temp1 = String("") + "室外温度:" + w_temp + "°C";
String w_humi1;
w_humi1 = String("") + "室外湿度:" + w_humi + "%RH";

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "3");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);

u8g2.setCursor(0, 25);
u8g2.print(w_weather1);

u8g2.setCursor(0, 40);
u8g2.print(w_temp1);

u8g2.setCursor(0, 55);
u8g2.print(w_humi1);
}
/*********************************************************************************************************
获取天气信息并用OLED显示
功能:显示室外风向、室外风力信息
变量:w_wind1 将室外风向信息整合
变量:w_power1 将室外风力信息整合
*********************************************************************************************************/
void weather_OLED2() {
String w_wind1;
w_wind1 = String("") + "室外风向:" + w_wind;
String w_power1;
w_power1 = String("") + "室外风力:" + w_power + "级";

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "3");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);

u8g2.setCursor(0, 25);
u8g2.print(w_wind1);

u8g2.setCursor(0, 40);
u8g2.print(w_power1);
}
void w_OLED() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
weather_OLED();
u8g2.nextPage();
}
void w_OLED2() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
weather_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
空气质量回调函数

*********************************************************************************************************/
void airData(const String & data) {
//BLINKER_LOG("空气质量: ", data);
DynamicJsonDocument jsonBuffer(512);
DeserializationError error = deserializeJson(jsonBuffer, data);
JsonObject doc = jsonBuffer.as<JsonObject>();
if (data == '{') {
    strcpy(a_aqi, jsonBuffer["aqi"]); //空气质量
    strcpy(a_level, jsonBuffer["level"]); //空气等级
    strcpy(a_pm25, jsonBuffer["pm25"]); //pm2.5
    a2 = 1; a4 = 1;
}
else {
    BLINKER_LOG("airData_error!");
    //Serial.println(error.c_str());
    delay(1000);
    a2 = 1; a4 = 1;
    return;
}
}
/*********************************************************************************************************
获取空气信息并用OLED显示

*********************************************************************************************************/
void aqi_OLED() {
String a_aqi1;
a_aqi1 = String("") + "空气质量:" + a_aqi;
String a_level1;
a_level1 = String("") + "空气等级:" + a_level;
String a_pm251;
a_pm251 = String("") + "微颗粒物:" + a_pm25;

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "4");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);

u8g2.setCursor(0, 25);
u8g2.print(a_aqi1);

u8g2.setCursor(0, 40);
u8g2.print(a_level1);

u8g2.setCursor(0, 55);
u8g2.print(a_pm251);
}
/*********************************************************************************************************
获取ip相关信息
调用函数:WiFi.SSID 获取WiFi名称
调用函数:WiFi.psk获取WiFi密码
调用函数:WiFi.gatewayIP 获取网关IP
调用函数:WiFi.localIP 获取本地IP
调用函数:WiFi.macAddress 获取MAC地址
调用函数:WiFi.RSSI 获取WiFi信号强度
*********************************************************************************************************/
void ip_OLED() {
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawHLine(0, 10, 128);
u8g2.drawHLine(0, 63, 128);
u8g2.drawStr(122, 8, "0");

u8g2.drawStr(0, 21, "SSID");
u8g2.drawStr(31, 21, ":");
u8g2.setCursor(34, 21);
u8g2.print(WiFi.SSID());

u8g2.drawStr(0, 31, "Pswd");
u8g2.drawStr(31, 31, ":");
u8g2.setCursor(34, 31);
u8g2.print(WiFi.psk());

u8g2.drawStr(0, 41, "GaIP");
u8g2.drawStr(31, 41, ":");
u8g2.setCursor(34, 41);
u8g2.print(WiFi.gatewayIP());

u8g2.drawStr(0, 51, "LoIP");
u8g2.drawStr(31, 51, ":");
u8g2.setCursor(34, 51);
u8g2.print(WiFi.localIP());

u8g2.drawStr(0, 61, "MAC");
u8g2.drawStr(29, 61, ":");
u8g2.setCursor(33, 61);
u8g2.print(WiFi.macAddress());

u8g2.setCursor(0, 8);
u8g2.print(WiFi.RSSI());
}
/*********************************************************************************************************
获取ip相关信息并用OLED显示

*********************************************************************************************************/
void ip_OLED_0() {
u8g2.clearBuffer();
u8g2.firstPage();
ip_OLED();
time_OLED2();
DTH11_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
获取运行时间信息

*********************************************************************************************************/
void yxsj_OLED() {
String fh; String tianbl; String shibl; String fenbl; String miaobl;

u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(122, 8, "0");
u8g2.setFont(u8g2_font_wqy13_t_gb2312b);
u8g2.setCursor(0, 25);
u8g2.print("运行时间:");

time_t run_time = Blinker.runTime(); //获取运行时间,单位为秒
tian1 =run_time / 86400; //转化为天
shi1= (run_time - tian1 * 86400 ) / 3600; //转化为时
fen1= (run_time - tian1 * 86400 - shi1 * 3600) / 60; //转化为分
miao1 =run_time - tian1 * 86400 - shi1 * 3600 - fen1 * 60; //转化为秒
if (tian1 < 10) {
    tianbl = String("") + "0" + tian1;
}
else {
    tianbl = String("") + tian1;
}
if (shi1 < 10) {
    shibl = String("") + "0" + shi1;
}
else {
    shibl = String("") + shi1;
}
if (fen1 < 10) {
    fenbl = String("") + "0" + fen1;
}
else {
    fenbl = String("") + fen1;
}
if (miao1 < 10) {
    miaobl = String("") + "0" + miao1;
}
else {
    miaobl = String("") + miao1;
}

if (tian1 == 0 & shi1 == 0 & fen1 == 0) {
    fh = String("") + miaobl + "秒";
}
else if (tian1 == 0 & shi1 == 0 ) {
    fh = String("") + fenbl + "分" + miaobl + "秒";
}
else if (tian1 == 0) {
    fh = String("") + shibl + "时" + fenbl + "分" + miaobl + "秒";
}
else {
    fh = String("") + tianbl + "天" + shibl + "时" + fenbl + "分" + miaobl + "秒";
}
u8g2.setCursor(0, 40);
u8g2.print(fh);
}
/*********************************************************************************************************
获取运行时间并用OLED显示

*********************************************************************************************************/
void yxsj_OLED_0() {
u8g2.clearBuffer();
u8g2.firstPage();
yxsj_OLED();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
滑动条存储在EEPROM的延时函数

*********************************************************************************************************/
void yanshi() {
EEPROM.begin(2450);
int shua3 = EEPROM.read(2449);
shua2 = shua3;
EEPROM.end();
shua1 = shua2 * 1000;
Blinker.delay(shua1);
}
/*********************************************************************************************************
OLED第零屏显示,WiFi,ip

*********************************************************************************************************/
void OLED_0() {
ip_OLED_0();
yanshi();
Blinker.run();
yxsj_OLED_0();
}
/*********************************************************************************************************
OLED第一屏显示,时间

*********************************************************************************************************/
void OLED_1() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED();
DTH11_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
OLED第二屏显示,WiFi,温度

*********************************************************************************************************/
void OLED_2() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
DTH11_OLED();
time_OLED2();
u8g2.nextPage();
}
/*********************************************************************************************************
OLED第三屏显示,天气

*********************************************************************************************************/
void OLED_3() {
w_OLED();
yanshi();
Blinker.run();
w_OLED2();
}
/*********************************************************************************************************
OLED第四屏显示,空气

*********************************************************************************************************/
void OLED_4() {
u8g2.clearBuffer();
u8g2.firstPage();
Wifi_OLED();
time_OLED2();
DTH11_OLED2();
aqi_OLED();
u8g2.nextPage();
}
/*********************************************************************************************************
按键状态回调函数

*********************************************************************************************************/
void huidiaoneirong() {
if (b0 == 0) {
    Btn_wifi.icon("fal fa-wifi");
    Btn_wifi.text("WiFi信息");
    Btn_wifi.print("off");
}
if (b0 == 1) {
    Btn_wifi.icon("fal fa-wifi");
    Btn_wifi.text("WiFi信息");
    Btn_wifi.print("off");
}
if (b0 == 2) {
    Btn_wifi.icon("fal fa-wifi");
    Btn_wifi.text("显示WiFi信息");
    Btn_wifi.print("on");
}

if (b1 == 0) {
    Btn_time.text("时间");
    Btn_time.print("off");
}
if (b1 == 1) {
    Btn_time.text("时间");
    Btn_time.print("off");
}
if (b1 == 2) {
    Btn_time.text("显示时间");
    Btn_time.print("on");
}

if (b2 == 0) {
    Btn_temp_humi.text("温湿度");
    Btn_temp_humi.print("off");
}
if (b2 == 1) {
    Btn_temp_humi.text("温湿度");
    Btn_temp_humi.print("off");
}
if (b2 == 2) {
    Btn_temp_humi.text("显示温湿度");
    Btn_temp_humi.print("on");
}

if (b3 == 0) {
    Btn_weather.text("天气信息");
    Btn_weather.print("off");
}
if (b3 == 1) {
    Btn_weather.text("天气信息");
    Btn_weather.print("off");
}
if (b3 == 2) {
    Btn_weather.text("显示天气信息");
    Btn_weather.print("on");
}

if (b4 == 0) {
    Btn_air.text("空气信息");
    Btn_air.print("off");
}
if (b4 == 1) {
    Btn_air.text("空气信息");
    Btn_air.print("off");
}
if (b4 == 2) {
    Btn_air.text("显示空气信息");
    Btn_air.print("on");
}

if (c2 == 0 ) {
    if (a1 == 0 ) {
      Btn_OLED.icon("fas fa-toggle-on");
      Btn_OLED.text("屏幕自动打开");
      Btn_OLED.print("on");
    }
}
if (c2 == 0 ) {
    if (a1 == 1 ) {
      Btn_OLED.icon("fas fa-toggle-off");
      Btn_OLED.text("屏幕自动关闭");
      Btn_OLED.print("off");
    }
}
if (c2 == 1 ) {
    if (a1 == 0 ) {
      Btn_OLED.icon("fas fa-toggle-on");
      Btn_OLED.text("屏幕手动打开");
      Btn_OLED.print("on");
    }
}
if (c2 == 1 ) {
    if (a1 == 1 ) {
      Btn_OLED.icon("fas fa-toggle-off");
      Btn_OLED.text("屏幕手动关闭");
      Btn_OLED.print("off");
    }
}

if (c3 == 0 ) {
    Btn_xyd.icon("fal fa-lightbulb");
    Btn_xyd.text("小夜灯关闭");
    Btn_xyd.print("off");
}
if (c3 == 1 ) {
    Btn_xyd.icon("fal fa-lightbulb-on");
    Btn_xyd.text("小夜灯打开");
    Btn_xyd.print("on");
}

Blinker.delay(1000);
if (c1 == 0 ) {
    Btn_fmq.icon("fal fa-bell");
    Btn_fmq.text("蜂鸣器关闭");
    Btn_fmq.print("off");
}
if (c1 == 1 ) {
    Btn_fmq.icon("fal fa-bell-on");
    Btn_fmq.text("蜂鸣器打开");
    Btn_fmq.print("on");
}

Number1.icon("fal fa-wifi");
Number1.print(WiFi.RSSI());
Text_ip.print(WiFi.localIP().toString().c_str());

EEPROM.begin(2450);
int shua3 = EEPROM.read(2449);
shua2 = shua3;
Slider1.print(shua2);
EEPROM.end();

}
/*********************************************************************************************************
收到指令蜂鸣器响一声

*********************************************************************************************************/
void fmq_1m() {
if(c1 == 1 ) {
digitalWrite(fmq1, LOW);
Blinker.delay(50);
digitalWrite(fmq1, HIGH);
}
}
/*********************************************************************************************************
按键操作OLED显示WiFi

*********************************************************************************************************/
void Btn_wifi_callback(const String & state) {
//BLINKER_LOG("get button state3: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 2; b1 = 0; b2 = 0; b3 = 0; b4 = 0; //单独显示WiFi
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1; //恢复屏幕滚动显示
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示时间

*********************************************************************************************************/
void Btn_time_callback(const String & state) {
//BLINKER_LOG("get button state1: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 2; b2 = 0; b3 = 0; b4 = 0;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示温湿度

*********************************************************************************************************/
void Btn_temp_humi_callback(const String & state) {
//BLINKER_LOG("get button state2: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 0; b2 = 2; b3 = 0; b4 = 0;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示天气

*********************************************************************************************************/
void Btn_weather_callback(const String & state) {
//BLINKER_LOG("get button state3: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 0; b2 = 0; b3 = 2; b4 = 0;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
按键操作OLED显示空气质量

*********************************************************************************************************/
void Btn_air_callback(const String & state) {
//BLINKER_LOG("get button state3: ", state);
if (state == "on") {
    if (a1 == 0) {
      b0 = 0; b1 = 0; b2 = 0; b3 = 0; b4 = 2;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
else if (state == "off") {
    if (a1 == 0) {
      b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
      Blinker.vibrate();
      fmq_1m();
      huidiaoneirong();
    }
}
}
/*********************************************************************************************************
定时关闭OLED

*********************************************************************************************************/
void dingshiguanbioled() {
int8_t hour = Blinker.hour();//时
int8_t min= Blinker.minute();//分
if (hour < 7 ) { //小于7时自动关闭屏幕
    if (c2 == 0) {
      a1 = 1;
    }
}
if (hour <= -1 ) { //未获取到时间自动打开屏幕
    if (c2 == 0)   {
      a1 = 0;
    }
}
if (hour >= 7 ) { //等于、大于7时自动打开屏幕
    if (c2 == 0){
      a1 = 0;
    }
}

u8g2.setPowerSave(a1);

if (hour == 0 ) { //零点切换自动模式
    if (min < 2 ) {
      c2 = 0;
    }
}
if (hour == 7 ) { //七点切换自动模式
    if (min < 2 ) {
      c2 = 0;
    }
}
}
/*********************************************************************************************************
按键操作OLED屏幕滚动

*********************************************************************************************************/
void Btn_Refresh_callback(const String & state) {
//BLINKER_LOG("get button state4: ", state);
b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1; c2 = 0;
Blinker.vibrate();
fmq_1m();
dingshiguanbioled();
huidiaoneirong();
}
/*********************************************************************************************************
按键操作开关OLED屏幕

*********************************************************************************************************/
void Btn_OLED_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
    a1 = 0; c2 = 1; b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
    Blinker.vibrate();
    fmq_1m();
    huidiaoneirong();
    u8g2.setPowerSave(a1);
}
else if (state == "off") {
    a1 = 1; c2 = 1; b0 = 0; b1 = 0; b2 = 0; b3 = 0; b4 = 0;
    Blinker.vibrate();
    fmq_1m();
    huidiaoneirong();
    u8g2.setPowerSave(a1);
}
}
/*********************************************************************************************************
按键操作蜂鸣器

*********************************************************************************************************/
void Btn_fmq_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
    c1 = 1;
    Blinker.vibrate();
    fmq_1m();
    Btn_fmq.icon("fal fa-bell-on");
    Btn_fmq.text("蜂鸣器打开");
    Btn_fmq.print("on");
}
else if (state == "off") {
    c1 = 0;
    Blinker.vibrate();
    Btn_fmq.icon("fal fa-bell");
    Btn_fmq.text("蜂鸣器关闭");
    Btn_fmq.print("off");
}
}
/*********************************************************************************************************
按键操作小夜灯

*********************************************************************************************************/
void Btn_xyd_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
    c3 = 1;
    fmq_1m();
    Blinker.vibrate();
    digitalWrite(xyd1, HIGH);
    digitalWrite(xyd2, HIGH);
    huidiaoneirong();
}
else if (state == "off") {
    c3 = 0;
    fmq_1m();
    Blinker.vibrate();
    digitalWrite(xyd1, LOW);
    digitalWrite(xyd2, LOW);
    huidiaoneirong();
    Blinker.delay(50);
    digitalWrite(xyd2, HIGH);
}
}
/*********************************************************************************************************
切屏滑动条

*********************************************************************************************************/
void slider1_callback(int32_t value)
{
BLINKER_LOG("get slider value: ", value);
Blinker.vibrate();
huidiaoneirong();
EEPROM.begin(2450);
EEPROM.write(2449, value);
Slider1.print(value);
EEPROM.end();
}
/**********************************************************************************************************
WiFi配置清除

**********************************************************************************************************/
void Btn_WIFIEE_callback(const String & state) {
Blinker.reset();
}
void wifirst1(){
wifirstState = digitalRead(wifirst);
if(wifirstState == HIGH){
    Blinker.reset();
}
}
/*********************************************************************************************************
OLED关闭后不显示内容

*********************************************************************************************************/
void shifouxianshi() {
if (a1 == 0) {
    if (b0 == 1) {
      OLED_0(); yanshi();
      Blinker.run();
    }
    if (b0 == 2) {
      OLED_0();yanshi();
    }
    if (b1 == 1) {
      OLED_1();yanshi();
      Blinker.run();
    }
    if (b1 == 2) {
      OLED_1(); yanshi();
    }
    if (b2 == 1) {
      OLED_2();yanshi();
      Blinker.run();
    }
    if (b2 == 2) {
      OLED_2();yanshi();
    }
    if (b3 == 1) {
      OLED_3();yanshi();
      Blinker.run();
    }
    if (b3 == 2) {
      OLED_3();yanshi();
    }
    if (b4 == 1) {
      OLED_4();yanshi();
      Blinker.run();
    }
    if (b4 == 2) {
      OLED_4();yanshi();
    }
}
if (a1 == 1) {
    b0 = 0; b1 = 1; b2 = 1; b3 = 1; b4 = 1;
}
}
/*********************************************************************************************************
给blinkerapp回传数据

*********************************************************************************************************/
void heartbeat() {
HUMI.print(humi_read); //给blinkerapp回传湿度数据
TEMP.print(temp_read); //给blinkerapp回传温度数据
huidiaoneirong();
}
/*********************************************************************************************************
将设置代码放在此处,运行一次

*********************************************************************************************************/
void setup() {
//初始化端口
Serial.begin(115200);

Blinker.begin(auth); //初始化blinker
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();

pinMode(fmq1, OUTPUT); //蜂鸣器引脚设置为输出模式
pinMode(xyd1, OUTPUT); //小夜灯引脚设置为输出模式
pinMode(xyd2, OUTPUT); //小夜灯引脚设置为输出模式

pinMode(wifirst, INPUT);//按键清除WiFi配置设置为输入模式

digitalWrite(fmq1, HIGH); //蜂鸣器引脚高电平输出
digitalWrite(xyd1, LOW); //小夜灯引脚低电平输出
digitalWrite(xyd2, HIGH); //小夜灯引脚高电平输出

u8g2.begin(); //初始化OLED
u8g2.enableUTF8Print();
u8g2.clearBuffer();
u8g2.clearDisplay();
u8g2.setPowerSave(0);

dht.begin(); //初始化DHT传感器

Blinker.setTimezone(8.0);
Blinker.attachHeartbeat(heartbeat); //将传感器获取的数据传给blinker app上
Blinker.attachDataStorage(dataStorage); //注册回调函数,开启历史数据存储功能
BlinkerAliGenie.attachQuery(aligenieQuery); //天猫精灵回调函数,回调温湿度数据给天猫精灵
Blinker.attachWeather(weatherData); //注册回调函数,获取天气信息
Blinker.attachAir(airData); //注册回调函数,获取空气质量信息

Btn_time.attach(Btn_time_callback);
Btn_temp_humi.attach(Btn_temp_humi_callback);
Btn_wifi.attach(Btn_wifi_callback);
Btn_Refresh.attach(Btn_Refresh_callback);
Btn_OLED.attach(Btn_OLED_callback);
Btn_weather.attach(Btn_weather_callback);
Btn_air.attach(Btn_air_callback);
Btn_fmq.attach(Btn_fmq_callback);
Btn_xyd.attach(Btn_xyd_callback);
Slider1.attach(slider1_callback);
Btn_WIFIEE.attach(Btn_WIFIEE_callback);
}
/*********************************************************************************************************
把主代码放在这里,重复运行
通过循环不断读取温湿度传感器获取的数据

*********************************************************************************************************/
void loop() {
Blinker.run(); //运行Blinker

wifirst1();//按键清除WiFi配置
DHT11_1(); //开机获取环境温度
kjgxtq(); //开机获取天气信息
jggxtq(); //间隔更新天气信息
dingshiguanbioled(); //定时关闭OLED
shifouxianshi(); //关闭屏幕后不运行显部分相关程序
}

wactor8431 发表于 2020-12-10 10:46

wactor8431 发表于 2020-12-10 10:44
为什么时区要 改为 这样,才没有时差 Blinker.setTimezone(-8.0);    我们中国不是8 吗? ...

:L时间对了,日期却晚了1天

单片机菜鸟 发表于 2020-11-4 00:09

不错不错
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 自制WiFi天气温湿度时钟,Blinker esp-01(8266) 128*64 OLED屏