改造家里的開關成為智能開關,保留原有開關控制,零火版
亮點
- 成本不超20塊,這可能是目前能找到的最便宜方案了吧,
- 體積較小,可以塞入86開關面板內,
- 手機app+智能音箱+物理開關控制,狀態能同步,
- 接入點燈科技平臺,支持wifi配網,包括blinker 設備密鑰,
- 入手門檻大大降低,有電工基礎,會接入線就行,
程序1,下載韌體和配網
程序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 D4
3,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的IO
pinMode(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);
#endif
Blinker.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();//運行Blinker
esp8266_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-abc
if(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,操作更方便哦
關注陽陽學編程抖音號

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/262991.html
標籤:其他
下一篇:域格模塊移動網路信號指標介紹
