《ESP8266通信指南》15-MQTT连接、订阅MQTT主题并打印消息(基于Lua|适合新手|非常简单)


往期

《ESP8266通信指南》14-连接WIFI(基于Lua)-CSDN博客

《ESP8266通信指南》13-Lua 简单入门(打印数据)-CSDN博客

《ESP8266通信指南》12-Lua 固件烧录-CSDN博客

《ESP8266通信指南》11-Lua开发环境配置-CSDN博客

《ESP8266通信指南》10-MQTT通信(Arduino开发)-CSDN博客

《ESP8266通信指南》9-TCP通信(Arudino开发)-CSDN博客

《ESP8266通信指南》8-连接WIFI(Arduino开发)(非常简单)-CSDN博客

《ESP8266通信指南》7-Arduino 开发8266的环境配置与示例代码烧录-CSDN博客

《ESP8266通信指南》6-创建TCP服务器(AT指令)-CSDN博客

《ESP8266通信指南》5-TCP通信透传模式(AT指令)-CSDN博客

《ESP8266通信指南》4-以Client进行TCP通信(AT指令)-CSDN博客

《ESP8266通信指南》3-常用AT指令详解-8266连WIFI-CSDN博客

《ESP8266通信指南》2-ESP8266 AT测试-CSDN博客

《ESP8266通信指南》1-ESP8266 简介-CSDN博客

1. 小节目标

实现 MQTT 的连接,订阅主题,接收来自 MQTT 的消息,并在串口打印出来。

2. 完整代码

station_cfg = {}
station_cfg.ssid = "xlu_2.4"
station_cfg.pwd  = "111222333+"
station_cfg.auto = false
station_cfg.save = false
x_id=666
mqtt_cfg = {}
mqtt_cfg.host      = "broker.emqx.io"
mqtt_cfg.port      = 1883
mqtt_cfg.clientid  = "alro_xxx".. x_id
mqtt_cfg.keepalive = 120
mqtt_cfg.username  = "AlvaRocha"
mqtt_cfg.password  = "aio_KO<safety edit>sXwbgtWCboCal"
-- 
x_topic="/topic/ctiot/".. x_id
m=nil
wifi.setmode(wifi.STATION)
wifi.sta.config(station_cfg)iot_test = mqtt.Client(mqtt_cfg.clientid, mqtt_cfg.keepalive, mqtt_cfg.username, mqtt_cfg.password)
iot_test:on("offline", function(client)print("client offline")
end)
iot_test:on("message", function(client, topic, data)if data ~= nil thenprint(data)end
end)function get_broker(mqtt_client)mqtt_client:connect(mqtt_cfg.host, mqtt_cfg.port, false,function(client)client:subscribe(x_topic.."/c", 0, function(client)print("subscribe success "..x_topic.."/c")end)m:publish(x_topic.."/m", "success", 0, 0, function(client)print("init success")end)end,function(client, reason)print('connection failed', reason)end)m=mqtt_client
endfunction startup()if file.open("init.lua") == nil thenprint("init.lua deleted or renamed")elseprint("Running")file.close("init.lua")get_broker(iot_test)end
endwifi_connect_event = function(T)print("Connection to AP(" .. T.SSID .. ") established!")print("Waiting for IP address...")if disconnect_ct ~= nil thendisconnect_ct = nilend
endwifi_got_ip_event = function(T)print("Wifi connection is ready! IP address is: " .. T.IP)print("Startup will resume momentarily, you have 3 seconds to abort.")print("Waiting...")tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
endwifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.sta.connect()

各位读者需要自己将 ID 更改为自己的特殊信息,或者将整个主题更改为包含自己特征的主题,因为我们使用的是公共的 MQTT 服务器,为了避免接收到别人的消息,影响我们的测试,迫不得已这样做,在后来,我们会介绍如何自己部署一个 MQTT 服务器,到时候就不需要考虑这些主题的问题了,到时候就需要考虑设备的唯一表示 ID 主题。

3. 现象

3.1. 连接上 MQTT 服务

  1. 首先连接 WIFI
  2. 连接上 MQTT 服务器
  3. 订阅主题,并将订阅的主题打印出来

  • 这个就是 ESP8266 订阅的主题
