ESP8266 通过 MQTT 协议实现 LED 的远程控制
本文简要介绍了搭建 EMQX 服务器实现基于 MQTT 协议远程控制 NodeMCU ESP8266 板载 LED 的解决方案。
简介
1. MQTT
[MQTT] (Message Queuing Telemetry Transport)是一种基于 publish/subscribe
(发布/订阅) 模式的 轻量级 通讯协议,构建于 TCP/IP 协议上,由 IBM 在1999年发布。
MQTT 可以实现用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务 。
2. EMQX
[EMQX] 是一款大规模分布式物联网 MQTT 服务器,单集群支持 1 亿物联网设备连接,消息分发时延低于 1 毫秒。为高可靠、高性能的物联网实时数据移动、处理和集成提供动力。
3. Home Assistant
[Home Assistant] (HA) 家庭助理,是一款基于 Python 的智能家居开源系统,可以方便地连接各种外部设备,支持众多品牌的智能家居设备。
方案
安装 Home Assistant
**使用 **[Docker]容器安装 [Home Assistant] ,
- **下载 **[Docker] 软件;
- **C 盘根目录新建文件夹 **
homeassistant
; - **下载部署文件 **[GitHub] 并解压得到
docker-compose.yml
保存至上述homeassistant
文件夹; - **Windows 打开 **
命令提示符
或Windows PowerShell
,输入如下代码实现自动下载镜像
cd C:homeassistant
docker-compose.yml
docker-compose up
- 安装过程需大约 30 分钟,即可在 Docker 容器中创建 Home Assistant 镜像;
- **自动从镜像安装 Home Assistant 到容器。代码文件 **
docker-compose.yml
将映射 Home Assistant 配置文件到C:/homeassistant
文件夹; - **浏览器输入网址 **
http://localhost:8123/
进入Home Assistant 主界面,创建智能家居账号。
详见: [How to run Home Assistant Container on Windows using Docker - Kiril Peyanski's Blog] .
安装 EMQX
**使用 EMQX 最简单的方式是在 **[EMQX Cloud]上创建完全托管的 MQTT 服务。
这里我们使用 Docker 运行 EMQX
Windows 命令行或 PowerShell 输入并执行如下代码
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:latest
等待进度条下载和部署完成(大约5分钟),即可获得 EMQX 服务器。
**Docker 内的 **
localhost
或127.0.0.1
指向的是容器内部地址,如需访问宿主机地址请使用宿主机的真实 IP .
详见: [Gitee] .
配置 EMQX
**(1)浏览器打开网址 **http://localhost:18083/
,初始登录账户名 admin
密码 public
;
**(2)依次打开 **访问控制
- 客户端认证
- 创建
- Password-Based
- 内置数据库
- (默认配置)- 创建
;
(3)用户管理
- 新建用户
- 自定义用户名和密码(建议 admin).
连接 EMQX 与 HA
**(1)命令行或 PowerShell 输入 **ipconfig
获取本地计算机 IPv4 地址,如 42.34.25.153
(2)配置 Home Assistant ,依次点击设置 - 设备与服务 - 添加集成 - 搜索 MQTT - 填写代理信息。
代理栏输入计算机 IP 地址,端口 1883,用户名和密码为 EMQX 中创建的用户信息。
**(3)点击 **提交
后显示 成功创建 MQTT
,此时 集成
选项下出现 MQTT
条目,EMQX 网页 集群
的 总连接数
和 在线连接数
由 0
变为 1
,表明 MQTT 设备已连接。
参考: [MQTT 接入 Home Assistant] .
连接 ESP8266 与 EMQX
将如下代码下载至 ESP8266 开发板,
需要注意 MQTT 服务器地址,若是 EMQX Cloud,则根据创建远程节点填写地址;若是本地计算机或Docker容器,则填写本地物理 IP 地址。
主题为 MQTTX 客户端定义的订阅名称,客户名和密码则对应 EMQX 服务器客户端用户定义。
#include < ESP8266WiFi.h >
#include < PubSubClient.h >
#define LED 2 // on-board LED D4
// WiFi
const char *ssid = "xxx"; // Enter your WiFi name
const char *password = "xxxxxx"; // Enter WiFi password
// MQTT Broker
const char *mqtt_broker = "xx.xx.xx.xx"; // EMQX Server IP
const char *topic = "emqx/esp8266"; // MQTTX topic
const char *mqtt_username = "UART"; // EMQX Server User Name
const char *mqtt_password = "123456"; //EMQX Server User Password
const int mqtt_port = 1883;
bool ledState = false;
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
// Set software serial baud to 115200;
Serial.begin(115200);
delay(1000); // Delay for stability
// Connecting to a WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to the WiFi network");
// Setting LED pin as output
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW); // Turn off the LED initially
// Connecting to an MQTT broker
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
while (!client.connected()) {
String client_id = "esp8266-client-";
client_id += String(WiFi.macAddress());
Serial.printf("The client %s connects to the public MQTT brokern", client_id.c_str());
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
Serial.println("Public EMQX MQTT broker connected");
} else {
Serial.print("Failed with state ");
Serial.print(client.state());
delay(2000);
}
}
// Publish and subscribe
client.publish(topic, "hello emqx");
client.subscribe(topic);
}
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message: ");
String message;
for (int i = 0; i < length; i++) {
message += (char) payload[i]; // Convert *byte to string
}
Serial.print(message);
if (message == "on" && !ledState) {
digitalWrite(LED, LOW); // Turn on the LED
ledState = true;
}
if (message == "off" && ledState) {
digitalWrite(LED, HIGH); // Turn off the LED
ledState = false;
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
client.loop();
delay(100); // Delay for a short period in each loop iteration
}
测试
在 MQTTX 客户端向目标主题发送控制文本 on
和 off
以控制板载 LED
**注意发送文本格式选项更改为 **
Plaintext
.
Arduino IDE 的串口助手监控可以观察到反馈信息
**与 MQTTX 客户端操作类似,在 HomeAssistant 的 **MQTT 设置
中向目标主题发送消息,即可控制 LED 的亮灭
参考: [ESP8266 + MQTT :如何实现 LED 灯的远程控制 | EMQ (emqx.com)]
视频展示
总结
**完成该项目的关键在于环境搭建,即 **HomeAssistant 和 EMQX 服务器的安装,由于是在 Windows 操作系统环境下,需要将其安装于 Docker 容器中运行,而 Docker 软件通过检索实现镜像安装需要科学上网,因此环境搭建是关键。
**此外,该项目可进行扩展连接智能家居平台 ** HomeAssistant ,同样安装于 Docker 容器,只需要进行 MQTT 配置即可实现开关可视化和 APP 远程 LED 控制,参考[文章],具体操作如下
**修改 HA 配置文件 **configuration.yaml
添加如下代码,实现 LED 开关的界面可视化
# add light
mqtt:
light:
# Device name
- name: "On-board LED"
# State topic
state_topic: "emqx/esp8266"
# Command topic
command_topic: "emqx/esp8266"
# Command type
payload_on: "on"
payload_off: "off"
# unique_ID
unique_id: "on-board LED"
# optimistic set
optimistic: false
配置文件
configuration.yaml
的路径根据 HA 安装位置确定
保存配置文件后,在 开发者工具
中点击 所有 YAML 配置
实现重载配置文件,效果如下
点击开关按钮即可实现 NodeMCU-ESP8266 板载 LED 的亮灭控制。
审核编辑 黄宇
-
led
+关注
关注
242文章
23252浏览量
660545 -
物联网
+关注
关注
2909文章
44557浏览量
372751 -
远程控制
+关注
关注
4文章
627浏览量
34922 -
Arduino
+关注
关注
188文章
6468浏览量
186948 -
ESP8266
+关注
关注
50文章
962浏览量
44956 -
MQTT协议
+关注
关注
0文章
97浏览量
5361
发布评论请先 登录
相关推荐
评论