基于ESP8266实现86墙壁开关和语音双重控制-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 7226|回复: 12

[分享] 基于ESP8266实现86墙壁开关和语音双重控制

[复制链接]
发表于 2020-8-22 20:30 | 显示全部楼层 |阅读模式
本帖最后由 uint8_t 于 2020-8-22 20:57 编辑

前提:家里的墙壁开关里必须同时有零线和火线。
一:前期准备
1.  安装Arduino IDE 1.8.7或更新版本(目前最新版本为1.8.13)
软件链接 https://www.arduino.cn/thread-5838-1-1.html(来自Arduino论坛)
1.png
2.  Arduino IDE安装esp8266扩展
  目前在线安装有点问题,推荐离线安装。下载链接:https://share.weiyun.com/5CGEKJO(来自Arduino论坛),目前最新版本为2.7.4。
2.png
安装好之后,打开Arduino IDE,打开【工具】,开发板选择就可以选择ESP8266了。
3.png
3.下载blinkerArduino库
下载链接:https://github.com/blinker-iot/blinker-library/archive/dev_3.0.zip
4.png
将下载好的blinker库解压到 我的电脑>文档>Arduino>libraries 文件夹中
5.png
4.下载并安装blinker APP
    下载链接:https://github.com/blinker-iot/app-release/releases/download/2.4.7/blinker-2.4.7-release.apk
(1)在app中添加设备,获取Secret Key
进入App,点击右上角的“+”号,然后选择添加设备,点击选择Arduino -> WiFi接入-> 选择要接入的服务商 -> 复制申请到的Secret Key
TIM截图20200822203751.png
(2)DIY界面
  在设备列表页,点击刚才新建的设备图标,进入设备控制面板。首次进入设备控制面板,会弹出向导页,在向导页点击载入示例,即可载入示例组件。点击右上角的修改,选择开关的按钮,样式选择中间那种,按键类型选择:开关按键,再点击有上角的保存。之后我们就可以通过这个按键来控制并查看灯。
TIM截图20200822204015.png
5.硬件
   我是使用的自己绘制的电路板,学习阶段可以使用Node-MCU,真正接入到墙壁里还是需要自己绘制板子,不然板子太大放不进去。
TIM截图20200822204124.png 6.png
二:程序

  1. #define BLINKER_WIFI
  2. #define BLINKER_MIOT_LIGHT//支持小爱同学
  3. #include <Blinker.h>

  4. char auth[] = "  ";//app中获取到的Secret Key(密钥)
  5. char ssid[] = "  ";//WIFI名称
  6. char pswd[] = " ";//WIFI密码

  7. // 设置各引脚别名
  8. const int GPIO = 10; // 定义继电器输入引脚为GPIO/10
  9. const int KEY = 4; // 定义按键引脚
  10. // 变量定义
  11. int State = 0; // 存储按键状态的变量
  12. int led_state = 0;// 存储灯状态的变量

  13. // 新建组件对象
  14. BlinkerButton Button1("btn-abc");//注意:要和APP组件’数据键名’一致

  15. // 按下BlinkerAPP按键即会执行该函数
  16. void button1_callback(const String & state)
  17. {
  18.   BLINKER_LOG("get button state: ", state);
  19.   digitalWrite(GPIO, !digitalRead(GPIO));
  20.   led_state = !led_state;
  21.   if (led_state == 1)
  22.     Button1.print("on");
  23.   if (led_state == 0)
  24.     Button1.print("off");
  25.   Blinker.vibrate();
  26. }

  27. //小爱电源类操作的回调函数:
  28. //当小爱同学向设备发起控制, 设备端需要有对应控制处理函数
  29. void miotPowerState(const String & state)
  30. {
  31.   BLINKER_LOG("need set power state: ", state);
  32.   if (state == BLINKER_CMD_ON)
  33.   {
  34.     digitalWrite(GPIO, HIGH);
  35.     BlinkerMIOT.powerState("on");
  36.     BlinkerMIOT.print();

  37.     led_state = 1;
  38.     Button1.print("on");
  39.   }
  40.   else if (state == BLINKER_CMD_OFF)
  41.   {
  42.     digitalWrite(GPIO, LOW);
  43.     BlinkerMIOT.powerState("off");
  44.     BlinkerMIOT.print();

  45.     led_state = 0;
  46.     Button1.print("off");
  47.   }
  48. }

  49. void setup()
  50. {
  51.   // 初始化串口,并开启调试信息,调试用可以删除
  52.   Serial.begin(115200);
  53.   BLINKER_DEBUG.stream(Serial);
  54.   // 初始化IO
  55.   pinMode(GPIO, OUTPUT);
  56.   digitalWrite(GPIO, LOW);
  57.   pinMode(KEY, INPUT);
  58.   digitalWrite(KEY, HIGH);

  59.   State = digitalRead(KEY);
  60.   led_state = 0;


  61.   // 初始化blinker
  62.   Blinker.begin(auth, ssid, pswd);
  63.   Button1.attach(button1_callback);
  64.   Button1.print("off");//发送APP上按键当前的状态

  65.   //小爱同学务必在回调函数中反馈该控制状态
  66.   BlinkerMIOT.attachPowerState(miotPowerState);//注册回调函数
  67. }

  68. void loop()
  69. {
  70.   Blinker.run();
  71.   if (digitalRead(KEY) != State)
  72.   {
  73.     delay(100);
  74.     if (digitalRead(KEY) != State)
  75.     {
  76.       State = digitalRead(KEY);
  77.       digitalWrite(GPIO, !digitalRead(GPIO));
  78.       led_state = !led_state;
  79.       if (led_state == 1)
  80.         Button1.print("on");
  81.       if (led_state == 0)
  82.         Button1.print("off");
  83.       delay(1000);
  84.     }
  85.   }
  86. }