/topic/ctiot/666/c

3.2. 接收到 MQTT 消息

我们使用之前介绍过的 MQTTX 客户端,往我们订阅的主题发送消息,我的主题是:

/topic/ctiot/666/c

使用 MQTTX 软件往上述的主题发送消息,ESP8266 就可以接收到消息了,如下

关于 MQTTX 如何使用,可参考这篇博客:《ESP8266通信指南》10-MQTT通信(Arduino开发)-CSDN博客

4. 代码详解

4.1. 初始化 Wi-Fi 连接参数

station_cfg = {}
station_cfg.ssid = "xlu_2.4"
station_cfg.pwd  = "111222333+"
station_cfg.auto = false
station_cfg.save = false

在这段代码中,我们初始化了 Wi-Fi 连接参数 station_cfg,包括 SSID、密码、自动连接和保存连接信息的设置。

  • station_cfg.ssid: Wi-Fi 的 SSID,即网络名称。
  • station_cfg.pwd: Wi-Fi 的密码。
  • station_cfg.auto: 是否自动连接 Wi-Fi。
  • station_cfg.save: 是否保存 Wi-Fi 连接信息。

4.2. 设置 MQTT 连接参数

x_id=666
mqtt_cfg = {}
mqtt_cfg.host      = "broker.emqx.io"
mqtt_cfg.port      = 1883
mqtt_cfg.clientid  = "alro_xxx".. x_id
mqtt_cfg.keepalive = 120
mqtt_cfg.username  = "AlvaRocha"
mqtt_cfg.password  = "aio_KO<safety edit>sXwbgtWCboCal"

这部分代码定义了 MQTT 连接的参数,包括代理主机、端口、客户端 ID、保持连接时间、用户名和密码。

  • x_id: 用于客户端 ID 的标识符。
  • mqtt_cfg.host: MQTT 代理的主机地址。
  • mqtt_cfg.port: MQTT 代理的端口。
  • mqtt_cfg.clientid: MQTT 客户端 ID,结合了固定的前缀和 x_id
  • mqtt_cfg.keepalive: 客户端与服务器之间的心跳保持时间(以秒为单位)。
  • mqtt_cfg.usernamemqtt_cfg.password: MQTT 代理的用户名和密码。

4.3. 定义 MQTT 主题

x_topic="/topic/ctiot/".. x_id

这一行代码定义了 MQTT 主题,其中包含了一个固定的前缀 "/topic/ctiot/" 和之前定义的 x_id。这个主题将用于发布和订阅消息。

4.4. 初始化 Wi-Fi 连接

m=nil
wifi.setmode(wifi.STATION)
wifi.sta.config(station_cfg)

在这里,我们将 Wi-Fi 模式设置为 STATION(即客户端模式),然后配置 Wi-Fi 参数为之前定义的 station_cfg

初始化 MQTT 客户端

iot_test = mqtt.Client(mqtt_cfg.clientid, mqtt_cfg.keepalive, mqtt_cfg.username, mqtt_cfg.password)

这行代码创建了一个 MQTT 客户端实例,使用了之前定义的 MQTT 连接参数。

4.5. 定义 MQTT 客户端事件处理函数

iot_test:on("offline", function(client)print("client offline")
end)
iot_test:on("message", function(client, topic, data)if data ~= nil thenprint(data)end
end)

这里定义了两个事件处理函数,分别处理客户端离线和收到消息的情况。当客户端离线时,打印提示信息;当收到消息时,打印消息内容。

4.6. 定义连接到 MQTT 代理的函数

function get_broker(mqtt_client)mqtt_client:connect(mqtt_cfg.host, mqtt_cfg.port, false,function(client)client:subscribe(x_topic.."/c", 0, function(client)print("subscribe success "..x_topic.."/c")end)m:publish(x_topic.."/m", "success", 0, 0, function(client)print("init success")end)end,function(client, reason)print('connection failed', reason)end)m=mqtt_client
end

这个函数用于连接到 MQTT 代理,并订阅一个主题以及发布一条消息。连接成功后,将打印订阅成功和发布成功的信息。

