ESP8266 通过 MQTT 协议实现 LED 的远程控制

6 篇文章 0 订阅
4 篇文章 0 订阅

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 ,

  1. 下载 Docker 软件;

  2. C 盘根目录新建文件夹 homeassistant

  3. 下载部署文件 GitHub 并解压得到 docker-compose.yml 保存至上述 homeassistant 文件夹;

  4. Windows 打开 命令提示符Windows PowerShell,输入如下代码实现自动下载镜像

cd C:\homeassistant
docker-compose.yml
docker-compose up
  1. 安装过程需大约 30 分钟,即可在 Docker 容器中创建 Home Assistant 镜像;
  2. 自动从镜像安装 Home Assistant 到容器。代码文件 docker-compose.yml 将映射 Home Assistant 配置文件到 C:/homeassistant 文件夹;
  3. 浏览器输入网址 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 内的 localhost127.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 broker\n", 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 客户端向目标主题发送控制文本 onoff 以控制板载 LED

在这里插入图片描述

注意发送文本格式选项更改为 Plaintext .

Arduino IDE 的串口助手监控可以观察到反馈信息

在这里插入图片描述

与 MQTTX 客户端操作类似,在 HomeAssistant 的 MQTT 设置 中向目标主题发送消息,即可控制 LED 的亮灭

在这里插入图片描述

参考:ESP8266 + MQTT :如何实现 LED 灯的远程控制 | EMQ (emqx.com)

视频展示

ESP8266 通过 MQTT 协议实现 LED 的远程控制

总结

完成该项目的关键在于环境搭建,即 HomeAssistantEMQX 服务器的安装,由于是在 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 的亮灭控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值