基于ESP8266+机械面板实现的智能双控开关-Arduino中文社区 - Powered by Discuz! Archiver

世界不大我姓张 发表于 2020-3-20 19:51

基于ESP8266+机械面板实现的智能双控开关

本帖最后由 世界不大我姓张 于 2020-3-20 20:01 编辑

趁着疫情期间,今天来玩一个基于ESP8266+机械按键实现的智能双控开关。 一、准备工作1.1软件·Arduino IDE·安装blinker Arduino库(blinker-library-master.zip)·安装esp8266/esp32扩展包(8266_package_2.6.3.exe)1.2硬件·安信可ESP8266-12F

(我使用的ESP8266-12F是单芯片,你们可以用Node-MCU或者WIFIduino等都可以;单芯片方便应用于实际)
二、开始
2.1下载安装点灯blinker APP
2.2 获取Key码.



2.3Arduino程序#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET   //小爱同学支持类库
#define BLINKER_ALIGENIE_OUTLET    //天猫精灵支持类库
#include <Blinker.h>

char auth[] = "";//输入你从APP中获取到的auth
char ssid[] = "";//输入你家的WIFI账号
char pswd[] = "";//输入你家的WIFI的密码

bool ledStatus = false;
bool KeySwitchStatus = false;
bool LastKeySwitchStatus =false;

const int OUT_PIN = 12;      //继电器输出引脚                                                                                                            
const int LED_PIN = 2;      //LED灯的引脚
const int KEY = 4;          //机械开关的引脚

BlinkerButton Button1("ON");    //按键“开”组件
BlinkerButton Button2("OFF");   //按键“关”组件
BlinkerText Text1("KeyText");   //文字组件

void LedInit(void)    //LED灯及继电器引脚初始化
{
    pinMode(OUT_PIN, OUTPUT);   
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(OUT_PIN, LOW);   //继电器上电默认关(低电平)
    digitalWrite(LED_PIN, HIGH);
    ledStatus = false;
}

void KeyInit(void)   //机械开关初始化
{
pinMode(KEY, INPUT_PULLUP);
LastKeySwitchStatus = digitalRead(KEY) == 0 ? false : true;
}

void SwitchLed(void)       //LED及继电器引脚开关操作
{

if(ledStatus)
{
    digitalWrite(OUT_PIN, LOW);
    digitalWrite(LED_PIN,HIGH);
    ledStatus = false;
    Blinker.notify("已通过实体按键关闭设备");
    heartbeat();
}
else
{
    digitalWrite(OUT_PIN, HIGH);
    digitalWrite(LED_PIN, LOW);
    ledStatus = true;
    Blinker.notify("已通过实体按键开启设备");
    heartbeat();
}
}

void SwitchLed_ON(void)
{
digitalWrite(OUT_PIN, HIGH);
digitalWrite(LED_PIN, LOW);
ledStatus = true;
heartbeat();
}

void SwitchLed_OFF(void)
{
digitalWrite(OUT_PIN, LOW);
digitalWrite(LED_PIN, HIGH);
ledStatus = false;
heartbeat();
}

void KeySwitch(void)   //机械开关动作判断
{
KeySwitchStatus = digitalRead(KEY) == 0 ? false : true;
if (KeySwitchStatus != LastKeySwitchStatus)
{
    SwitchLed();
    LastKeySwitchStatus = KeySwitchStatus;
}
}

void miotPowerState(const String & state)
{
    if (state == BLINKER_CMD_ON) {
      SwitchLed_ON ();
      BlinkerMIOT.powerState("on");
      BlinkerMIOT.print();
      Blinker.notify("已通过小爱同学开启设备");
    }
    else if (state == BLINKER_CMD_OFF) {
      SwitchLed_OFF ();
      BlinkerMIOT.powerState("off");
      BlinkerMIOT.print();
      Blinker.notify("已通过小爱同学关闭设备");
    }
}



void miotQuery (int32_t queryCode)
{
switch (queryCode)
{
    case BLINKER_CMD_QUERY_ALL_NUMBER :
         BLINKER_LOG("MIOT Query ALL");
         BlinkerMIOT.powerState(ledStatus ? "设备处于开启状态" : "设备处于关闭状态");
         BlinkerMIOT.print();
         break;
    case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
         BLINKER_LOG("MIOT Query Power State");
         BlinkerMIOT.powerState(ledStatus ? "设备处于开启状态" : "设备处于关闭状态");
         BlinkerMIOT.print();
         break;
    default :
         BlinkerMIOT.powerState (ledStatus ? "设备处于开启状态" : "设备处于关闭状态");
         BlinkerMIOT.print();
         break;
}
}

void aligeniePowerState(const String & state)
{
    if (state == BLINKER_CMD_ON) {
      SwitchLed_ON ();
      BlinkerAliGenie.powerState("on");
      BlinkerAliGenie.print();
      Blinker.notify("已通过天猫精灵开启设备");
    }
    else if (state == BLINKER_CMD_OFF) {
      SwitchLed_OFF ();
      BlinkerAliGenie.powerState("off");
      BlinkerAliGenie.print();
      Blinker.notify("已通过天猫精灵关闭设备");
    }
}