4.7. 启动函数

function startup()if file.open("init.lua") == nil thenprint("init.lua deleted or renamed")elseprint("Running")file.close("init.lua")get_broker(iot_test)end
end

这个函数用于启动 MQTT 客户端。首先检查是否存在 init.lua 文件,如果存在,则执行 get_broker 函数。

4.8. 定义 Wi-Fi 连接事件处理函数

wifi_connect_event = function(T)print("Connection to AP(" .. T.SSID .. ") established!")print("Waiting for IP address...")if disconnect_ct ~= nil thendisconnect_ct = nilend
endwifi_got_ip_event = function(T)print("Wifi connection is ready! IP address is: " .. T.IP)print("Startup will resume momentarily, you have 3 seconds to abort.")print("Waiting...")tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
end

这里定义了两个 Wi-Fi 连接事件处理函数,分别处理连接到 AP 和获取 IP 地址的情况。当连接到 AP 时,打印连接成功的提示信息;当获取到 IP 地址时,打印 IP 地址,并在 3 秒后执行 startup 函数。

4.9. 注册 Wi-Fi 事件回调函数并连接 Wi-Fi

wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.sta.connect()

最后,注册了 Wi-Fi 事件回调函数,并启动 Wi-Fi 连接。

4.10. 带有注释的完整代码

带有中文注释的代码在烧录的时候有时候会烧录不进去,原因是中文编码导致的问题,建议如下:

  1. 不烧录带有中文的代码
  2. 将注释更改为简单易懂的英文

在这里贴出中文注释代码的原因是为了方便各位同学学习和阅读代码

-- 初始化 Wi-Fi 连接参数
station_cfg = {}
station_cfg.ssid = "xlu_2.4"  -- Wi-Fi SSID
station_cfg.pwd  = "111222333+"  -- Wi-Fi 密码
station_cfg.auto = false  -- 不自动连接
station_cfg.save = false  -- 不保存连接信息-- 设置 MQTT 连接参数
x_id = 666
mqtt_cfg = {}
mqtt_cfg.host      = "broker.emqx.io"  -- MQTT 代理主机
mqtt_cfg.port      = 1883  -- MQTT 代理端口
mqtt_cfg.clientid  = "alro_xxx" .. x_id  -- MQTT 客户端 ID
mqtt_cfg.keepalive = 120  -- 保持连接时间
mqtt_cfg.username  = "AlvaRocha"  -- MQTT 用户名
mqtt_cfg.password  = "aio_KO<safety edit>sXwbgtWCboCal"  -- MQTT 密码-- 定义 MQTT 主题
x_topic = "/topic/ctiot/" .. x_id-- 初始化 Wi-Fi 连接
m = nil
wifi.setmode(wifi.STATION)
wifi.sta.config(station_cfg)-- 初始化 MQTT 客户端
iot_test = mqtt.Client(mqtt_cfg.clientid, mqtt_cfg.keepalive, mqtt_cfg.username, mqtt_cfg.password)-- 定义 MQTT 客户端事件处理函数
iot_test:on("offline", function(client)print("client offline")
end)iot_test:on("message", function(client, topic, data)if data ~= nil thenprint(data)end
end)-- 定义连接到 MQTT 代理的函数
function get_broker(mqtt_client)mqtt_client:connect(mqtt_cfg.host, mqtt_cfg.port, false,function(client)client:subscribe(x_topic .. "/c", 0, function(client)print("subscribe success " .. x_topic .. "/c")end)-- 发布一条消息m:publish(x_topic .. "/m", "success", 0, 0, function(client)print("init success")end)end,function(client, reason)print('connection failed', reason)end)m = mqtt_client
end-- 启动函数
function startup()if file.open("init.lua") == nil thenprint("init.lua deleted or renamed")elseprint("Running")file.close("init.lua")get_broker(iot_test)end
end-- 定义 Wi-Fi 连接事件处理函数
wifi_connect_event = function(T)print("Connection to AP(" .. T.SSID .. ") established!")print("Waiting for IP address...")if disconnect_ct ~= nil thendisconnect_ct = nilend
endwifi_got_ip_event = function(T)print("Wifi connection is ready! IP address is: " .. T.IP)print("Startup will resume momentarily, you have 3 seconds to abort.")print("Waiting...")tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
end-- 注册 Wi-Fi 事件回调函数并连接 Wi-Fi
wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.sta.connect()