复制代码
三:程序分析及实物
     将墙壁开关中间口接到GPIO4上,墙壁开关的另外两个口分别接GND和VCC,然后程序检测到4号脚上的状态发生改变,就对灯的状态进行取反。并且每次改变灯的状态时,将灯的状态反馈给APP。
TIM图片20200822204805.jpg

发表于 2020-8-24 13:21 | 显示全部楼层
本帖最后由 skygz 于 2020-8-24 13:23 编辑

这样不够理想,  要接开关要三条线(这样挑开关 要支持3线的开关),  完全可以  2条线 接IO和接地并且    IO上拉,  就可以了

代码加个变量记录最后的false/true状态  即可。


if 按下=接地低电平    并且 变量最后记录为 假 then
   变量最后记录 =取反 变量最后记录
       开关继电器IO 取反输出
else if 开关抬起松开=上拉电阻至为高电平  并且 变量最后记录为 真 then
     变量最后记录 =取反 变量最后记录
   开关继电器IO 取反输出

取自另一坛友的 精简代码
void KeySwitch(void)     //机械开关动作判断
{
  KeySwitchStatus = digitalRead(GPIO_BTNSWITCH) == 0 ? false : true;
  if (KeySwitchStatus != LastKeySwitchStatus)
  {
    ChangeSwitch();
    LastKeySwitchStatus = KeySwitchStatus;
  }
}

 楼主| 发表于 2020-8-25 14:44 | 显示全部楼层
skygz 发表于 2020-8-24 13:21
这样不够理想,  要接开关要三条线(这样挑开关 要支持3线的开关),  完全可以  2条线 接IO和接地并且     ...

理论上是两根线就可以,程序里给IO口状态,开关接另一个状态。但是我接到墙壁开关里就会有问题,IO口悬空的时候电压一直在调,不接入墙壁开关就不会,不知道是不是因为我家墙壁开关里面弹片的问题,然后就又加了一根线。
发表于 2020-8-25 22:15 | 显示全部楼层
本帖最后由 skygz 于 2020-8-27 19:56 编辑
uint8_t 发表于 2020-8-25 14:44
理论上是两根线就可以,程序里给IO口状态,开关接另一个状态。但是我接到墙壁开关里就会有问题,IO口悬空 ...

我不是说了吗, IO接上拉电阻,   悬空时,    上拉电阻会让IO保持于 高电平。
 楼主| 发表于 2020-8-27 16:12 | 显示全部楼层
skygz 发表于 2020-8-25 22:15
不是说了吧, IO接上拉电阻,   悬空时,    上拉电阻会让IO保持于 高电平。 ...

接上拉电阻啊,这个可以
发表于 2020-9-9 01:02 来自手机 | 显示全部楼层
有没有双控开关的原理,易微联好像有个单火双控他那是怎么实现的。谁分析下,或也做一个
 楼主| 发表于 2020-9-9 23:23 | 显示全部楼层
menlsux 发表于 2020-9-9 01:02
有没有双控开关的原理,易微联好像有个单火双控他那是怎么实现的。谁分析下,或也做一个 ...

可能就和墙壁开关的双开原理一样吧
发表于 2020-9-11 09:07 | 显示全部楼层
兄弟板子出吗?
 楼主| 发表于 2020-9-11 09:29 来自手机 | 显示全部楼层
雨梦随行 发表于 2020-9-11 09:07
兄弟板子出吗?

另一个贴子有B站链接,里面有板子的链接,你可以去看看
发表于 2021-1-12 09:42 | 显示全部楼层
谁家的墙壁开关里面老放个零线做什么?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-28 12:33 , Processed in 0.113452 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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