465 lines
13 KiB
C++
465 lines
13 KiB
C++
/**
|
||
*
|
||
* 小夜灯
|
||
*
|
||
*/
|
||
|
||
#define BLINKER_MIOT_LIGHT
|
||
#define BLINKER_WIFI
|
||
#include <ESP8266WiFi.h>
|
||
#include <Blinker.h>
|
||
#include <WS2812FX.h>
|
||
#define BLINKER_OTA_VERSION_CODE "1.0.1"
|
||
|
||
//【据自己情况修改】Blinker 的秘钥
|
||
char auth[] = "74f87766a518";
|
||
// 自己家中的 2.4G wifi名称
|
||
char ssid[] = "bmy";
|
||
// 自己家中的 2.4G wifi密码
|
||
char pswd[] = "lb714500";
|
||
|
||
//【据自己情况修改】WS2812的 GPIO 引脚编号
|
||
#define LED_PIN 4 // 对应开发板上的 D2
|
||
#define LED_COUNT 30 //【据自己情况修改】灯珠个数
|
||
#define DEFAULT_COLOR 0xFF5900 // 初始化灯的颜色
|
||
#define DEFAULT_BRIGHTNESS 255 // 初始化亮度
|
||
#define DEFAULT_SPEED 1000 // 初始化速度
|
||
#define DEFAULT_MODE FX_MODE_STATIC // 初始化灯的模式
|
||
//HC-SR501红外人体感应模块的 GPIO 引脚编号
|
||
#define irSensor_PIN 5 // 对应开发板上的 D1
|
||
bool sensorReading = 0; // 红外人体感应模块 读到的数值 1 表示有人,0 表示无人,默认0无人
|
||
bool isUseSensor = false; // 是否使用人体红外感应模块 true 使用, false 不使用
|
||
#define TIMER_MS 4000 // 随机主题模式间隔切换时间
|
||
bool isUseRandomTheme = false; // 是否使用随机主题模式 true 使用,false 不使用,默认false不使用
|
||
unsigned long last_change = 0; // 上一次切换的事件
|
||
unsigned long now = 0; // 当前的时候
|
||
|
||
// 初始化 WS2812FX
|
||
WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
|
||
|
||
// 颜色选择器
|
||
BlinkerRGB RGB1("RGB");
|
||
// 开灯按钮
|
||
BlinkerButton openButton("open");
|
||
// 工作模式按钮
|
||
BlinkerButton workButton("work");
|
||
// 默认模式按钮
|
||
BlinkerButton defaultButton("default");
|
||
// 红外人体传感器按钮
|
||
BlinkerButton sensorButton("sensor");
|
||
// 休眠模式按钮
|
||
BlinkerButton sleepButton("sleep");
|
||
// 随机模式按钮
|
||
BlinkerButton randomButton("random");
|
||
// 亮度调节
|
||
BlinkerSlider brightnessSlider("brightness");
|
||
|
||
|
||
//APP RGB颜色设置回调
|
||
void rgb1_callback(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value) {
|
||
ws2812fx.setColor(ws2812fx.Color(r_value, g_value, b_value));
|
||
if (bright_value != 0) {
|
||
ws2812fx.setBrightness(bright_value);
|
||
}
|
||
}
|
||
|
||
// 开灯
|
||
void openLamp() {
|
||
if (!ws2812fx.isRunning()) {
|
||
openButton.color("#F0AA41");
|
||
openButton.text("已开启");
|
||
openButton.print("on");
|
||
ws2812fx.start();
|
||
}
|
||
}
|
||
|
||
// 关灯
|
||
void closeLamp() {
|
||
if (ws2812fx.isRunning()) {
|
||
closeRandom();
|
||
openButton.color("#595959");
|
||
openButton.text("已关闭");
|
||
openButton.print("off");
|
||
ws2812fx.stop();
|
||
}
|
||
}
|
||
|
||
// 开关灯的回调函数
|
||
void openLamp_Callback(const String & state) {
|
||
if (state == BLINKER_CMD_ON) {
|
||
openLamp();
|
||
} else if (state == BLINKER_CMD_OFF) {
|
||
closeLamp();
|
||
}
|
||
}
|
||
|
||
// 亮度:将 0 ~ 255 的数值转换为 0 ~ 100 亮度
|
||
int BrightTransformation(int Bright) {
|
||
return 100 * Bright / 255;
|
||
}
|
||
|
||
// 默认模式按钮被点击的回调函数
|
||
void defaultButton_Callback(const String & state) {
|
||
closeRandom();
|
||
|
||
ws2812fx.setBrightness(DEFAULT_BRIGHTNESS);
|
||
ws2812fx.setSpeed(DEFAULT_SPEED);
|
||
ws2812fx.setColor(DEFAULT_COLOR);
|
||
ws2812fx.setMode(DEFAULT_MODE);
|
||
brightnessSlider.print(BrightTransformation(127));
|
||
}
|
||
|
||
// 工作模式按钮被点击的回调函数
|
||
void workButton_Callback(const String & state) {
|
||
closeRandom();
|
||
|
||
ws2812fx.setBrightness(127);
|
||
ws2812fx.setSpeed(1000);
|
||
ws2812fx.setMode(FX_MODE_COLOR_WIPE_RANDOM);
|
||
brightnessSlider.print(BrightTransformation(127));
|
||
}
|
||
|
||
// 休眠模式按钮被点击的回调函数
|
||
void sleepButton_Callback(const String & state) {
|
||
closeRandom();
|
||
ws2812fx.setColor(255, 89, 0);
|
||
ws2812fx.setBrightness(50);
|
||
ws2812fx.setMode(FX_MODE_BREATH);
|
||
brightnessSlider.print(BrightTransformation(50));
|
||
}
|
||
|
||
// 拖动调节亮度
|
||
void brightnessSlider_Callback(int32_t value) {
|
||
uint8_t set_brightness = 255 * int(value) / 100;
|
||
ws2812fx.setBrightness(set_brightness);
|
||
brightnessSlider.print(value);
|
||
}
|
||
|
||
// 随机模式的按钮
|
||
void randomButton_Callback(const String & state) {
|
||
if (state == BLINKER_CMD_ON) {
|
||
isUseRandomTheme = true;
|
||
changeRandomTheme();
|
||
randomButton.text("已开启");
|
||
randomButton.color("#F0AA41");
|
||
randomButton.print("on");
|
||
} else if (state == BLINKER_CMD_OFF) {
|
||
closeRandom();
|
||
}
|
||
}
|
||
|
||
// 关闭随机模式
|
||
void closeRandom() {
|
||
isUseRandomTheme = false;
|
||
randomButton.text("随机模式");
|
||
randomButton.color("#595959");
|
||
randomButton.print("off");
|
||
}
|
||
|
||
// 是否开启传感器的回调
|
||
void sensorButton_Callback(const String & state) {
|
||
if (state == BLINKER_CMD_ON) {
|
||
openSensor();
|
||
} else if (state == BLINKER_CMD_OFF) {
|
||
closeSensor();
|
||
}
|
||
}
|
||
|
||
// 开关红外人体传感器
|
||
void changeUseSensor() {
|
||
BLINKER_LOG("---------------------- changeUseSensor");
|
||
// 为 true 则使用红外人体传感器
|
||
if (isUseSensor) {
|
||
bool sensorReading = digitalRead(irSensor_PIN);
|
||
|
||
Serial.println(sensorReading);
|
||
int8_t hour = Blinker.hour();
|
||
// 判断如果是晚上六点以后,早上六点以前,并且有人,那么开灯
|
||
// if (sensorReading && (hour >= 18 || hour <= 6)) {
|
||
if (sensorReading) {
|
||
openLamp();
|
||
// Serial.println("yes.....");
|
||
} else {
|
||
closeLamp();
|
||
// closeSensor();
|
||
// Serial.println("no.....");
|
||
}
|
||
}
|
||
}
|
||
|
||
void closeSensor() {
|
||
BLINKER_LOG("Toggle off!");
|
||
isUseSensor = false;
|
||
sensorButton.text("已关闭人体传感");
|
||
sensorButton.color("#595959");
|
||
sensorButton.print("off");
|
||
}
|
||
|
||
void openSensor() {
|
||
BLINKER_LOG("Toggle on!");
|
||
isUseSensor = true;
|
||
sensorButton.text("已开启人体传感");
|
||
sensorButton.color("#F0AA41");
|
||
sensorButton.print("on");
|
||
}
|
||
|
||
void switch_callback(const String & state) {
|
||
if (state == BLINKER_CMD_ON) {
|
||
openLamp();
|
||
BUILTIN_SWITCH.print("on");
|
||
} else if (state == BLINKER_CMD_OFF) {
|
||
closeLamp();
|
||
BUILTIN_SWITCH.print("off");
|
||
}
|
||
}
|
||
|
||
// 小音箱控制亮度
|
||
void miotBright(const String & bright) {
|
||
BLINKER_LOG("need set brightness: ", bright);
|
||
uint8_t colorW = 0;
|
||
if (bright == BLINKER_CMD_MAX) {
|
||
colorW = 100;
|
||
} else if (bright == BLINKER_CMD_MIN) {
|
||
colorW = 0;
|
||
} else {
|
||
colorW = bright.toInt();
|
||
}
|
||
//进行亮度值转换
|
||
uint8_t set_brightness = 255 * colorW / 100;
|
||
ws2812fx.setBrightness(set_brightness);
|
||
brightnessSlider.print(colorW);
|
||
BlinkerMIOT.brightness(colorW);
|
||
BlinkerMIOT.print();
|
||
}
|
||
|
||
|
||
// 灯的颜色设置
|
||
void miotColor(int32_t color) {
|
||
BLINKER_LOG("need set color: ", color);
|
||
ws2812fx.setColor(color);
|
||
BlinkerMIOT.color(color);
|
||
BlinkerMIOT.print();
|
||
}
|
||
|
||
// 灯的状态查询
|
||
void miotQuery(int32_t queryCode) {
|
||
BLINKER_LOG("MIOT Query codes: ", queryCode);
|
||
|
||
switch (queryCode) {
|
||
case BLINKER_CMD_QUERY_ALL_NUMBER :
|
||
BLINKER_LOG("MIOT Query All ---- : ", ws2812fx.getBrightness());
|
||
BlinkerMIOT.powerState(ws2812fx.isRunning() ? "on" : "off");
|
||
BlinkerMIOT.color(ws2812fx.getColor());
|
||
BlinkerMIOT.mode(ws2812fx.getMode());
|
||
BlinkerMIOT.brightness(100 * ws2812fx.getBrightness() / 255);
|
||
BlinkerMIOT.print();
|
||
break;
|
||
case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
|
||
BLINKER_LOG("MIOT Query Power State");
|
||
BlinkerMIOT.powerState(ws2812fx.isRunning() ? "on" : "off");
|
||
BlinkerMIOT.print();
|
||
break;
|
||
case BLINKER_CMD_QUERY_COLOR_NUMBER :
|
||
BLINKER_LOG("MIOT Query Color");
|
||
BlinkerMIOT.color(ws2812fx.getColor());
|
||
BlinkerMIOT.print();
|
||
break;
|
||
case BLINKER_CMD_QUERY_MODE_NUMBER :
|
||
BLINKER_LOG("MIOT Query Mode");
|
||
BlinkerMIOT.mode(ws2812fx.getMode());
|
||
BlinkerMIOT.print();
|
||
break;
|
||
case BLINKER_CMD_QUERY_BRIGHTNESS_NUMBER :
|
||
BLINKER_LOG("MIOT Query Brightness");
|
||
BlinkerMIOT.brightness(100 * ws2812fx.getBrightness() / 255);
|
||
BlinkerMIOT.print();
|
||
break;
|
||
default :
|
||
BlinkerMIOT.powerState(ws2812fx.isRunning() ? "on" : "off");
|
||
BlinkerMIOT.color(ws2812fx.getColor());
|
||
BlinkerMIOT.mode(ws2812fx.getMode());
|
||
BlinkerMIOT.brightness(100 * ws2812fx.getBrightness() / 255);
|
||
BlinkerMIOT.print();
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 灯的模式控制
|
||
void miotMode(uint8_t mode) {
|
||
BLINKER_LOG("need set mode: ", mode);
|
||
|
||
// 日光 模式
|
||
if (mode == BLINKER_CMD_MIOT_DAY) {
|
||
ws2812fx.setColor(255, 255, 255);
|
||
ws2812fx.setBrightness(255);
|
||
ws2812fx.setMode(DEFAULT_MODE);
|
||
brightnessSlider.print(BrightTransformation(255));
|
||
}
|
||
// 月光 模式
|
||
else if (mode == BLINKER_CMD_MIOT_NIGHT) {
|
||
ws2812fx.setColor(255, 89, 0);
|
||
ws2812fx.setBrightness(255);
|
||
ws2812fx.setMode(FX_MODE_STATIC);
|
||
brightnessSlider.print(BrightTransformation(10));
|
||
}
|
||
// 彩光 模式
|
||
else if (mode == BLINKER_CMD_MIOT_COLOR) {
|
||
ws2812fx.setBrightness(255);
|
||
ws2812fx.setSpeed(200);
|
||
ws2812fx.setMode(FX_MODE_RAINBOW_CYCLE);
|
||
brightnessSlider.print(BrightTransformation(255));
|
||
}
|
||
// 温馨 模式
|
||
else if (mode == BLINKER_CMD_MIOT_WARMTH) {
|
||
ws2812fx.setMode(FX_MODE_TWINKLEFOX);
|
||
}
|
||
// 电视模式
|
||
else if (mode == BLINKER_CMD_MIOT_TV) {
|
||
ws2812fx.setBrightness(20);
|
||
ws2812fx.setSpeed(1000);
|
||
ws2812fx.setMode(FX_MODE_CHASE_RAINBOW);
|
||
brightnessSlider.print(BrightTransformation(20));
|
||
}
|
||
// 阅读 模式
|
||
else if (mode == BLINKER_CMD_MIOT_READING) {
|
||
ws2812fx.setBrightness(255);
|
||
ws2812fx.setSpeed(200);
|
||
ws2812fx.setMode(FX_MODE_MULTI_STROBE);
|
||
brightnessSlider.print(BrightTransformation(255));
|
||
}
|
||
// 电脑模式
|
||
else if (mode == BLINKER_CMD_MIOT_COMPUTER) {
|
||
ws2812fx.setBrightness(255);
|
||
ws2812fx.setMode(FX_MODE_COLOR_SWEEP_RANDOM);
|
||
brightnessSlider.print(BrightTransformation(255));
|
||
}
|
||
|
||
BlinkerMIOT.mode(mode);
|
||
BlinkerMIOT.print();
|
||
}
|
||
|
||
// 电源控制
|
||
void miotPowerState(const String & state) {
|
||
if (state == BLINKER_CMD_ON) {
|
||
openLamp();
|
||
BlinkerMIOT.powerState("on");
|
||
BlinkerMIOT.print();
|
||
}
|
||
else if (state == BLINKER_CMD_OFF) {
|
||
closeLamp();
|
||
BlinkerMIOT.powerState("off");
|
||
BlinkerMIOT.print();
|
||
}
|
||
}
|
||
|
||
// 心跳包Heartbeat
|
||
void heartbeat() {
|
||
if (ws2812fx.isRunning()) {
|
||
BUILTIN_SWITCH.print("on");
|
||
openButton.color("#F0AA41");
|
||
openButton.text("已开启");
|
||
openButton.print("on");
|
||
|
||
if (isUseSensor) {
|
||
openSensor();
|
||
}
|
||
} else {
|
||
BUILTIN_SWITCH.print("off");
|
||
};
|
||
}
|
||
|
||
// 随机切换主题
|
||
void changeRandomTheme() {
|
||
BLINKER_LOG("---------------------- changeRandomTheme");
|
||
if (isUseRandomTheme) {
|
||
if (now - last_change > TIMER_MS) {
|
||
ws2812fx.setMode((ws2812fx.getMode() + 1) % ws2812fx.getModeCount());
|
||
BlinkerMIOT.brightness(100 * ws2812fx.getBrightness() / 255);
|
||
last_change = now;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Ws2812fxInit() {
|
||
|
||
BLINKER_LOG("---------------------- Ws2812fxInit 1");
|
||
|
||
ws2812fx.init();
|
||
ws2812fx.setBrightness(DEFAULT_BRIGHTNESS);
|
||
ws2812fx.setSpeed(DEFAULT_SPEED);
|
||
ws2812fx.setColor(DEFAULT_COLOR);
|
||
ws2812fx.setMode(DEFAULT_MODE);
|
||
ws2812fx.start();
|
||
|
||
openButton.color("#F0AA41");
|
||
openButton.text("已开启");
|
||
openButton.print("on");
|
||
|
||
BLINKER_LOG("---------------------- Ws2812fxInit 2");
|
||
}
|
||
|
||
// 初始化 Blinker,并绑定各种事件监听
|
||
void BlinkerInit() {
|
||
|
||
BLINKER_LOG("---------------------- BlinkerInit 1");
|
||
// 初始化blinker链接wifi
|
||
Blinker.begin(auth, ssid, pswd);
|
||
BLINKER_LOG("---------------------- BlinkerInit 2");
|
||
// 开启 DEBUG
|
||
BLINKER_DEBUG.stream(Serial);
|
||
//注册调节颜色的回调函数
|
||
RGB1.attach(rgb1_callback);
|
||
// 打开按钮的回调
|
||
openButton.attach(openLamp_Callback);
|
||
// 亮度调节
|
||
brightnessSlider.attach(brightnessSlider_Callback);
|
||
// 工作模式
|
||
workButton.attach(workButton_Callback);
|
||
// 默认模式
|
||
defaultButton.attach(defaultButton_Callback);
|
||
// 休眠模式
|
||
sleepButton.attach(sleepButton_Callback);
|
||
// 红外人体传感器
|
||
sensorButton.attach(sensorButton_Callback);
|
||
// 随机模式
|
||
randomButton.attach(randomButton_Callback);
|
||
|
||
// 在列表首页显示开关按钮
|
||
BUILTIN_SWITCH.attach(switch_callback);
|
||
// 自定义心跳的监听处理
|
||
Blinker.attachHeartbeat(heartbeat);
|
||
|
||
// 语音电源控制
|
||
BlinkerMIOT.attachPowerState(miotPowerState);
|
||
// 语音亮度调节
|
||
BlinkerMIOT.attachBrightness(miotBright);
|
||
// 语音颜色设置
|
||
BlinkerMIOT.attachColor(miotColor);
|
||
// 语音状态查询设置
|
||
BlinkerMIOT.attachQuery(miotQuery);
|
||
// 语音设置模式
|
||
BlinkerMIOT.attachMode(miotMode);
|
||
}
|
||
|
||
void setup() {
|
||
// 初始化串口
|
||
Serial.begin(115200);
|
||
// 设置主板上灯为输出模式
|
||
// 设置WS2812为输出模式
|
||
pinMode(LED_PIN, OUTPUT);
|
||
// 设置传感器为输入模式
|
||
pinMode(irSensor_PIN, INPUT);
|
||
Ws2812fxInit();
|
||
BlinkerInit();
|
||
}
|
||
|
||
void loop() {
|
||
BLINKER_LOG("---------------------- 5");
|
||
now = millis();
|
||
changeUseSensor();
|
||
ws2812fx.service();
|
||
Blinker.run();
|
||
changeRandomTheme();
|
||
BLINKER_LOG("---------------------- 6");
|
||
}
|