智能wifi灯开关



美好的一天,亲爱的读者。

一开始有点歌词。 “智能”电灯开关的想法并不是什么新鲜事物,对于那些开始熟悉Arduino平台和IoT元素的人来说,这可能是第一件事。我也不例外。在对电路元件,电动机和LED进行了实验之后,我想做更多应用,这是日常生活中所需要的,最重要的是,它将易于使用,并且不会因为舒适而成为实验的受害者。

在本文中,我将告诉您如何制作像普通开关一样工作的开关(即通常安装在墙壁上的开关),同时允许通过WiFi(或通过Internet进行控制,如本例所示)进行操作。

因此,我们将列出实施计划所需的清单。我必须马上说,我不想过多地花钱在组件上,而是根据论坛的反馈和物有所值来选择组件。因此,某些组件对于经验丰富的电气业余爱好者来说似乎不合适,但请不要严格判断,因为 我只是机电领域的新手,非常感谢经验丰富的专业人士的意见。
不行名称内容描述价钱
1个HLK-PM01220VAC至5VDC适配器4,02€
2SSR-40DA固态继电器,用于电路电流控制3,35€
3AMS1117-3.35V至3V电压抑制器1,29€
4ESP8266-01带有WiFi的微控制器2,35€
总计:11,01€

我还需要:可以通过互联网控制开关的服务器,Arduino Uno,我可以通过它编程ESP,路由器和诸如导线,端子等耗材,所有这些都可能因口味而异,并且不会影响到最终结果。

价格从我购买的Ebay处获取。

这是表中元素的外观:



现在,您可以绘制一个连接图:



您可能已经注意到,该方案非常简单。一切都可以轻松,快速且无焊接地组装。一种有效的原型,不需要长时间困扰。一切都通过电线和端子连接。唯一的缺点是继电器未安装在交换机的插座中。是的,最初我计划将其全部推入开关后面的墙上,以使其看起来美观。但是令我遗憾的是,插座中没有足够的空间,继电器根本无法插入左右两侧:



因此,我暂时将继电器从插座中取出,直到找到一个合适的带有插座的开关盒以将铁隐藏在里面。但是没有什么比永久的更永久的了,不是吗?因此,现在所有这些看起来像这样:



绝缘胶带可以避免电击……我希望。

现在让我们谈谈软件部分。

并且在继续分析代码和细节之前,我将给出灯控制实施的一般示意图。



我希望有一天我会重写所有内容,并且该连接将基于比HTTP更快的协议,但是首先它会做。灯泡在大约1-1.5秒内从远程更改其状态,并与合适的开关相匹配,可立即从开关更改状态。

编程ESP8266-01


最简单的方法是使用Arduino。您可以从GitHub下载Arduino IDE的必要库。有所有安装和配置说明。

接下来,我们需要将ESP连接到计算机,为此,我们需要USB到串行适配器(例如FTDiCH340FT232RL)或任何具有RX和TX输出的Arduino平台(我有Arduino Uno)。

值得注意的是,ESP8266-01由3.3伏特供电,这意味着在任何情况下都不要将其连接至(通常)由5伏特供电的Arduino,否则,一切都会陷入困境。您可以使用上表所示的降压器。

连接方案很简单:我们连接TXRXGND ESP分别连接到RX,TX和GND适配器/ Arduino。在那之后,实际上,该连接已准备就绪。可以使用Arduino IDE对微控制器进行编程。

使用Arduino Uno时有一些细微差别:
  • Uno的输出为3.3V,但这还不够。当您将ESP连接到它时,一切似乎正常,指示灯亮,但是与COM端口的通信丢失。因此,我为ESP使用了不同的3.3V电源。
  • 此外,由于UNO由5V和3V的ESP供电,因此UNO与ESP的通信没有任何问题。

经过对ESP8266-01的多次实验后,事实证明ESP对连接到GPIO0和GPIO2的电压敏感。在启动时,如果您打算以普通模式启动,则在任何情况下都不应接地。有关微控制器启动的更多详细信息,请参见此处我不知道这一点,我不得不稍微改变一下电路,因为 在ESP-01版本中,仅存在这两个引脚,并且在我的电路中都使用了这两个引脚。

这是ESP本身的程序:

显示代码
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPClient.h>
extern "C" { //         initVariant
  #include "user_interface.h"
}

