ESP32使用MQTT协议通讯(EMQX)

news2025/1/21 22:02:52

一、背景介绍

前面完成了ESP32+MicroPython环境的搭建01_ESP32 MicroPython开发环境搭建_eps32开发板-CSDN博客

现在想实现以下功能:

1.通过手机或电脑,远程给ESP32发送相关指令。

2.ESP32接到指令后,做出相应的高低电平输出。

这样就相当于可以远程控制ESP32了。

查询资料了解到,目前物联网差不多都使用MQTT协议来进行设备间通信。所以从协议开始学习。

二、MQTT协议

       MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。
       MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。

三、MQTT服务器 

现在电脑有了,ESP32有了,要完成手机或电脑与ESP32通信,中间还差了个MQTT服务器。网上搜了一番,发现EMQX提供了一个免费的MQTT服务器-免费的公共 MQTT 服务器 | EMQ。(这里就不截图了,只给链接,免得有广告嫌疑)可以用来测试,后面用于生成环境时,可以考虑自己部署一个MQTT服务器。

四、实现步骤

1.准备工作

我们这里使用Thonny+MicroPython来演示通信过程,需要注意的是:这里使用的是MicroPython v1.23.0 on 2024-06-02,不同版本可能有所差异。

我们使用命令 help('modules')查看已安装的模块,其中umqtt/robust,umqtt/simple就是用来进行MQTT协议通信的模块

2.EMQ客户端

为了方便调试程序,我们在电脑端安装一个MQTT的客户端,EMQ提供了一个客户端MQTTX:全功能 MQTT 客户端工具,点击链接下载并安装即可。后面我们就通过这个客户端与ESP32进行通信。

3.ESP32 发布消息,EMQ客户端订阅

这种模式下,ESP32是发布者,EMQClient是订阅者,ESP32发送消息到MQTT服务器,MQTT服务器将消息推送给EMQClient。

EMQ的MQTT服务器是可以不做身份验证的,所以下面代码中:

mqtt_client 可以随便写,只要与现有的不重复就行。

mqtt_user,mqtt_password 保持发布和订阅一致就行。

其中mqtt_topic比较关键,是发布者与订阅者之间的桥梁,ESP32和EMQ客户端两边要一致。

import time
import network
import utime 
from umqtt.robust import MQTTClient

# WiFi 连接信息
wifi_ssid = '******' # 请替换为自己的WiFi
wifi_password = '******' # 请替换为自己的WiFi

# MQTT 服务器信息
mqtt_server = 'broker.emqx.io'
mqtt_port = 1883
mqtt_user = 'username'
mqtt_password = 'password'
mqtt_client = 'mqttx_20240804-esp32' # 客户端ID
mqtt_topic = b'mqttx_20240804' # 主题

# 时间戳
def currentTime():
    # 获取当前时间元组
    current_time = utime.localtime()
    # 解构时间元组
    year, month, day, hour, minute, second, _, _ = current_time
    # 使用字符串格式化功能生成日期时间字符串
    formatted_time = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(year, month, day, hour, minute, second)
    return formatted_time

# 连接 WiFi
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(wifi_ssid, wifi_password)
while not wifi.isconnected():
    time.sleep(1)
 
# 定义消息回调函数
def sub_cb(topic, msg):
    print((topic, msg))

# 创建MQTT客户端对象
client = MQTTClient(mqtt_client, mqtt_server, mqtt_port,mqtt_user, mqtt_password)

# 设置消息回调函数
client.set_callback(sub_cb)

# 连接到MQTT代理
client.connect()

# 发布消息 
client.publish(mqtt_topic, b'Hello World! '+currentTime())

# 断开与MQTT代理的连接
client.disconnect()

在EMQ客户端订阅上面的主题: mqttx_20240804,可以看到这样的结果

4.ESP32 订阅消息,EMQ客户端发送消息

这种模式下,ESP32是订阅者,EMQClient是发布者,EMQClient发送消息到MQTT服务器,MQTT服务器将消息推送给ESP32。

import time
import network
import utime 
from umqtt.robust import MQTTClient

# WiFi 连接信息
wifi_ssid = '******' # 请替换为自己的WiFi
wifi_password = '******' # 请替换为自己的WiFi

# MQTT 服务器信息
mqtt_server = 'broker.emqx.io'
mqtt_port = 1883
mqtt_user = 'username'
mqtt_password = 'password'
mqtt_client = 'mqttx_20240804-esp32' # 客户端ID
mqtt_topic = b'mqttx_20240804' # 主题

