Blinker 天气时钟 esp8266+SH1106 OLCD屏显示
🌼更新时间:2022年12月24日 12:37:07
✨本文总会有人翻到,虽然距离发布时间已经很长时间了,今天来更新一下,顺便回答一下评论区的疑惑。
- 🔖本篇所使用到的库随着时间也在更新,我的电脑也换了新硬盘,也是一个全新的环境来编译原来的程序代码,将编译遇到的所有问题进行处理。代码整体没有说明改动,功能都在,由于blinker库的更新,数据都可以在OLED上看到。
- 📋编译信息:
使用 1.0 版本的库 ESP8266WiFi 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi
使用 6.19.4 版本的库 ArduinoJson 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\ArduinoJson
使用 0.3.9 版本的库 Blinker 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\Blinker
使用 1.2 版本的库 ESP8266mDNS 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266mDNS
使用 1.2 版本的库 ESP8266HTTPClient 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266HTTPClient
使用 1.0 版本的库 EEPROM 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\EEPROM
使用 1.0 版本的库 Ticker 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Ticker
使用 1.3 版本的库 ESP8266httpUpdate 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266httpUpdate
使用 1.4.4 版本的库 DHT_sensor_library 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\DHT_sensor_library
使用 2.33.15 版本的库 U8g2 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\U8g2
使用 1.0.0 版本的库 DS18B20 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\DS18B20
使用 2.3.7 版本的库 OneWire 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\OneWire
使用 4.3.0 版本的库 ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays
使用 1.0 版本的库 Wire 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Wire
使用 1.0 版本的库 Hash 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Hash
使用 1.1.6 版本的库 Adafruit_Unified_Sensor 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\Adafruit_Unified_Sensor
使用 1.0 版本的库 SPI 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SPI
"C:\\Users\\Administrator\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.0.4-gcc10.3-1757bed/bin/xtensa-lx106-elf-size" -A "d:\\arduino\\MyHexDir/Blinker_esp8266_02.ino.elf"
项目使用了 701965 字节,占用了 (67%) 程序存储空间。最大为 1044464 字节。
全局变量使用了40036字节,(48%)的动态内存,余留41884字节局部变量。最大为81920字节。
- 原代码编译报错处理:
- blinker库报错1:
/*********************************************************************************************************
给一个地址获取天气数据
功能;通过地址参数获取天气信息延时一秒后在空气信息
输入参数:给 weather 输入地址参数
输入参数:给 aqi 输入地址参数
*********************************************************************************************************/
void tianqi() {
Blinker.weather();//不带参数,默认查询设备ip所属地区的当前时刻的天气情况
Blinker.delay(1000);
Blinker.air(); //不带参数,默认查询设备ip所属地区的当前时刻的空气质量
}
或者将变量location
改为uint32_t
数据类型,定义内容为所在城市的城市编码
uint32_t location = 510100; //定义所在城市的城市编码
- 📌城市编码查询:
http://preview.www.mca.gov.cn/article/sj/xzqh/2020/2020/202101041104.html
- 📍需要安装最新库Blinker库:
https://github.com/blinker-iot/blinker-library
#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头文件
#include <ArduinoJson.h> //包含ArduinoJson头文件,用于解析从点灯获取到的天气数据
#include <Blinker.h> //包含Blinker头文件,用于连接点灯科技
#include <DHT.h> //包含DHT头文件,用于温湿度传感器获取数据
#include <U8g2lib.h> //包含u8g2头文件,用于OLED显示
#include <DS18B20.h>
DS18B20 ds(D7); //温度传感器io口
#include "SH1106Wire.h" //1.3寸用这个
#define U8X8_HAVE_HW_I2C
#include <Wire.h>
const int I2C_DISPLAY_ADDRESS = 0x3c; //I2c地址默认
#if defined(ESP8266)//OLED引脚定义
const int SDA_PIN = D2;//对应nodemcu接D5或者D1,,wemosD1mini的D2
const int SDC_PIN = D1;//对应nodemcu接D6或者D2,,wemosD1mini的D5
#else
const int SDA_PIN = D1;//对应nodemcu接D5或者D1
const int SDC_PIN = D2;//对应nodemcu接D6或者D2
#endif
U8G2_SH1106_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*SCL*/ D1, /*SDA*/ D2, /*reset*/ U8X8_PIN_NONE);
SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); // 1.3寸用这个
#ifdef U8X8_HAVE_HW_I2C //定义OLED连接方式为I2C
#include <Wire.h>
#endif
- blinker库报错2:调用
Blinker.begin(auth, ssid, pswd);
报错,注释掉下面的宏
#define BLINKER_ESP_SMARTCONFIG
或者使用宏添加判断语句:(直接WIFI信息写入的方式)
#if defined(BLINKER_ESP_SMARTCONFIG)
Blinker.begin(auth); //初始化blinker
#else
Blinker.begin(auth, ssid, pswd);
#endif
🌼更新的全部代码:(去掉了DS18B20)
如果使用DS18B20替代DHT11,可以启用DS18B20库,来替代DHT11,定义的引脚都是同一个。
#define BLINKER_WIFI //定义wifi模块
#define BLINKER_WITHOUT_SSL //非SSL加密通信接入,省堆栈
#define BLINKER_PRINT Serial //给debug打开串口
//#define BLINKER_ESP_SMARTCONFIG //定义EspTouch/SmartConfig模式进行配网,可以用APP配网,注释掉:Blinker.begin(auth)
#define BLINKER_ALIGENIE_SENSOR //连接天猫精灵,定义设备类型为传感器
#include <ESP8266WiFi.h> //包含ESP8266头文件
#include <ArduinoJson.h> //包含ArduinoJson头文件,用于解析从点灯获取到的天气数据
#include <Blinker.h> //包含Blinker头文件,用于连接点灯科技
#include <DHT.h> //包含DHT头文件,用于温湿度传感器获取数据
#include <U8g2lib.h> //包含u8g2头文件,用于OLED显示
//#include <DS18B20.h>
//DS18B20 ds(D7); //温度传感器io口
#include "SH1106Wire.h" //1.3寸用这个
#define U8X8_HAVE_HW_I2C
#include <Wire.h>
const int I2C_DISPLAY_ADDRESS = 0x3c; //I2c地址默认
#if defined(ESP8266)//OLED引脚定义
const int SDA_PIN = D2;//对应nodemcu接D5或者D1,,wemosD1mini的D2
const int SDC_PIN = D1;//对应nodemcu接D6或者D2,,wemosD1mini的D5
#else
const int SDA_PIN = D1;//对应nodemcu接D5或者D1
const int SDC_PIN = D2;//对应nodemcu接D6或者D2
#endif
U8G2_SH1106_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*SCL*/ D1, /*SDA*/ D2, /*reset*/ U8X8_PIN_NONE);
SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); // 1.3寸用这个
//****wifi、设备的定义****
char auth[] = "73933528b8e2"; //设备key号
char ssid[] = "MERCURY_D268G"; //wifi名称
char pswd[] = "pba5ayzk"; //wifi密码
//display.flipScreenVertically(); //屏幕翻转
/*********************************************************************************************************
日期:2021/1/08
功能:WiFi+DHT11+SH1106 OLED+有源蜂鸣器+继电器 8266端
128X64OLED显示 DHT11获取温度 蜂鸣器蜂鸣 继电器工作
调用Blinker、ESP8266、ArduinoJson、DHT、u8g2库文件
*********************************************************************************************************/
#ifdef U8X8_HAVE_HW_I2C //定义OLED连接方式为I2C
#include <Wire.h>
#endif
//定义128X64四针OLED模块连接管脚io14、io2
#define DHTPIN D7 //定义DHT11模块连接管脚io5
#define DHTTYPE DHT11 //使用温度湿度模块的类型为DHT11
DHT dht(DHTPIN, DHTTYPE); //生成DHT对象,参数是引脚和DHT的类型
#define TEXTE_ip "tex-ip"
/*********************************************************************************************************
定义全局变量
*********************************************************************************************************/
String location = "hunan-changshashi"; //定义天气地址
float humi_read = 0, currTemp = 8.8; //定义浮点型全局变量 储存传感器读取的温湿度数据
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;
char w_weather[12] = ""; //天气
char w_temp[10] = ""; //室外温度
char w_humi[24] = ""; //室外湿度
char w_wind[10] = ""; //风向
char w_power[10] = ""; //风力
char a_aqi[12] = ""; //空气质量
char a_level[12] = ""; //空气等级
char a_pm25[10] = ""; //pm2.5
/*********************************************************************************************************
新建数据类型组件对象,作用:将数据传输到手机blinker app
*********************************************************************************************************/
BlinkerText Text_ip("Text_ip");
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");
currTemp = t - 0.6; //校准温度
humi_read = h - 11; //校准湿度
if (a1 == 1) {
Blinker.delay(2000);
}
}
}
/*********************************************************************************************************
云存储回调函数
*********************************************************************************************************/
void dataStorage() {
Blinker.dataStorage("temp", currTemp);
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(currTemp);
BlinkerAliGenie.humi(humi_read);
BlinkerAliGenie.print();
break;
case BLINKER_CMD_QUERY_TEMP_NUMBER :
BlinkerAliGenie.temp(currTemp);
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("") + "室内温度:" + currTemp + "°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();//默认查询设备ip所属地区的当前时刻的天气情况
Blinker.delay(1000);
Blinker.air();//默认查询设备ip所属地区的当前时刻的空气质量情况
Blinker.delay(1000);
}
/*********************************************************************************************************
开机更新天气信息
功能:开机等待五秒后获取天气信息
变量: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[0] == '{') {
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;
}
uint32_t BlinkerTime = millis();
Blinker.print("millis", BlinkerTime);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Blinker.weather();//默认查询设备ip所属地区的当前时刻的天气情况
Blinker.delay(60000);
}
/*********************************************************************************************************
获取天气信息并用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[0] == '{') {
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_t month = Blinker.month(); //月
int8_t mday = Blinker.mday(); //日
int8_t wday = Blinker.wday(); //星期
int8_t hour = Blinker.hour(); //时
int8_t min = Blinker.minute(); //分
int8_t sec = 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";
wendu2 = String("") + currTemp + "°C";
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(75, 8);
u8g2.print(wendu2);
}
/*********************************************************************************************************
OLED第零屏显示,WiFi,ip
*********************************************************************************************************/
void OLED_0() {
ip_OLED_0();
Blinker.delay(5000);
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();
Blinker.delay(5000);
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") {
b0 = 2;
b1 = 0;
b2 = 0;
b3 = 0;
b4 = 0;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
}
else if (state == "off") {
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") {
b0 = 0;
b1 = 2;
b2 = 0;
b3 = 0;
b4 = 0;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
}
else if (state == "off") {
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") {
b0 = 0;
b1 = 0;
b2 = 2;
b3 = 0;
b4 = 0;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
}
else if (state == "off") {
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") {
b0 = 0;
b1 = 0;
b2 = 0;
b3 = 2;
b4 = 0;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
}
else if (state == "off") {
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") {
b0 = 0;
b1 = 0;
b2 = 0;
b3 = 0;
b4 = 2;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
}
else if (state == "off") {
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;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
u8g2.setPowerSave(false);
}
else if (state == "off") {
a1 = 1;
c2 = 1;
Blinker.vibrate();
fmq_1m();
huidiaoneirong();
u8g2.setPowerSave(true);
}
}
/*********************************************************************************************************
按键操作蜂鸣器
*********************************************************************************************************/
void Btn_fmq_callback(const String & state) {
//BLINKER_LOG("get button state5: ", state);
if (state == "on") {
c1 = 1;
Blinker.vibrate();
digitalWrite(fmq1, LOW);
huidiaoneirong();
}
else if (state == "off") {
c1 = 0;
Blinker.vibrate();
digitalWrite(fmq1, HIGH);
huidiaoneirong();
}
}
/*********************************************************************************************************
按键操作小夜灯
*********************************************************************************************************/
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 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");
}
}
Blinker.delay(100);
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");
}
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");
}
}
/*********************************************************************************************************
收到指令蜂鸣器响一声
*********************************************************************************************************/
void fmq_1m() {
c1 = 0;
digitalWrite(fmq1, LOW);
Blinker.delay(50);
digitalWrite(fmq1, HIGH);
}
/*********************************************************************************************************
OLED关闭后不显示内容
*********************************************************************************************************/
void shifouxianshi() {
if (a1 == 0) {
if (b0 == 1) {
OLED_0();
Blinker.delay(5000);
Blinker.run();
}
if (b0 == 2) {
OLED_0();
Blinker.delay(5000);
}
if (b1 == 1) {
OLED_1();
Blinker.delay(5000);
Blinker.run();
}
if (b1 == 2) {
OLED_1();
Blinker.delay(5000);
}
if (b2 == 1) {
OLED_2();
Blinker.delay(5000);
Blinker.run();
}
if (b2 == 2) {
OLED_2();
Blinker.delay(5000);
}
if (b3 == 1) {
OLED_3();
Blinker.delay(5000);
Blinker.run();
}
if (b3 == 2) {
OLED_3();
Blinker.delay(5000);
}
if (b4 == 1) {
OLED_4();
Blinker.delay(5000);
}
if (b4 == 2) {
OLED_4();
Blinker.delay(5000);
}
}
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(true);
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(currTemp); //给blinkerapp回传温度数据
Number1.icon("fal fa-wifi");
Number1.print(WiFi.RSSI());
Text_ip.print(WiFi.localIP().toString().c_str());
huidiaoneirong();
}
/*********************************************************************************************************
将设置代码放在此处,运行一次
*********************************************************************************************************/
void setup() {
//初始化端口
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
#if defined(BLINKER_ESP_SMARTCONFIG)
Blinker.begin(auth); //初始化blinker
#else
Blinker.begin(auth, ssid, pswd);
#endif
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(false);//OLED关闭省电模式
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);
}
/*********************************************************************************************************
把主代码放在这里,重复运行
通过循环不断读取温湿度传感器获取的数据
*********************************************************************************************************/
void loop() {
Blinker.run(); //运行Blinker
// currTemp = ds.getTempC();
DHT11_1(); //开机获取环境温度
kjgxtq(); //开机获取天气信息
jggxtq(); //间隔更新天气信息
dingshiguanbioled(); //定时关闭OLED
shifouxianshi(); //关闭屏幕后不运行显部分相关程序
}
- 📜编译信息:
使用 1.0 版本的库 ESP8266WiFi 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi
使用 6.19.4 版本的库 ArduinoJson 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\ArduinoJson
使用 0.3.9 版本的库 Blinker 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\Blinker
使用 1.2 版本的库 ESP8266mDNS 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266mDNS
使用 1.2 版本的库 ESP8266HTTPClient 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266HTTPClient
使用 1.0 版本的库 EEPROM 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\EEPROM
使用 1.0 版本的库 Ticker 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Ticker
使用 1.3 版本的库 ESP8266httpUpdate 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266httpUpdate
使用 1.4.4 版本的库 DHT_sensor_library 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\DHT_sensor_library
使用 2.33.15 版本的库 U8g2 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\U8g2
使用 4.3.0 版本的库 ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays
使用 1.0 版本的库 Wire 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Wire
使用 1.0 版本的库 Hash 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Hash
使用 1.1.6 版本的库 Adafruit_Unified_Sensor 在文件夹: C:\Users\Administrator\Documents\Arduino\libraries\Adafruit_Unified_Sensor
使用 1.0 版本的库 SPI 在文件夹: C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SPI
"C:\\Users\\Administrator\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.0.4-gcc10.3-1757bed/bin/xtensa-lx106-elf-size" -A "d:\\arduino\\MyHexDir/Blinker_esp8266_02.ino.elf"
项目使用了 699485 字节,占用了 (66%) 程序存储空间。最大为 1044464 字节。
全局变量使用了40020字节,(48%)的动态内存,余留41900字节局部变量。最大为81920字节。
📓以前原发布内容
OLED自动显示效果图:
第一屏:
第二屏:
第三屏幕:
第四屏幕:
上电串口打印信息:
手机APP,Blinker应用端:
手机APP界面的可以查看开发板的温湿度显示,所处环境wifi信号强度显示,按键控制OLED屏幕相关的显示内容,以及控制其他IO口接入的设备。
点击查看wifi信息:,OLED如下图显示:
如果不想让OLED屏幕一直亮着显示,可以关闭屏幕:
注册的相关数据类型组件:
/*********************************************************************************************************
注册的相关数据类型组件对象,作用:将数据传输到手机blinker app
*********************************************************************************************************/
BlinkerText Text_ip("Text_ip");
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");
⛳源码下载:
链接:https://pan.baidu.com/s/1lk8eqMGrrqfP--Q-TA_UEw
提取码:nkee