完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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上的继电器了。 |
|
|
|
只有小组成员才能发言,加入小组>>
3318 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9063 浏览 16 评论
4088 浏览 18 评论
1185浏览 3评论
611浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
601浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2337浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1897浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 12:58 , Processed in 0.983193 second(s), Total 47, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号