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.h和mqtt_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
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!