本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

带有ESP8266,ioBroker和MQTT的智能替代开关
发布时间:2021-02-11
分享到:
带有ESP8266,ioBroker和MQTT的智能替代开关
发布时间:2021-02-11
分享到:

我们可以使用ESP8266电路使房屋中的照明开关更智能,因此,如果没有WiFi,它将继续作为普通开关工作。
硬件组件:

  • NodeMCU Lolin V3模组ESP8266 ESP-12F Wifi×    1个    
  • 带光耦合器的继电器模块×    1个    
  • pc817光耦合器×    1个    
  • AC-DC电源3.3V×    1个    
  • AC-DC电源5V×    1个    
  • 电阻组×    1个    

软件应用程序和在线服务:

  • Arduino IDE    

手动工具和制造机:

  • 烙铁(通用)
  • 多功能工具,螺丝刀

我们可以使用ESP8266电路使房屋中的照明开关更智能,因此,如果出现问题(例如,没有WiFi或服务器关闭),它将继续作为普通开关工作。
注意!
以下电路的某些部分在电源电压下工作。电源电压不是玩具,需要注意规避风险。
下图中红色标记的区域低于电源电压!
让我们看一下电路:
我在市电电压为230V的欧盟使用此电路!如果要使用它,而您所在区域的电源电压不是230V,则可以通过更换图中所示的电源来使用。


电路

如果主电源电压不是230伏,则必须用正确的电压替换图中的2个黑色电源模块。

除了普通的备用开关外,还必须像安装其他备用开关一样安装继电器模块。该继电器模块具有一个光耦合器,因此ESP8266微控制器是完全光学隔离的。

在图中,上方的黑色立方体是一个230 V至3.3 V的开关电源(如果电源电压不是230伏,则必须更换!)。它的230 V输入连接到灯泡,其输出通过光耦合器(pc817)路由到ESP8266 D2引脚。这用于监视灯泡是否点亮。输入D2必须通过上拉电阻切换至3.3V。

下部的黑色立方体为230 V至5 V(如果市电电压不是230,则还必须更换!)开关模式电源,用于为电路的低压部分供电。


备用开关如何工作

ESP8266微控制器必须经过编程才能使电路正常工作。打开Arduino应用并复制此原理图。重写WLAN连接所需的SSID和密码对以及MQTT服务器的IP地址。完成后,将代码上传到ESP8266。
/**************************************/
//  https://myhomethings.eu           //
//  Alternative switch - ESP8266      //
//  Board: NodeMCU 1.0 ESP-12E        //
/**************************************/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "SSID";
const char* password = "Password";
const char* mqtt_server = "192.168.x.xxx";

WiFiClient espClient;
PubSubClient client(espClient);

int relayPin = D5;
int lightControllPin = D2;
long previousMillis = 0;
int relayState = 1;
int switchState = 0;
int switchFlag = 0;


void setup_wifi()
{
  delay(100);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
  randomSeed(micros());
}

void reconnect()
{
  while (!client.connected())
  {
    String clientId = "ESP8266-AlternativeSwitch";
    
    if (client.connect(clientId.c_str()))
    {
      client.subscribe("Light_topic");
    }
    else
    {
      delay(6000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length)
{
  payload[length] = '\0';
  String strTopic = String(topic);
  String strPayload = String((char * ) payload);
 
  if(strTopic == "Light_topic" && switchFlag == 0)
  {
    if(strPayload == "false")
    {
      if(digitalRead(lightControllPin) == LOW)
      {
        if(relayState == 1)
        {
          digitalWrite(relayPin, LOW);
          relayState = 0;
        }
        else
        {
          digitalWrite(relayPin, HIGH);
          relayState = 1;
        }
      }
    }
    
    if(strPayload == "true")
    {
      if(digitalRead(lightControllPin) == HIGH)
      {
        if(relayState == 1)
        {
          digitalWrite(relayPin, LOW);
          relayState = 0;
        }
        else
        {
          digitalWrite(relayPin, HIGH);
          relayState = 1;
        }
      }
    }
  }
}

void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
 
  pinMode(relayPin, OUTPUT);
  pinMode(lightControllPin, INPUT);
  digitalWrite(relayPin, HIGH);
}

void loop()
{
  unsigned long Millis = millis();
  if (Millis - previousMillis >= 1000)
  {
    previousMillis = Millis;
    switchFlag = 0;
  }
 
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
 
  if(digitalRead(lightControllPin) == LOW)
  {
    if(switchState == 0)
    {
      client.publish("Light_topic", "true");
      switchState = 1;
      switchFlag = 1;
    }
  }
 
  if(digitalRead(lightControllPin) == HIGH)
  {
    if(switchState == 1)
    {
      client.publish("Light_topic", "false");
      switchState = 0;
      switchFlag = 1;
    }
  }
}
说明
在第41行,我们输入设备的唯一ID。值得对此进行更改,否则我们可以通过将其更改为以下代码片段来创建更为简洁的生成的ID。
String clientId = "ESP8266ClientID-";
clientId += String(random(0xffff), HEX);
在第45行中,我们在MQTT服务器上订阅了“ Light_topic”。这是一个包含指示灯状态的数据点。“回调”功能监视状态变化。
client.subscribe("Light_topic");
如果第60行的变量“ strTopic”的值为“ Light_topic”,而“ switchFlag”的值为“ 0”,则MQTT服务器上有更改。当使用常规开关打开灯时,“ switchFlag”的值为“ 1”。在这种情况下这是必需的,因为如果我们手动打开灯,则MQTT服务器上的灯的值会更改,并且由于订阅,该条件会再次满足,并且继电器会再次打开
if(strTopic == "Lampa_topic" && switchFlag == 0)
第62行:“ strPayload”的值为“ false”。这意味着必须根据从服务器收到的命令关闭指示灯。
if(strPayload == "false")
第64行:检查灯泡是否点亮。如果它没有点亮,则程序不执行任何操作。尽管有此命令,打开灯泡也不是一件好事。
if(digitalRead(lightControllPin) == LOW) // it is on
值“ LOW”表示灯已打开,因为默认情况下D2引脚被拉至3.3 V,即“ HIGH”。灯泡打开时,pc817光耦合器将其下拉至GND。
如果到目前为止满足所有条件,则必须检查继电器的状态并进行相应的切换。
if(relayState == 1)
{
  digitalWrite(relayPin, LOW);
  relayState = 0;
}
 else
{
  digitalWrite(relayPin, HIGH);
  relayState = 1;
}
第124行:程序检查灯泡是否点亮。如果是这样,并且在以下情况下,开关的状态为“ 0”。因此将其关闭,进行了手动切换。必须使用“ client.publish()”功能将其传输到MQTT服务器,并将“ Light_topic”数据点设置为“ true”。
if(digitalRead(lightControllPin) == LOW)
{
  if(switchState == 0)
  {
    client.publish("Lampa_topic", "true");
    switchState = 1;
    switchFlag = 1;
  }
}
那就是代码的解释,我希望我可以理解。
调试后,新设备将在MQTT下的iobroker中显示为新数据点。
安装了IoT适配器后,您可以连接到Google Home或Amazon Alexa,还可以通过语音命令控制灯泡。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论