目录
1. 前言
2. MQTT
2.1 相关简介
2.2 协议特点
2.3 协议原理
2.4 交互流程
2.5 应用
3. 简单测试
3.1 测试准备
3.2 连接方式
3.3 程序流程图
3.4 相关代码
3.5 测试现象
4. 总结
5. 相关链接
本章相关例程链接https://gitee.com/wiznet-hk/example-of-w6100-evb-pico.git
上一章我们用W6100-EVB-PICO开发板进行UDP组播回环测试,本章用我们的开发板作为MQTT客户端连接MQTT服务器进行简单测试。
注意这里我们用的MQTT版本为3.1.1。
随着物联网技术的快速发展,MQTT(Message Queuing Telemetry Transport)协议已成为一种广泛使用的通讯协议,它适用于设备间低带宽、高延迟、不可靠的网络通信。W6100是一款集成全硬件 TCP/IP 协议栈的嵌入式以太网控制器,同时也是一颗工业级以太网控制芯片。在以太网应用中使用 W6100 + MQTT应用协议让用户可以更加方便地在设备之间实现远程连接和通信。本教程将介绍W6100以太网MQTT应用的基本原理、使用步骤、应用实例以及注意事项,帮助读者更好地掌握这一技术。
MQTT协议具有以下特点:
在MQTT有三种角色,发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe);其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
套入具体的场景就是设备采集温湿度并发布在对应主题上,服务器会将其发布的消息发送给订阅了对应主题的其他客户端(如果发布消息的客户端也订阅了该主题,那它自己也会收到)。采集温度和湿度的设备分别将数据发送到主题“temperature”和“humidity”,订阅了这两个主题的设备便会收到对应主题上的数据,如下图所示:
以一个客户端为例,交互流程是客户端向服务器发送连接请求,服务器回复确认连接后,连接建立;客户端发送订阅主题的请求,服务器回复确认后,订阅主题完成;客户端发布消息后,服务器回复发布确认,则消息发布完成,没有操作后会根据设定的时间,每到一次发送一次心跳请求,服务器返回心跳响应,以维持连接。过程如下图所示(注:图示例子为QOS=1的情况):
值得一提的是,在订阅请求和发布消息中都有服务质量等级,等级有0,、1、2三种,分别代表最多分发一次(QOS=0)、至少分发一次(QOS=1)、仅分发一次(QOS=2);订阅请求中的服务质量等级(服务质量要求)是订阅者与服务器之间的交互规则,发布消息中的服务质量等级是发布者与服务器之间的交互规则。只是指代对象不同,相同等级对应的交互规则是相同的。
下边分别简单说下每个服务质量等级的交互过程:
QOS = 0:发送者最多发送一次,且接受者没有回复。
QOS = 1:发送者最少发送一次,接收者收到后回复确认。
QOS = 2:发送者只发送一次,接受者收到后回复收到,然后发送者再发送释放请求,接受者回复释放完成。
这里发送者——接收者可以是发布者——服务器(发布消息的服务质量等级),也可以是服务器——订阅者(订阅请求的服务质量要求)。
如下图所示:
我们本章的原理那节描述的只是在传感器网络中的应用,它还可以应用在实时数据传输场合中的如股票市场数据、实时天气信息、即时更新的新闻、监测博客的文章浏览量或粉丝量等,以及工农业控制中的远程下发控制等。
硬件:
软件:
开发板和PC都接在交换机或路由器LAN口
主函数中,我们先配置好网络信息,然后初始化定时器、mqtt信息等,即系统初始化,然后死循环里执行保活函数即可,如下所示:
int main()
{
struct repeating_timer timer;
stdio_init_all();
sleep_ms(2000);
network_init();
add_repeating_timer_ms(1, repeating_timer_callback, NULL, &timer);
mqtt_init(); // mqtt连接函数
while (true)
{
keep_alive(); // mqtt保活
}
}
快速上手使用的话,主要看这几个参数,pubtest[]是我们测试发送的字符串,接着连接参数用一个结构体来存放,其中有mqtt服务器ip和端口、连接的客户端ID、用户名和密码、订阅的主题和发布消息的主题、以及订阅请求的服务质量等级;其中客户端ID在同一平台下(服务器)是唯一的,不可重复,否则会出现后连接的把已经连接的设备挤掉的情况;用户名和密码用以我们不同用户的区别信息,不同平台如阿里云和腾讯云鉴权方式不同,这个以具体平台为准,这里调试工具的平台我们随便填就好,仅用于调试;订阅主题就是我们订阅的主题名;发布消息的主题就是我们选择在哪个主题发布消息。
同样的,发布消息相关参数包括发布消息质量服务等级、发布消息保留标志、重复分发标志、消息ID;发布消息的质量服务等级即QOS,发布消息的保留标志(RETAIN),设为1的话,服务器会保留最近一次发布消息,并发给订阅了该主题的设备,如果设备已经收了但是掉线后重连也仍然会收到;重复分发标志就是在QOS=1或2时,如果发送消息后接收方未回复,则该位被置1,发送方会重复发送;如下所示:
uint8_t pubtest[]="hello mqtt";
typedef struct MQTTCONNECTION
{
char mqttHostUrl[1024];
int port;
char clientid[1024];
char username[1024];
char passwd[1024];
uint8_t server_ip[4];
char pubtopic[255];
char subtopic[255];
int QOS;
} mqttconn;
/* 连接、订阅参数相关 */
mqttconn mqtt_params = {
.server_ip = {54, 244, 173, 190},
.port = 1883,
.clientid = "W6100",
.username = "W6100",
.passwd = "123456",
.pubtopic = "W6100",
.subtopic = "W6100",
.QOS = 0, // 订阅请求的服务等级要求
};
// 发布消息相关参数
MQTTMessage pubmessage = {
.qos = QOS0, // 发布消息服务质量等级
.retained = 0, //发布报文的保留标志
.dup = 0, //重复分发标志
};
除了发布-订阅模式,还有一个重要的遗嘱模式,遗嘱模式的相关参数有遗嘱主题、遗嘱消息、服务质量等级、保留标志;服务质量等级和保留标志跟发布消息一样,不再过多说,遗嘱主题和遗嘱消息主要是设备因为一些原因导致断开连接后,订阅了遗嘱主题的设备,便会收到掉线设备的遗嘱消息;即掉线设备在连接服务器时发布的遗嘱消息,服务器会保存下来,在检测到设备掉线后会发布该消息给订阅了遗嘱主题的其他在线的设备;参数如下所示:
/* 遗嘱消息相关参数 */
MQTTPacket_willOptions will_info = {
.topicName = "device_status", // 遗嘱主题
.message = "offline", // 遗嘱消息
.qos = 0, // 服务质量等级
.retained = 0, // 保留标志
};
了解了以上几种不同的参数后,我们就可以根据需要自行修改了,而不必过于关注底层,是不是非常容易上手呢。
我们编译烧录下载到开发板后,打开wireshark输入mqtt过滤,打开MQTTX,填写相关参数,注意Client ID不要相同,否则后连接的会把先连接的挤掉;其他信息可任意填写,因为我们不是连接特定平台如阿里云、腾讯云等需要根据平台规则连接,我们是用MQTTX这个工具的服务器平台,这与程序中设置服务器ip一致,配置完后点击连接,添加订阅主题为“W6100”和“device_status”,其余默认即可;然后打开vscode自带的串口监视器,复位我们的开发板。
在串口打印的信息中我们可以看到开发板在配置完网络信息后成功连接了MQTT服务器,并成功订阅了主题“W6100”,发布了消息“hello mqtt”;在MQTTX调试工具这边我们可以看到也收到了来自主题W6100的消息,即正是开发板在该主题发布的信息,同样的我们可以在MQTTX这边发布消息,在串口那边显示收到,如下图所示:
然后我们点击“device_status”这个(遗嘱)主题,我们把网线拔了,模拟实际场景中的设备意外掉线的情形,等待一会可以看到,我们调试工具这边收到了遗嘱消息,如下图所示:
我们看wireshark这边抓包的情况,由于没连接抓包交换机,这里只能抓到跟我们PC交互的数据,首先看到我们用MQTTX工具连接并订阅后的数据交互情况,然后开发板连接订阅并发布了一条消息,MQTTX直接收到了该消息,接着通过MQTTX在该主题发布消息,开发板和MQTTX也都收到了,也即订阅了该主题的设备都可以收到,其他设备在该主题发布的消息,如下图所示:
从以太网接入方式来看,不同于以往的的MCU(无MII/RMII接口)+MAC+PHY或MCU(有MII/RMII接口)+PHY,然后运行软件协议栈的接入方式,我们通过MCU+W6100(MAC+PHY和TCP/IP 硬件协议栈)直接从硬件层面实现了从链路层到传输层的协议栈,那么应用层如我们本章节所涉及的MQTT协议,可以通过软件组包解包实现,而且提供丰富的库非常方便我们进行开发。
值得一提是W6100不仅支持IPv4,还支持IPv6。
想了解更多,评论留言哦。