STM32F1网络编程-MQTT客户端(基于W5500网卡)

MQTT客户端(基于W5500网卡)

MQTT 是用于物联网 (IoT) 的 OASIS 标准消息传递协议。 它被设计为一种极其轻量级的发布/订阅消息传输,非常适合连接具有小代码足迹和最小网络带宽的远程设备。 如今,MQTT 被广泛用于各种行业,例如汽车、制造、电信、石油和天然气等。

W5500驱动支持MQTT客户端。本次实例将演示如何使用MQTT客户端。

MQTT客户端的主要使用步骤如下:

  • 1)初始化Network对象,并连接Network
  • 2)初始化MQTTClient对象
  • 3)创建MQTT连接
  • 4)订阅主题
  • 5)发布主题

注意:在连接Network时,如MQTT服务器使用的是域名而不是IP地址,则需要使用DNS客户端查询MQTT服务器的IP地址。

关于W5500的驱动移植及IP设置、获取,请参考:

关于TCP通信过程,请参考:

关于远程主机IP查询,请参考:

本次使用的MQTT服务器为:https://mosquitto.org/

1、MQTT客户端

在STM32CubeIDE工程的Application目录下分别添加mqtt_client_demo.hmqtt_client_demo.c文件。其内容分别如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/\*
\* mqtt\_client\_demo.h
\*
\* Created on: 2022年7月18日
\* Author: jenson
\*/

#ifndef MQTT\_CLIENT\_DEMO\_H\_
#define MQTT\_CLIENT\_DEMO\_H\_

void mqtt\_client\_init(void);
void mqtt\_client\_loop(void);

#endif /\* MQTT\_CLIENT\_DEMO\_H\_ \*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/\*
\* mqtt\_client\_demo.c
\*
\* Created on: 2022年7月18日
\* Author: jenson
\*/
#include "app\_config.h"
#ifdef MQTT\_DEMO
#include <stdio.h>
#include <string.h>
#include "stm32f1xx\_hal.h"
#include "mqtt\_client\_demo.h"
#include "w5500.h"
#include "socket.h"
#include "MQTT/MQTTClient.h"

#define MQTT\_CLIENT\_BUFFER\_SIZE 1024
#define MQTT\_SOCKET 0
#define MQTT\_TIMEOUT 1000

static Network network;
static MQTTClient client;

static uint8\_t tx_buffer[MQTT_CLIENT_BUFFER_SIZE]; // 发送缓存
static uint8\_t rx_buffer[MQTT_CLIENT_BUFFER_SIZE]; // 接收缓存
static uint8\_t message_buffer[MQTT_CLIENT_BUFFER_SIZE]; //消息缓存

static uint8\_t server_ip[4] = { 192, 168, 2, 78 }; // MQTT服务器IP
static uint16\_t server_port = 1883; // MQTT服务器端口


// MQTT消息接收回调函数。
void on\_mqtt\_message(MessageData \*md) {
memset(message_buffer, 0, MQTT_CLIENT_BUFFER_SIZE);
MQTTMessage \*msg = md->message;
printf("message received len = %d.\r\n", msg->payloadlen);
memcpy(message_buffer, (uint8\_t\*) msg->payload, msg->payloadlen);
printf("message:%s\r\n", message_buffer);
}

void mqtt\_client\_init(void) {
int ret;
// 初始化Network
NewNetwork(&network, MQTT_SOCKET);

// 连接MQTT服务器
ConnectNetwork(&network, server_ip, server_port);
MQTTClientInit(&client, &network, MQTT_TIMEOUT, tx_buffer,
MQTT_CLIENT_BUFFER_SIZE, rx_buffer, MQTT_CLIENT_BUFFER_SIZE);

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.willFlag = 0;
data.MQTTVersion = 3;
data.clientID.cstring = "stm32\_w5500";
data.username.cstring = "";
data.password.cstring = "";

data.keepAliveInterval = 60;
data.cleansession = 1;

// 建立MQTT连接
ret = MQTTConnect(&client, &data);
if (ret != SUCCESSS) {
printf("mqtt\_client\_init:mqtt connect failed(%d)\r\n", ret);
while (1)
;
}
printf("mqtt\_client\_init:connected\r\n");

// 订阅主题
ret = MQTTSubscribe(&client, "stm32\_iot/led\_ctr", QOS0, on_mqtt_message);
}

void mqtt\_client\_loop(void) {
MQTTMessage msg;
msg.qos = QOS0;
msg.retained = 0;
msg.dup = 0;
msg.payload = "{\"led\":\"0\",\"state\":\"on\"}";
msg.payloadlen = strlen((const char\*)msg.payload);
while (client.isconnected) {
MQTTPublish(&client, "stm32\_iot/led\_state", &msg);
HAL\_Delay(2000);
MQTTYield(&client, 60);
}
}
#endif


2、主程序

main.c文件中添加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/
#include <stdio.h>
#include "w5500\_port.h"
#include <string.h> // memcmp
#include "app\_config.h"
#ifdef MQTT\_DEMO
#include "mqtt\_client\_demo.h"
#endif
/\* USER CODE END Includes \*/

int main(void) {
/\* USER CODE BEGIN 1 \*/

/\* USER CODE END 1 \*/

/\* MCU Configuration--------------------------------------------------------\*/

/\* Reset of all peripherals, Initializes the Flash interface and the Systick. \*/
HAL\_Init();

/\* USER CODE BEGIN Init \*/

/\* USER CODE END Init \*/

/\* Configure the system clock \*/
SystemClock\_Config();

/\* USER CODE BEGIN SysInit \*/

/\* USER CODE END SysInit \*/

/\* Initialize all configured peripherals \*/
MX\_GPIO\_Init();
MX\_USART1\_UART\_Init();
MX\_SPI1\_Init();
/\* USER CODE BEGIN 2 \*/
printf("-----STM32 W5500 Ethernet Demo-----\r\n");
w5500\_restart(); // hardware restart through RESET pin
wiznet\_register();
w5500\_network\_init\_static();
wiznet\_chip\_config();


#ifdef MQTT\_DEMO
mqtt\_client\_init();
mqtt\_client\_loop();
#endif

/\* USER CODE END 2 \*/

/\* Infinite loop \*/
/\* USER CODE BEGIN WHILE \*/
while (1) {
/\* USER CODE END WHILE \*/
//loopback\_tcpc(0, (uint8\_t\*) recv\_buff, destip, destport);
/\* USER CODE BEGIN 3 \*/
}
/\* USER CODE END 3 \*/
}

其他MQTT订阅stm32_iot/led_state主题接收到的消息如下:

在这里插入图片描述

STM32接收到订阅stm32_iot/led_ctr主题的消息如下:

在这里插入图片描述

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/125957004