# 时间戳
def currentTime():
    # 获取当前时间元组
    current_time = utime.localtime()
    # 解构时间元组
    year, month, day, hour, minute, second, _, _ = current_time
    # 使用字符串格式化功能生成日期时间字符串
    formatted_time = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(year, month, day, hour, minute, second)
    return formatted_time

# 连接 WiFi
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(wifi_ssid, wifi_password)
while not wifi.isconnected():
    time.sleep(1)
 
# 定义消息回调函数
def sub_cb(topic, msg):
    print(currentTime()+" 收到主题 "+topic.decode('utf-8')+' 消息 ' +msg.decode('utf-8'))
    

# 创建MQTT客户端对象
client = MQTTClient(mqtt_client, mqtt_server, mqtt_port,mqtt_user, mqtt_password)

# 设置消息回调函数
client.set_callback(sub_cb)

# 连接到MQTT代理
client.connect()

# 订阅主题
client.subscribe(mqtt_topic)
print("ESP32已开启消息订阅,请在EMQ客户端发送消息...")

# 持续接收消息
while True:
    client.check_msg()
    
# 断开与MQTT代理的连接
client.disconnect()

这时,在EMQ客户端发送消息到对于的主题mqttx_20240804,ESP32就可以收到对于的消息了。

至此,ESP32通过MQTT收发消息就实现了,后面将EMQ客户端改为Android客户端发送,就可以实现手机端与ESP32通信了。离手机控制ESP32又进一步了。

补充说明:

MicroPython的umqtt是一个用于MicroPython的简单MQTT客户端,它实现了CPython模块paho-mqtt的一个子集,但也有一些特殊的特点和限制。

umqtt模块的主要特点是:

它支持MQTT v3.1.1协议,但不支持QoS 。
它支持消息回调,并且为接收消息提供了阻塞和非阻塞的两种实现。
它支持SSL/TLS加密连接,但需要额外的ssl模块。
它分为simple和robust两个子模块,robust模块提供了自动重连和延时发送等功能,但也有一些缺陷。

umqtt模块的应用场景是:

在MicroPython中实现与互联网或局域网中的其他设备或服务的通信,如获取天气信息、控制智能家居设备、上传传感器数据等。
在MicroPython中实现基于MQTT协议的客户端或服务器端的应用,如物联网设备、远程控制、消息推送等。

umqtt模块需注意事项是:

由于MicroPython的内存限制,umqtt模块不能处理过大的消息内容,否则可能导致内存不足或异常。
由于MicroPython的网络支持不完善,umqtt模块可能在不同的硬件平台或MicroPython版本上有不同的表现或错误。
由于umqtt.robust模块在弱网或断网后可能出现死锁或无限递归等问题,建议使用micropython-mqtt库5来替代它,该库提供了更稳定和灵活的MQTT客户端实现。 

参考文档

【雕爷学编程】MicroPython手册之MQTT通信 umqtt 模块_micropython mqtt-CSDN博客

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

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

相关文章

视频编辑SDK,底层架构合理,前端自定义程度高

如何高效、专业地制作出符合品牌形象、吸引目标受众的视频内容,成为了众多企业面临的共同挑战。美摄科技,作为视频编辑技术的先行者,以其卓越的视频编辑SDK(Software Development Kit),为企业用户量身打造了…

进程状态都有哪些?

