在前面,我们已经学会了 ESP32-C3 的WiFi 配置以及使用,为我们学习网络协议建立了基础。
这篇文章我们就来学习测试一下ESP32-C3 的 MQTT 驱动。
前言
接下来的 ESP32-C3 功能测试都是基于自己设计的开发板:
自己画一块ESP32-C3 的开发板(第一次使用立创EDA)(PCB到手)
开发环境是乐鑫官方的 ESP-IDF, 基于VScode插件搭建好的:
ESP32-C3 VScode开发环境搭建(基于乐鑫官方ESP-IDF——Windows和Ubuntu双环境)
学习 ESP32-C3 的 MQTT 协议包使用,不要用到其他外设。
1、基础介绍
1.1 MQTT协议基本概念
基本概念的东西网上很多,基本概念这里从网上摘取做个说明,说明节选自百度百科和下面的博文:
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
MQTT的通讯模型如下图:
MQTT 协议特点:
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
- 对负载内容屏蔽的消息传输;
- 使用 TCP/IP 提供网络连接;
- 有三种消息发布服务质量:
“至多一次”,消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。
“至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。
- 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
- 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。
Last Will:即遗言机制,用于通知同一主题下的其他设备发送遗言的设备已经断开了连接。Testament:遗嘱机制,功能类似于Last Will。
MQTT 协议实现方式:
实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:
- Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);
- payload,可以理解为消息的内容,是指订阅者具体要使用的内容。
1.2 ESP-MQTT 基础
关于 ESP32-C3 的MQTT,官方链接如下: ESP-MQTT官方说明
ESP-MQTT 对应的底层都已经写好 ,官方也是主要介绍了有哪些基于 MQTT 的应用:
1.2.1 SSL
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种 安全协议。TLS与SSL在传输层对网络连接进行加密。大部分互联网登录都是用的SSL/TLS。
在官方的示例代码中,SSL传输的MQTT示例如下:
1.2.2 MQTT over Websocket
MQTT over WebSocket是把MQTT control message 包装成WebSocket包,通过WebSocket 管道发送。即使用WebSocket来支持MQTT Client和Broker的连接。
他们之间的共同点:
- MQTT 和 WebSocket 都是应用层协议目前底层
- 都是使用 TCP 协议确保可靠传输数据
- 都规定了自己的报文(消息)结构
- 都支持双向通信都使用二进制编码(有别于 HTTP 这一类基于文本编码的协议)
- 都是公开标准 mqtt rfc6455
他们之间的区别:
- WebSocket 是一种简单的报文协议,着重解决浏览器和服务端不能进行双向通信的问题。本质上有点像是 TCP 协议之上的 UDP 协议。WebSocket 仅仅定义了会话的发起方式和报文格式及类型。如何使用报文通信全由应用程序控制。
- MQTT 是一套相对比较复杂的消息投递协议,而 WebSocket则只是在TCP协议之上实现了简单的报文通信。两种协议工作层次不一样。从这个意义上讲,MQTT 可以工作在 WebSocket之上。
- MQTT 做原生设备的通信,MQTT over WebSocket 主要用于 MQTT 设备跟 Web 端通信。
在官方的示例中,MQTT over Websocket 的示例如下:
2、示例测试
在前面 ESP3-MQTT 基础介绍中,我们了解到了官方 MQTT 的示例种类,今天作为基础的测试,选用的示例代码为 ../mqtt/tcp
:
2.1 测试工具
本次测试使用在线的公共 MQTT 服务器,公共的在线服务器相关的参考,可查看下面文章:
我们的 ESP32-C3 开发板作为一个客户端, 自己使用的 PC 作为另外一个客户端;
在PC上可以使用 MQTT X 工具:
下载好 MQTT X 工具,我们建立一个连接(基础测试 SSL 就不用勾选了):
上面设置好以后,记住Usename
和 Password
,点击连接即可。
2.2 示例代码简析
入门教程,快速上手,我们从文章开头的介绍也不涉及 MQTT 协议的具体实现与协议格式,这里我们目的是能够正确的掌握 ESP3-MQTT 的使用,能够在一般的项目中快速使用起来。
所以示例代码,简单的介绍一下各部分功能,我们从程序运行的最开头 app_main
开始看,那么在程序开始有一个ESP_ERROR_CHECK(example_connect());
这个函数用来连接wifi的,需要在menuconfig
中配置,但是我们使用的是 Vscode 插件,所以直接点击设置图标:
找到对应的wifi设置,如下图填写 ssid 和 Password:
mqtt_app_start(void)
在app_main
函数的最后就直接调用了 static void mqtt_app_start(void)
函数,在这个函数中,需要根据开始在 MQTT X 工具中的设置进行填写:
注意下图中有个Client ID 选项,客户端的ID,如果要想PC 和 ESP32开发板是不同的客户端,两者ID 不能一样,如果是下图中,那么服务器会认为他们两个是一个客户端,所以实际测试需要注意下,Client ID两者不要一样,那么作为两个独立的客户端,可以做相互发布和订阅测试。
mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
在上面启动了 client
以后,所有的事件发生都是在回调函数中处理, 上面注册的回调函数为mqtt_event_handler
,而这个函数调用了mqtt_event_handler_cb()
函数:
2.3 测试
了解了示例代码,在代码中修改好 mqtt_cfg配置参数 和 wifi 连接参数以后,就可以程序烧录到板子上,上电后运行的效果如下图:
在 PC 客户端MQTT X 工具上,我们也订阅和示例中相同的两个主题,操作如下:
MQTT X 工具设置好,重启开发本,能够收到3条消息,如下图:
和预想的一样,那么我们知道,示例程序中,最后是取消了 /topic/qos1
的订阅,只订阅了/topic/qos0
,所以我们可以通过 PC客户端,发布/topic/qos0
主题的消息,在 MQTT X 工具进行如下操作:
最后的测试效果图如下:
好了,对于示例程序来说,测试到这里就基本结束了。
那么结合我们之前的学习,我们在下一篇文章将会实现一个小的应用, 利用ESP32-C3 使用 MQTT 连接阿里云,上报传感器数据给平台,平台下发命令控制开发板。