1.簡介
ESP8266是一款序列槽WiFi子產品,内部內建MCU能實作單片機之間序列槽通信, 這款子產品簡單易學,體積小,便于嵌入式開發。
本文介紹的是ESP8266系列中的ESP-01,這款晶片使用了3.3V的直流電源,體積小,功耗低,支援透傳,價格低,下圖是ESP8266的ESP-01系列,相應的還有ESP-02,03等等,它們使用的核心晶片都是相同的。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CNhhDNlZWMxATOwQTOxMmNwQGO5MTO2MDO4UWNiZTOk9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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[i];
}
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上的繼電器了。
感興趣的可以繼續通路
愛上制作-K12DIYwww.k12diy.com