改造家里的开关成为智能开关,保留原有开关控制,零火版,基础入门(一)
亮点
- 成本不超20块,这可能是目前能找到的最便宜方案了吧。
- 体积较小,可以塞入86开关面板内。
- 手机app+智能音箱+物理开关控制,状态能同步。
- 接入点灯科技平台,支持wifi配网,包括blinker 设备密钥。
- 入手门槛大大降低,有电工基础,会接入线就行。
过程1,下载固件和wifi配置网
过程2,接线
过程3,改造过程
过程4,最后效果
点动式物理开关演示
器材
需要的器件如下,
接线
手机app端,Blinker设置
1,下载客户端
https://diandeng.tech/doc/app-download, 下载其app, 按注册blinker账号,获取密钥authkey,iOS 在app store 搜索blinker 安装
2,注册账号
3,创建设备
到这一步,我们拿到设备的密钥,请记录下来,后面要用!!!!
为设备增加一个按钮, 按键设置如下图
固件下载
1,下载网盘工具包
链接:https://pan.baidu.com/s/1LU4XkcYnH83GNsA61ywFqw 提取码:681i 复制这段内容后打开百度网盘手机App,操作更方便哦
2,烧写固件
把esp8266插在烧写器上,然后插入电脑的usb口,如下
运行NdoeMcu-pyFlasher-4.0-xx.exe开始下载固件到esp8266
配置wifi上网
1, 重启esp-01
用手机连接到esp8266的wifi热点,热点名不是根据型号会不一样,多半以esp-xxx开头
在电脑的浏览器打开http://192.168.4.1
选择要配置的wifi,点击
2,输入密码和点灯科技创建的设备ID
3,点确定开始配网
成功后
手机端
接入小爱同学配置
1、在手机上安装米家,小米音箱app.
2、在米家APP上添加点灯科技的扩展。
3,从小爱音箱APP上查看有没有找到设备
1、如果发现在设备,就说明配置成功了,我这里设备名叫“新的设备”,现在可以对小爱说 “打开新的设备”
2、你还可以添加小爱学习
接入小度配置
代码已经支持,作者还没来得及测试,参考小爱同学配置一下
接入天猫精灵配置
代码已经支持,作者还没来得及测试,参考小爱同学配置一下
接入siri配置
1,安装“快捷指令”app,点击打开
点运行按钮测试一下开关,passwd是123456
出现下图结果,说明接口调用成功了。
现在对着siri说,“打开台灯”“关闭台灯”
代码
/*
NodeMcu或esp-01/01s控制1路继电器,集成blinker平台,
用手机app控制1路继电器开关,添加一路物理开关控制,继电器用常开(NO)模式v1.0
Created 2021
by 阳阳学编程
www.sooncore.com
抖音号:yyxbc2010
微信号:yyxbc2010固件有网页配网功能,固件烧写工具:
链接:https://pan.baidu.com/s/1WsE_2gERyjaUZFbwgJnsOw 提取码:56r8 说明:1,继电器高电平触发时,YYXBC_HIGH = 1,YYXBC_LOW = 0
继电器低电平触发时,YYXBC_HIGH = 0,YYXBC_LOW = 1
const int YYXBC_HIGH = 0 ;
const int YYXBC_LOW = 1 ;2,用esp-01时,物理开关接在vcc 和gpio2上,继电器接在gpio0上
用nodeMcu时,物理开关接在vcc 和D4上,继电器接在D3上,下面的宏
定义只能同时有一个生效//NodeMCU 继电器接D3,物理开关接D4
#define LED_BUILTIN_LIGHT 0
#define LED_BUILTIN_K2 2//Esp-01/01s,继电器接GPIO0,物理开关接GPIO2
//#define LED_BUILTIN_LIGHT D3
//#define LED_BUILTIN_K2 D43,YYXBC_BUTTON_TYPE = 1时表示物理开关为点动模式,0时表示自锁模式
const int YYXBC_BUTTON_TYPE = 1;获得具体连接电路图和更多资源,请参阅阳阳学编程网站 www.sooncore.com。This example code is in the public domain.
*/#define BLINKER_PRINT Serial
#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET // 设置小爱灯类库
#define BLINKER_DUEROS_OUTLET // 设置小度灯类库
#define BLINKER_ALIGENIE_OUTLET // 设置天猫灯类库#define BLINKER_WITHOUT_SSL //使用这个宏,表示不用SSL加密,可以得到更多内存//
如果要使用apconfig配网模式,打开注释掉,加让这行代码生效
//#define BLINKER_APCONFIG
如果要使用smartconfig配网模式,打开注释掉,加让这行代码生效
//#define BLINKER_ESP_SMARTCONFIG#include <Blinker.h>
#include <ESP8266WebServer.h>char auth[] = "a7a437131912";
char ssid[] = "panzujiMi10";
char pswd[] = "moto1984";String version = "1.0.3";//NodeMCU 继电器接D3,物理开关接D4
#define LED_BUILTIN_LIGHT 0
#define LED_BUILTIN_K2 2//Esp-01/01s,继电器接GPIO0,物理开关接GPIO2
//#define LED_BUILTIN_LIGHT D3
//#define LED_BUILTIN_K2 D4/**** 继电器高电平触发时,YYXBC_HIGH = 1,YYXBC_LOW = 0* 继电器低电平触发时,YYXBC_HIGH = 0,YYXBC_LOW = 1*/
const int YYXBC_HIGH = 0 ;
const int YYXBC_LOW = 1 ;/**** 物理开关点动模式1,自锁模式0*/
const int YYXBC_BUTTON_TYPE = 0;//http接口请求密码
String httppswd = "123456";bool oDuerState = YYXBC_LOW;
bool oMioState = YYXBC_LOW;
bool oAligenieState = YYXBC_LOW;// 新建组件对象
BlinkerButton Button1("btn-abc");//webserver for siri
static ESP8266WebServer esp8266_server(80);//心跳回调
void heartbeat()
{BLINKER_LOG("heartbeat,state: ", digitalRead(LED_BUILTIN));//较正app的按钮状态if(YYXBC_HIGH == digitalRead(LED_BUILTIN_LIGHT) ){Button1.print("on");}else{Button1.print("off");}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果是手机app 有对设备进行操作就执行下面void button1_callback(const String & state)
{BLINKER_LOG("button1_callback get button state: ", state);if (state == BLINKER_CMD_ON) {BLINKER_LOG("Toggle on!");Button1.print("on");digitalWrite(LED_BUILTIN_LIGHT, YYXBC_HIGH);oDuerState = YYXBC_HIGH;oMioState =YYXBC_HIGH;oAligenieState = YYXBC_HIGH;}else if (state == BLINKER_CMD_OFF) {BLINKER_LOG("Toggle off!");Button1.print("off");digitalWrite(LED_BUILTIN_LIGHT, YYXBC_LOW);oDuerState = YYXBC_LOW;oMioState = YYXBC_LOW;oAligenieState = YYXBC_LOW;}BlinkerDuerOS.powerState(oDuerState == YYXBC_HIGH ? "on" : "off");BlinkerDuerOS.report();BlinkerMIOT.powerState(oMioState == YYXBC_HIGH ? "on" : "off");BlinkerMIOT.print();BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH ? "on" : "off");BlinkerAliGenie.print();
}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果小度 有对设备进行操作就执行下面
void duerPowerState(const String & state)
{BLINKER_LOG("duerPowerState need set power state: ", state);if (state == BLINKER_CMD_ON) {button1_callback(BLINKER_CMD_ON);}else if (state == BLINKER_CMD_OFF) {button1_callback(BLINKER_CMD_OFF);}
}void duerQuery(int32_t queryCode)
{BLINKER_LOG("DuerOS Query codes: ", queryCode);switch (queryCode){case BLINKER_CMD_QUERY_POWERSTATE_NUMBER : BLINKER_LOG("DuerOS Query power state");BlinkerDuerOS.powerState(oDuerState == YYXBC_HIGH? "on" : "off");BlinkerDuerOS.print();break;case BLINKER_CMD_QUERY_TIME_NUMBER :BLINKER_LOG("DuerOS Query time");BlinkerDuerOS.time(millis());BlinkerDuerOS.print();break;default :BlinkerDuerOS.powerState(oDuerState == YYXBC_HIGH? "on" : "off");BlinkerDuerOS.print();break;}
}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果小爱有对设备进行操作就执行下面
void miotPowerState(const String & state)
{BLINKER_LOG("miotPowerState need set power state: ", state);if (state == BLINKER_CMD_ON) {button1_callback(BLINKER_CMD_ON);}else if (state == BLINKER_CMD_OFF) {button1_callback(BLINKER_CMD_OFF);}
}void miotQuery(int32_t queryCode)
{BLINKER_LOG("MIOT Query codes: ", queryCode);switch (queryCode){case BLINKER_CMD_QUERY_ALL_NUMBER :BLINKER_LOG("MIOT Query All");BlinkerMIOT.powerState(oMioState == YYXBC_HIGH? "on" : "off");BlinkerMIOT.print();break;case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :BLINKER_LOG("MIOT Query Power State");BlinkerMIOT.powerState(oMioState ==YYXBC_HIGH ? "on" : "off");BlinkerMIOT.print();break;default :BlinkerMIOT.powerState(oMioState ==YYXBC_HIGH ? "on" : "off");BlinkerMIOT.print();break;}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果天猫精灵有对设备进行操作就执行下面
void aligeniePowerState(const String & state)
{BLINKER_LOG("aligeniePowerState need set power state: ", state);if (state == BLINKER_CMD_ON) {button1_callback(BLINKER_CMD_ON);}else if (state == BLINKER_CMD_OFF) {button1_callback(BLINKER_CMD_OFF);}
}void aligenieQuery(int32_t queryCode)
{BLINKER_LOG("AliGenie Query codes: ", queryCode);switch (queryCode){case BLINKER_CMD_QUERY_ALL_NUMBER :BLINKER_LOG("AliGenie Query All");BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH? "on" : "off");BlinkerAliGenie.print();break;case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :BLINKER_LOG("AliGenie Query Power State");BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH? "on" : "off");BlinkerAliGenie.print();break;default :BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH ? "on" : "off");BlinkerAliGenie.print();break;}
}void dataRead(const String & data){BLINKER_LOG("Blinker readString: ", data);Blinker.vibrate();uint32_t BlinkerTime = millis();Blinker.print("millis", BlinkerTime);}void setup() {// 初始化串口Serial.begin(115200);#if defined(BLINKER_PRINT)BLINKER_DEBUG.stream(BLINKER_PRINT);#endif// //debug 命令
// BLINKER_DEBUG.stream(BLINKER_PRINT);
// BLINKER_DEBUG.debugAll();// 初始化有LED的IOpinMode(LED_BUILTIN_LIGHT, OUTPUT);digitalWrite(LED_BUILTIN_LIGHT, YYXBC_LOW);pinMode(LED_BUILTIN_K2, OUTPUT);
// digitalWrite(LED_BUILTIN_K2, LOW);#if (defined(BLINKER_APCONFIG)) || (defined(BLINKER_ESP_SMARTCONFIG))//启动配网模式用这行代码Blinker.begin(auth);#else Blinker.begin(auth, ssid, pswd);#endifBlinker.attachData(dataRead);BlinkerDuerOS.attachPowerState(duerPowerState); //小度语音操作注册函数BlinkerDuerOS.attachQuery(duerQuery);BlinkerMIOT.attachPowerState(miotPowerState);//小爱语音操作注册函数BlinkerMIOT.attachQuery(miotQuery);BlinkerAliGenie.attachPowerState(aligeniePowerState);//天猫语音操作注册函数BlinkerAliGenie.attachQuery(aligenieQuery); Button1.attach(button1_callback);//注册回调函数Blinker.attachHeartbeat(heartbeat);//启动webserver ,提供接口给siri用esp8266_server.on("/", handleRoot); esp8266_server.on("/post", handleSetConfig); esp8266_server.onNotFound(handleNotFound); esp8266_server.begin(); Serial.println("HTTP esp8266_server started");
}void loop() {static int lastms = 0;if (millis()-lastms > 10000) {lastms = millis();Serial.printf(PSTR("Running (%s),state(%s),version %s for %d Free mem=%d\n"),WiFi.localIP().toString().c_str(),oAligenieState == YYXBC_HIGH ? "YYXBC_HIGH" : "CLOES",version.c_str(), lastms/1000, ESP.getFreeHeap());}Blinker.run();//运行Blinkeresp8266_server.handleClient();// 处理http服务器访问//检查物理开关状态if(YYXBC_BUTTON_TYPE == 1){btnHandler1();}else{btnHandler2();}}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果iOS的siri有对设备进行操作就执行下面void handleRoot() { //处理网站根目录“/”的访问请求 String data = "<html>";data += "<head><title>设置</title></head>";data += "<body>";data +=" <p>ESP8266 智能开关,技术支持 微信:yyxbc2010</p><hr>";data +=" <p>SSID:"+ WiFi.SSID() + "</p><hr>";data +=" <p>PSW:"+ WiFi.psk() + "</p><hr>";data += "</body>";data += "</html>"; esp8266_server.send(200, "text/html; charset=utf-8", data);
} void handleSetConfig() { //处理来自siri的访问请求 if (esp8266_server.method() != HTTP_POST) {esp8266_server.send(405, "text/plain", "Method Not Allowed");} else {
// String message = "POST form was:\n";String btnName,btnState,btnPswd;for (uint8_t i = 0; i < esp8266_server.args(); i++) {String name = esp8266_server.argName(i);if(name == "btn") {btnName = esp8266_server.arg(i);}else if (name == "state"){btnState = esp8266_server.arg(i);} else if (name == "passwd"){btnPswd = esp8266_server.arg(i);} }if(btnPswd != httppswd){String message = "{\"errcode\":0,\"msg\":\"password error\"}"; esp8266_server.send(200, "text/html; charset=utf-8", message); return;}if(btnName.length() >0 && btnState.length() >0) {//开关btn-abcif(btnName == "btn-1"){if(btnState == "on"){button1_callback( BLINKER_CMD_ON);}else if (btnState == "off"){button1_callback( BLINKER_CMD_OFF);}}}String message = "{\"errcode\":0,\"msg\":\" ok\"}"; esp8266_server.send(200, "text/html; charset=utf-8", message); }
}// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){
// digitalWrite(led, 1);String message = "File Not Found\n\n";message += "URI: ";message += esp8266_server.uri();message += "\nMethod: ";message += (esp8266_server.method() == HTTP_GET) ? "GET" : "POST";message += "\nArguments: ";message += esp8266_server.args();message += "\n";for (uint8_t i = 0; i < esp8266_server.args(); i++) {message += " " + esp8266_server.argName(i) + ": " + esp8266_server.arg(i) + "\n";}esp8266_server.send(404, "text/plain", message);}//点动模式按钮,监听按钮状态,执行相应处理
void btnHandler1()
{static bool oButtonState = false;int state1 = digitalRead(LED_BUILTIN_K2); //按钮状态int state2 = digitalRead(LED_BUILTIN_LIGHT); //灯的状态if(state1 == HIGH ){if(oButtonState ){if(state2 == YYXBC_HIGH ){ button1_callback(BLINKER_CMD_OFF);Serial.println("按钮对灯已执行关闭");}else{button1_callback(BLINKER_CMD_ON);Serial.println("按钮对灯已执行打开");}oButtonState = false;}}else{oButtonState = true;}
}//自锁模式按钮,监听按钮状态,执行相应处理
void btnHandler2()
{static bool is_btn = false;//按钮的标志位,用来逻辑处理对比,判断按钮有没有改变状态bool is = digitalRead(LED_BUILTIN_K2); //按钮状态if ( is != is_btn){bool is_led = digitalRead(LED_BUILTIN_LIGHT);digitalWrite(LED_BUILTIN_LIGHT, !is_led);if (is_led == YYXBC_HIGH){button1_callback(BLINKER_CMD_OFF);Serial.println("按钮对灯已执行关闭");}else{button1_callback(BLINKER_CMD_ON);Serial.println("按钮对灯已执行打开");}is_btn = digitalRead(LED_BUILTIN_K2); //更新按钮状态}
}
资源下载
本文章相关资源链接:https://pan.baidu.com/s/1LU4XkcYnH83GNsA61ywFqw 提取码:681i 复制这段内容后打开百度网盘手机App,操作更方便哦