5. 结语


在小节中学习了如何使用 ESP8266 连接 MQTT 服务器同时订阅一个主题,在接收到 MQTT 服务器上发送来的消息的时候,将数据打印出来,在下一小节中我们将学习,如何将串口接收到的消息发送到 MQTT 服务器。



柴头物联网出品

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3030090.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

面试中算法(找到两个数组的中位数)

有两个升序数组&#xff0c;如何找出这两个数组归并以后新的升序数组的中位数? 中位数把一个升序数组分成了长度相等的两部分&#xff0c;其中左半部分的最大值永远小于或等于右半部分的最小值。 如上图所示&#xff0c;对于偶数长度的数组&#xff0c;可以根据中位数分成长度…

一文了解webpack和vite中Tree-Shaking

1、什么是Tree-Shaking 1.1 摇树优化&#xff08;Tree Shaking&#xff09;是Webpack中一种用于优化JavaScript代码的技术。它的目标是通过静态分析&#xff0c;从代码中剔除未被使用的模块&#xff0c;从而减少最终打包文件的大小。 1.2 Tree-shaking 它的名字来源于通过摇晃…

物联网技术在数字化工厂中的应用,你知道多少?——青创智通

工业物联网解决方案-工业IOT-青创智通 物联网&#xff08;IoT&#xff09;技术在数字化工厂的应用正日益成为工业革命的重要推动力。随着科技的飞速发展&#xff0c;物联网技术不断革新&#xff0c;其在数字化工厂中的应用也呈现出愈发广泛和深入的态势。本文将详细探讨物联网…

传输层之 TCP 协议

TCP协议段格式 源/目的端口号&#xff1a;表示数据是从哪个进程来&#xff0c;到哪个进程去。 序号&#xff1a;发送数据的序号。 确认序号&#xff1a;应答报文的序号&#xff0c;用来回复发送方的。 4 位首部长度&#xff1a;一个 TCP 报头&#xff0c;长度是可变的&#xff…

Android 屏幕适配全攻略(上)-掌握屏幕单位,应对千变万化的设备

本文从 Android 开发中常见的长度单位 px、dp、sp 入手&#xff0c;详细介绍了它们的特点及转换关系。 接着深入探讨了屏幕尺寸、分辨率、像素密度等重要的屏幕指标&#xff0c;帮助读者全面理解它们之间的联系。最后&#xff0c;通过实例代码演示了如何在代码中进行单位转换&…

第一章 buffer cache管理 - 2 原理机制

本章节主要介绍缓冲区管理器机制&#xff0c;从原理上介绍共享缓冲区如何管理内存页。 1、缓冲区管理器的结构 PostgreSQL缓冲区管理器由缓冲区hash表、缓冲区buffer描述符和缓冲池组成。下面依次介绍这几个结构。 1.1 缓冲区标签 typedef struct buftag {RelFileNode rnod…

Python运维之协程

目录 一、定义协程 二、并发 三、异步请求 协程是一种轻量级的线程&#xff0c;它通过保存和恢复寄存器上下文和栈来实现调度切换&#xff0c;从而保留函数执行的状态。 这种机制使得协程在处理I/O密集型任务时效率较高&#xff0c;因为它们可以在I/O操作期间让出CPU&#…

5g视频彩信和普通彩信有什么区别

5G视频彩信和普通彩信有什么区别 随着科技的不断进步&#xff0c;手机通信技术也在迅速发展。5G技术的出现&#xff0c;为彩信传输提供了更高的速度和更广的带宽。在这种背景下&#xff0c;5G视频彩信和普通彩信成为了人们关注的焦点。本文将探讨这两种彩信的区别。 5G视频彩信…

Java数组的应用---选择排序(Select Sort)

