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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 20755|回复: 35

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

[复制链接]
发表于 2020-3-20 19:51 | 显示全部楼层 |阅读模式
本帖最后由 世界不大我姓张 于 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正面.PNG


(我使用的ESP8266-12F是单芯片,你们可以用Node-MCU或者WIFIduino等都可以;单芯片方便应用于实际)

二、开始
2.1下载安装点灯blinker APP
2.2 获取Key码.



1.jpg 2.jpg 3.jpg 4.jpg
2.3Arduino程序
[mw_shl_code=arduino,true]#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();
}[/mw_shl_code]
·选择工具-开发板-Generic ESP8266 Module
11.png


·连接ESP8266-电路图如下


mmexport1582048263558.jpg 47D794382FC751DBA74770D4EA556690.jpg

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


ESP8266反面.PNG
69D71EB75F7547987762A941CC115798.jpg
Schematic_智能插座_2020-03-20_19-08-12.png
14242.png
发表于 2020-3-20 20:18 | 显示全部楼层
楼主 有没有成品 卖啊
 楼主| 发表于 2020-3-20 21:47 | 显示全部楼层
果奔的瓜牛 发表于 2020-3-20 20:18
楼主 有没有成品 卖啊

不卖喔,不过你可以对着教程自己做呢
发表于 2020-3-21 09:27 | 显示全部楼层
pcb文件不公开嘛?
 楼主| 发表于 2020-3-21 12:27 来自手机 | 显示全部楼层
Creeper666 发表于 2020-3-21 09:27
pcb文件不公开嘛?

为什么都好奇我的PCB
发表于 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,继电器,和变压器。
...

这样是可以的,只要程序写得没错,电路设计完全行得通
发表于 2020-3-27 22:49 来自手机 | 显示全部楼层
程序里能不能再加几条控制回路
发表于 2020-3-31 21:31 | 显示全部楼层
世界不大我姓张 发表于 2020-3-23 11:30
这样是可以的,只要程序写得没错,电路设计完全行得通

谢谢你啦,我去试试。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 01:47 , Processed in 0.106768 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表