目录 前言: 进程的各个状态: 1、R状态(进程运行状态)和S状态(休眠状态) 2、T状态和t状态(暂停进程) 3、D状态(磁盘休眠状态) 4、Z状态(僵尸状…

学习笔记 韩顺平 零基础30天学会Java(2024.8.2)

P447 五大运行时异常 P448 异常课堂练习 P449 异常处理机制 try-catch-finally throws(处理机制二选一),如果没有显式处理异常,默认throws JVM处理异常直接输出异常信息,退出程序 P450 tryCatch 对于第一个细节,发生异常之后时try…

C语言快速入门及精通学习指南——手把手教零基础/新手入门(完整C语言学习笔记整理)

前言 作为一名拥有多年开发经验的码农,我的职业生涯涵盖了多种编程语言,包括 C 语言、C、C# 和 JavaScript。在这一过程中,我深刻地意识到扎实的基础对于编程学习的重要性,尤其是对于 C 语言这样一门核心语言来说。 出于对…

sgg快餐项目-3 项目

一、数仓架构 本项目的数据是事务数据,都存储在mysql数据库,如果是其他的项目,那数据可能会在文本、爬虫等。要使用相关的组件将数据导入到HDFS上。(因为要把数据导入到hive做数据管理、存储和分析,而hive就是在hfds上…

2024年文件防泄密系统TOP3|遥遥领先的文件防泄密系统

古语有云:“密者,国之重器,不可不慎。” 在今日之数字化时代,信息的保密与安全,已然成为企业乃至国家生存与发展的基石。 随着数据泄露事件频发,文件防泄密系统的重要性愈发凸显。 2024年,随着…

数据存储与访问

一、文件存储读写 1.Android文件的操作模式 2.文件的相关操作方法 3.文件读写的实现 Android中的文件读写和Java中的文件I/O相同,流程也很简单,下面我们来写个简单的示例: PS:这里用的是模拟器,因为笔者的N5并没有root&#xf…

Go语言加Vue3零基础入门全栈班11 Go语言+gorm用户管理系统实战 2024年08月03日 课程笔记

概述 如果您没有Golang的基础,应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227GoRedis开发用户管理系统API实战_20240730Mo…

工业人工智能真的能落地吗?

文章目录 前言Part1 聊聊技术1 人工智能、机器学习和深度学习的关系2 优化思想的一个案例 part2 聊聊业务3 工业人工智能与消费互联网人工智能的区别3.1 消费互联网中人工智能的应用3.2 为什么如此成熟的消费互联网人工智能扩展到工业场景那么难 4 工业互联网人工智能的发展方向…

wxPython中wx.adv.DatePickerCtrl用法

wx.adv.DatePickerCtrl是一个日期选择组件,支持键盘手工录入日期和弹出日历窗口选择日期两种方式。 一、组件样式 wx.adv.DP_SPIN : 只允许键盘手工录入和组件右侧上下箭头调整日期。 wx.adv.DP_DROPDOWN : 只允许健盘手工录入和组件右侧打开…

CentOS7 编译ffmpeg wasm库

1. 安装 emscripten 1)克隆 emsdk git clone https://github.com/emscripten-core/emsdk.git 2)cd 到emsdk 3)安装,按照官网的步骤(Download and install — Emscripten 3.1.65-git (dev) documentation) 4)验证 注意:如果emcc -v 报错: 提示是python脚本错误,是因为…

Qt Modbus 寄存器读写实例

一.线圈状态寄存器读写 项目效果如下 1. 写单个寄存器 MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status); int addrui->spinBoxwirte_addr->value();int dataui->spinBoxwirte_data->value();int ret modbus_write_bit(mb,addr,d…

【Qt】Qt日志信息处理

Qt日志信息处理 一、介绍二、相关函数的使用介绍1. qInstallMessageHandle2. QtMsgType3. QMessageLogContext 三、一个简单示例 一、介绍 Qt有Info、Debug、Warning、Critical、Fatal五种级别的调试信息。 Info: 提示信息qDebug:调试信息qWarning:警告…

目标检测——X光安检数据集

1. OPIXray数据集(2020) 2. HIXray数据集(2021) 3. SIXray数据集(2019) 4. CLCXray数据集(2022) 5. PIDray数据集(2021) 6. GDXray数据集(20…

C++-引用,inline,nullptr

一,引用 1.1引用的概念与定义 引用不是新定义⼀个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同⼀块内存空间。 引用的使用方式如下: 类型& 引用别名 引用对象…

【带你入门生信】什么是生物信息学

生物信息学 生物信息学:利用应用数学、信息学、统计学和计算机科学,对生物学数据进行搜索(收集和筛选)、处理(编辑、整理、管理和显示)及分析(计算和模拟),提取生物信息…

一键生成原创文案,轻松成为文案高手的方法

当下时代,文案写作对于各个企业推广产品和服务显得隔外重要。优秀的文案能够吸引用户的注意力,激发购买欲望,从而为企业带来更多的销售机会。然而,对于许多人来说,撰写出一篇吸引人的原创文案可能并不容易。但是&#…

【C++】C++11之新的类功能与可变参数模板

目录 一、新的默认成员函数 二、新的关键字 2.1 default 2.2 detele 2.3 final和override 三、可变参数模板 3.1 定义 3.2 递归展开参数包 3.3 逗号表达式展开参数包 3.4 emplace_back 一、新的默认成员函数 在C11之前,默认成员函数只有六个,…

2024华数杯选题建议-建模思路-代码论文助攻

你是否在寻找数学建模比赛的突破点?数学建模进阶思路! 作为经验丰富的数学建模团队,我们将为你带来2024 华数杯的全面解析。这个解决方案包不仅包括完整的代码实现,还有详尽的建模过程和解析,帮助你全面理解并掌握如何…

C:关于static 和 extern 关键字的介绍-学习笔记

目录 1、作用域与生命周期 1.1 作用域 1.2 生命周期 1.3 变量的作用域和生命周期之间的关系 2、static 和 extern 2.1 static 修饰局部变量: 2.2 static 修饰全局变量(包含extern的作用): 2.3 static修饰函数&#xff1a…