void aligenieQuery(int32_t queryCode)
{

    switch (queryCode)
    {
      case BLINKER_CMD_QUERY_ALL_NUMBER :
            BLINKER_LOG("AliGenie Query All");
            BlinkerAliGenie.powerState(ledStatus ? "设备处于开启状态" : "设备处于关闭状态");
            BlinkerAliGenie.print();
            break;
      case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
            BLINKER_LOG("AliGenie Query Power State");
            BlinkerAliGenie.powerState(ledStatus ? "设备处于开启状态" : "设备处于关闭状态");
            BlinkerAliGenie.print();
            break;
      default :
            BlinkerAliGenie.powerState(ledStatus ? "设备处于开启状态" : "设备处于关闭状态");
            BlinkerAliGenie.print();
            break;
    }
}

void dataRead(const String & data)
{
    uint32_t BlinkerTime = millis();
    Blinker.print("millis", BlinkerTime);
}

void heartbeat(void)
{
Text1.print(ledStatus ? "设备当前状态为: 开启" : "设备当前状态为: 关闭");
}

void button1_callback(const String & state)
{
    SwitchLed_ON ();
    Blinker.notify("已通过APP开启设备");
}

void button2_callback(const String & state)
{
    SwitchLed_OFF ();
    Blinker.notify("已通过APP关闭设备");
}

void setup()
{
    Serial.begin(115200);
    LedInit();
    KeyInit();
    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);
    BlinkerMIOT.attachPowerState(miotPowerState);
    BlinkerMIOT.attachQuery(miotQuery);
    BlinkerAliGenie.attachPowerState(aligeniePowerState);
    BlinkerAliGenie.attachQuery(aligenieQuery);
    Button1.attach(button1_callback);
    Button2.attach(button2_callback);
    Blinker.attachHeartbeat(heartbeat);
}

void loop()
{
    Blinker.run();
    KeySwitch();
}·选择工具-开发板-Generic ESP8266 Module

·连接ESP8266-电路图如下



(该电路板是我自己画的,预留了TXD、RXD、GND串口,连接好线路,就可以在ArduinoIDE中点击下载程序了,PCB原理图见下面)·选择对应的COM端口,最后上传程序~三、测试将ESP8266-12F的GPIO0断开,并且RST一下,设备即可上线。 (在APP界面添加相应的组件,该设备大体就成型了)四、实际应用   将设备放入86暗盒中,可以用小爱同学、天猫精灵、Blinker APP来在线控制,还可以用实体按键控制,即使WIFI断网也可以使用按键来控制。双控的好处就是不管设备现在处于何种状态(开启/关闭),都可以使用。比如说,我用机械开关开启了灯,晚上上床了之后,叫小爱关闭灯。此时机械开关反方向再按一次又变成了“开启”。。。。。。说了这么多废话,讲白了就是机械开关与ESP8266互不干扰。关于PCB部分你们可以不用画PCB可以直接用手焊接成最小系统,也非常简单。我附上我的PCB原理图:    备注:程序不是最终版本,可能会出现BUG,实现功能的方法很好,可以自己尝试优化,本程序仅供参考。

果奔的瓜牛 发表于 2020-3-20 20:18

楼主 有没有成品 卖啊

世界不大我姓张 发表于 2020-3-20 21:47

果奔的瓜牛 发表于 2020-3-20 20:18
楼主 有没有成品 卖啊

不卖喔,不过你可以对着教程自己做呢

Creeper666 发表于 2020-3-21 09:27

pcb文件不公开嘛?

世界不大我姓张 发表于 2020-3-21 12:27

Creeper666 发表于 2020-3-21 09:27
pcb文件不公开嘛?

为什么都好奇我的PCB

Creeper666 发表于 2020-3-21 13:30

懒得画板;P

zhaixiaozh 发表于 2020-3-22 15:33

楼主我刚刚开始学习,看完想弄一个,有些地方不太明白,请教一下,我现在有Node-MCU,继电器,和变压器。
我是不是可以给机械开关的L给一个3.3v的电,L1接到Node-MCU的引脚上,如果Node-MCU收到3.3v的电就控制继电器吸合。然后继电器连接led灯线啊.麻烦有时间的话指点一下,万分感谢。

世界不大我姓张 发表于 2020-3-23 11:30

zhaixiaozh 发表于 2020-3-22 15:33
楼主我刚刚开始学习,看完想弄一个,有些地方不太明白,请教一下,我现在有Node-MCU,继电器,和变压器。
...

这样是可以的,只要程序写得没错,电路设计完全行得通

akram831 发表于 2020-3-27 22:49

程序里能不能再加几条控制回路

zhaixiaozh 发表于 2020-3-31 21:31

世界不大我姓张 发表于 2020-3-23 11:30
这样是可以的,只要程序写得没错,电路设计完全行得通

谢谢你啦,我去试试。
页: [1] 2 3 4
查看完整版本: 基于ESP8266+机械面板实现的智能双控开关