一、需求&#xff1a;选择排序(Select Sort)&#xff0c;进行升序显示 在一组排列中把最大的数取出来放在一个新的列表里&#xff0c;再删去&#xff0c;在取最大的数出来&#xff0c;依次类推直到取到最后一个数字 二、定义一个无序的一维数组&#xff0c;并输出数组 程序运…

BBS客户端服务器的编写

根据网络编程中的内容&#xff0c;我们本篇文章将讲解一个bbs通信的项目&#xff0c;首先让我们了解一下什么是bbs. 一、bbs介绍 BBS&#xff0c;即Bulletin Board System的缩写&#xff0c;中文译为“电子公告板系统”或“网络论坛”。它是一个在网络上进行信息交流和讨论的…

重装前端整体流程

用户管理 --汇总 -- 明细-CSDN博客 一、node 这个看环境变量 2023最新版Node.js下载安装及环境配置教程&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了_nodejs安装及环境配置-CSDN博客 配置到国内镜像的时候&#xff0c;去看&#xff0c;淘…

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水 503.下一个更大元素II 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元…

小程序(三)

十三、自定义组件 &#xff08;二&#xff09;数据方法声明位置 在js文件中 A、数据声明位置&#xff1a;data中 B、方法声明位置methods中&#xff0c;这点和普通页面不同&#xff01; Component({/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {isCh…

【系统架构师】-案例篇(七)信息安全

某软件公司拟开发一套信息安全支撑平台&#xff0c;为客户的局域网业务环境提供信息安全保护。该支撑平台的主要需求如下&#xff1a; 1.为局域网业务环境提供用户身份鉴别与资源访问授权功能&#xff1b; 2.为局域网环境中交换的网络数据提供加密保护&#xff1b; 3.为服务…

26、Qt使用QFontDatabase类加载ttf文件更改图标颜色

一、图标下载 iconfont-阿里巴巴矢量图标库 点击上面的链接&#xff0c;在打开的网页中搜索自己要使用的图标&#xff0c;如&#xff1a;最大化 找到一个自己想用图标&#xff0c;选择“添加入库” 点击“购物车”图标 能看到刚才添加的图标&#xff0c;点击“下载代码”(需要…

js教程(13)

一、作用域 作用域规定了变量能够被访问的范围&#xff0c;而离开变量作用域的变量则不能被访问&#xff08;有时也叫变量的生命周期&#xff09;。作用域又分为局部作用域和全局作用域。 1.局部作用域 在函数或代码块内部声明的变量只能在其内部被访问&#xff0c;在外部无法…

牛客周赛 Round 41 C-F

C 小红的循环移位 思路&#xff1a; 一个数是不是四的倍数&#xff0c;只用看最后两位是否能够整除4即可。 #include <bits/stdc.h>using namespace std; const int N 1e6 5; typedef long long ll; typedef pair<ll, ll> pll; typedef array<ll, 3> p3;…

暗区突围进不去/游戏无法启动/掉帧卡顿/报错的解决方法

暗区突围是一款高拟真硬核射击手游&#xff0c;打造了全新的沉浸式暗区战局体验&#xff0c;发行商是腾讯公司。这个游戏名词虽然看起来有些陌生&#xff0c;但其本身的玩法内核毫无疑问的是&#xff0c;这款游戏在画面质量和枪械操作方面&#xff0c;都是手游市场上同类游戏中…

【vulhub靶场】Apache 中间件漏洞复现

【vulhub靶场】Apache 中间件漏洞复现 一、Apache HTTPD 换行解析漏洞&#xff08;CVE-2017-15715&#xff09;1. 漏洞详情2. 影响版本3. 漏洞复现 二、Apache多后缀解析漏洞&#xff08;apache_parsing_vulnerability&#xff09;1. 漏洞详情2. 漏洞复现 三、Apache HTTP Serv…

【LLM 论文】Step-Back Prompting:先解决更高层次的问题来提高 LLM 推理能力

论文&#xff1a;Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models ⭐⭐⭐⭐ Google DeepMind, ICLR 2024, arXiv:2310.06117 论文速读 该论文受到的启发是&#xff1a;人类再解决一个包含很多细节的具体问题时&#xff0c;先站在更高的层次上解…