const char* ssid = "WIFISSID"; //  WiFi
const char* password = "***************"; //  WiFi
const String self_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //     
const String serv_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //     
const String name = "IOT_lamp"; //  ,  
const String serverIP = "192.168.1.111"; //  IP WEB  
bool lamp_on =  false;
bool can_toggle = false;
int button_state;

ESP8266WebServer server(80); //  
HTTPClient http; //  

const int lamp = 2; //    GPIO2
const int button = 0; // ""   GPIO0

//    
void handleRoot() { 
  server.send(200, "text/plain", "Hello! I am " + name);
}

//    
void handleNotFound(){
  String message = "not found";
  server.send(404, "text/plain", message);
}

//   
void turnOnLamp(){
  digitalWrite(lamp, LOW);
  lamp_on = true;
}

//   
void turnOffLamp(){
  digitalWrite(lamp, HIGH);
  lamp_on = false;
}

//     ./.
void sendServer(bool state){
  http.begin("http://"+serverIP+"/iapi/setstate");
  String post = "token="+self_token+"&state="+(state?"on":"off"); //         
  http.addHeader("Content-Type", "application/x-www-form-urlencoded");
  int httpCode = http.POST(post);
  http.end();  
}

//   
void toggleLamp(){
  if(lamp_on == true) {
    turnOffLamp();
    sendServer(false);
  } else {
    turnOnLamp();
    sendServer(true);
  }
}

//     
void handleOn(){
  String token = server.arg("token");
  if(serv_token != token) {
    String message = "access denied";
    server.send(401, "text/plain", message);
    return;
  }
  turnOnLamp();
  String message = "success";
  server.send(200, "text/plain", message);
}

//     
void handleOff(){
  String token = server.arg("token");
  if(serv_token != token) {
    String message = "access denied";
    server.send(401, "text/plain", message);
    return;
  }
  turnOffLamp();
  String message = "success";
  server.send(200, "text/plain", message);
}

//  MAC    IP
void initVariant() {
  uint8_t mac[6] = {0x00, 0xA3, 0xA0, 0x1C, 0x8C, 0x45};
  wifi_set_macaddr(STATION_IF, &mac[0]);
}

void setup(void){
  pinMode(lamp, OUTPUT);
  pinMode(button, INPUT_PULLUP); //   INPUT_PULLUP
  turnOffLamp();
  WiFi.hostname(name);
  WiFi.begin(ssid, password);

  //     WiFi
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  //    
  server.on("/", handleRoot);
  server.on("/on",  HTTP_POST, handleOn);
  server.on("/off", HTTP_POST, handleOff);
  server.onNotFound(handleNotFound);

  //  
  server.begin();
}

void loop(void){
  server.handleClient();

  //   
  button_state = digitalRead(button);
  if (button_state == HIGH && can_toggle) {
    toggleLamp();
    can_toggle = false;
    delay(500);
  } else if(button_state == LOW){
    can_toggle = true;
  }
}


关于代码的一些注释:
  • 将引脚GPIO0声明为pinMode(按钮,INPUT_PULLUP非常重要,因为 在电路中,我们不为此按钮使用电阻。为此,ESP具有自己的“缝制”功能。
  • .

WEB


在这里,您可以发挥自己的想象力,并使用任何可用的方式来创建服务,该服务将处理由交换机发送的请求并发送开/关请求。

我为此目的使用了Yii。我选择此框架的原因有很多,我需要授权(因为该门户在Internet上可用)和角色管理(用于以后的实验),所以我很喜欢。现在,我的管理门户看起来像这样:



要控制网络到达区域中的灯泡,ESP上的服务器本身就足够了。但是您确实希望将来拥有日志,逻辑和其他设备,因此最好使用单独的服务器进行管理。

这一切都是关于门户的,我认为写更多有关它是没有意义的,但是如果您有任何疑问,我会很乐意在评论中回答。

而不是结论


感谢您阅读本文的结尾,也许在其中找到了对自己有用的东西。我将很乐意为您提供建议和批评。通常,在我看来,电路中的瓶颈仍然是5V适配器,如果您分享解决此类问题的经验,我将感到非常高兴。至于ESP8266-01,到目前为止,除了特殊使用GPIO引脚外,它没有引起我任何抱怨。第二周稳定运行。在项目中取得成功。

Source: https://habr.com/ru/post/zh-CN393497/


All Articles