单片机学习小组
直播中

陈燕

7年用户 1102经验值
私信 关注

怎样通过无线开关直接控制ESP-01上的继电器呢

ESP8266是什么?
ESP8266中的ESP-01模块有何功能?
怎样通过无线开关直接控制ESP-01上的继电器呢?



回帖(1)

陈杰

2022-2-22 13:58:26
1.简介


ESP8266是一款串口WiFi模块,内部集成MCU能实现单片机之间串口通信, 这款模块简单易学,体积小,便于嵌入式开发。

本文介绍的是ESP8266系列中的ESP-01,这款芯片使用了3.3V的直流电源,体积小,功耗低,支持透传,价格低,下图是ESP8266的ESP-01系列,相应的还有ESP-02,03等等,它们使用的核心芯片都是相同的。


  ESP-01模块

ESP8266官方提供的rom主要有两个,一个是支持at命令修改参数的at系列rom,使用此rom时,可以使用at命令来设置芯片的大部分参数,同时也可将芯片设置为透传模式,这样ESP8266就相当于在互联网和UART之间架起了一座桥梁。

另一个就是物联网的rom了,此rom可以通过命令来控制ESP的部分GPIO,而且ESP8266也可以采集一些温湿度传感器的数据,然后发送到互联网上。

2.方案





  


ESP-01做为MQTT的客户端,连接到MQTT Server, Home Assistant通过mqtt组件和MQTT Server通信,实现控制ESP-01的功能

3.硬件和开发环境


需要的硬件为:ESP-01模块,继电器模块,运行Home Assistant的树莓派一块


  ESP-01和继电器模块

软件:Arduino通过支持ESP8266的组件进行开发

4.代码


4.1定义基本变量


  #define SWITCH_ON     0  



定义了3个MQTT Topic:

TOPIC_CONFIG: 发送配置信息用

TOPIC_COMMAND: 接收控制命令

TOPIC_STATE: 报告状态用

4.2初始化


  void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(PIN_SWITCH, OUTPUT);
}



  void setup_wifi() {
  delay(100);
  WiFi.begin(ssid, password);           // 连接到WiFi网络
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
  }
  Serial.println("WiFi connected");
  // Print the IP address
  Serial.println(WiFi.localIP());
  Serial.println(WiFi.macAddress());
}


4.3 接收MQTT消息的回调函数


  void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);   
  Serial.print("] ");

  set_str = "";
  for (int i = 0; i < length; i++) {
    set_str += (char)payload;
  }  

  String topic_str = topic;
  Serial.println(set_str);

  if (topic_str.equals(TOPIC_COMMAND)) {
    set_switch(set_str);
  }
}


4.4 Wifi和MQTT重新连接


  void reconnect( ) {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi is not connected, retry setup");
    setup_wifi();
  }
   
  while (!client.connected()) {
    Serial.println("MQTT connecting...");
    if (client.connect(client_id, mqtt_user, mqtt_password)) {              
      Serial.println("MQTT connect success.");  
      mqtt_config();
      client.subscribe(TOPIC_COMMAND);      
    } else {
      delay(5000);  
    }
  }
}


4.5 主循环


  void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
   
  long now = millis();
  if (now - last_msg > 5000) {
    last_msg = now;
    pub_mqtt_state();
  }
  
  delay(100);  
}


4.6 设置开关状态


  char* get_state(){
  if (switch_value == SWITCH_ON) {
    return "ON";
  } else {
    return "OFF";
  }
}

boolean set_switch(String set_str) {
  client.publish(TOPIC_STATE, set_str.c_str());
  Serial.print("Recv command:");
  Serial.println(set_str.c_str());

  if (set_str.equals("ON")) {
    switch_value = SWITCH_ON;
  } else if (set_str.equals("OFF")){
    switch_value = SWITCH_OFF;
  } else {
    return false;
  }

  digitalWrite(PIN_SWITCH, switch_value);
  pub_mqtt_state();
  return true;
}



4.7 发布MQTT状态和配置消息


  void pub_mqtt_state() {
  if(switch_value == SWITCH_ON){
    client.publish(TOPIC_STATE, "ON");   
  } else {
    client.publish(TOPIC_STATE, "OFF");   
  }  
}

void mqtt_config() {
  String head = "{";
  String name_str = ""name": "" + String(device_name) + "", ";
  String cmd_topic = ""command_topic": "" + String(TOPIC_COMMAND) + "", ";
  String state_topic = ""state_topic": "" + String(TOPIC_STATE) + """;
  String end_str = "}";
  String config = "{" + name_str + ", " + state_topic + ", " + cmd_topic + "}";
  Serial.println(config.c_str());
  
  int msgLen = head.length() + name_str.length() + cmd_topic.length() + state_topic.length() + end_str.length();
  //发送长文本需要另外处理
  client.beginPublish(TOPIC_CONFIG, msgLen, false);
  client.print(head);
  client.print(name_str);
  client.print(cmd_topic);
  client.print(state_topic);
  client.print(end_str);
  client.endPublish();
}




注意:发布长消息时,要做专门处理,通过client.beginPublish,client.endPublish();

5. Home Assistant配置

5.1 安装MQTT Server

在运行Home Assistant的树莓派上安装MQTT Server, 选择的版本是mosquitto

5.2 树莓派配置

在Home Assistant的Web上,”配置”->"集成", 添加MQTT;

  在configuration.yaml中配置:


  switch: !include switchs.yaml


在switchs.yaml中定义mqtt开关:


  - platform: mqtt
  name: "ESP-01 switch1"
  state_topic: "ESP-01/switch/state"
  command_topic: "ESP-01/switch/set"
  payload_on: "ON"
  payload_off: "OFF"
  state_on: "ON"
  state_off: "OFF"
  optimistic: false
  qos: 0
  retain: true



这样,在Home Assistant的界面中就可以控制继电器开启和关闭了:




  


6. 总结

可以把小米网关也接入到Home Assistant,这样,通过小米的无线开关就可以直接控制ESP-01上的继电器了。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分