天天看點

MQTT協定在物聯網環境中的應用及代碼實作解析(四)

作者:北京老白
MQTT協定在物聯網環境中的應用及代碼實作解析(四)

四、使用單片機環境程式設計接收MQTT伺服器上特定主題的資訊

以下是使用STM32F103單片機連結W5500晶片連結到網絡上,利用MQTT協定接收MQTT伺服器“mqtt.laobai.net”上的“laobai_topic001”主題上的訂閱資訊,并發送給序列槽的C語言代碼示例,包括完整的代碼注釋和程式設計說明:

#include "stm32f10x.h"
#include "w5500.h"
#include "mqtt.h"
#include "usart.h"

// 定義W5500的IP、端口等詳細資訊
#define W5500_IP        "192.168.1.100"   // W5500的IP位址
#define W5500_GW        "192.168.1.1"     // 網關的IP位址
#define W5500_SUBNET    "255.255.255.0"   // 子網路遮罩
#define W5500_DNS       "8.8.8.8"         // DNS伺服器的IP位址
#define W5500_MAC       {0x00, 0x08, 0xDC, 0x01, 0x02, 0x03}   // W5500的MAC位址
#define W5500_PORT      5000              // W5500的端口号

// 定義MQTT伺服器的詳細資訊
#define MQTT_SERVER     "mqtt.laobai.net"  // MQTT伺服器位址
#define MQTT_PORT       1883               // MQTT伺服器端口号

// 定義要接收的主題
#define MQTT_TOPIC      "laobai_topic001"  // MQTT主題

// 初始化W5500晶片
void W5500_Init(void) {
    uint8_t mac[6] = W5500_MAC;
    uint8_t ip[4] = {0};
    uint8_t gw[4] = W5500_GW;
    uint8_t sn[4] = W5500_SUBNET;
    uint8_t dns[4] = W5500_DNS;

    // 初始化W5500晶片
    W5500_InitSPI();     // 初始化SPI接口
    W5500_InitGPIO();    // 初始化GPIO
    W5500_InitPHY();     // 初始化PHY
    W5500_InitCommonReg(mac, ip, gw, sn, dns);   // 初始化W5500的正常寄存器
}

// 處理接收到的MQTT消息
void MQTT_HandleReceivedMessage(MqttMessageReceivedEventArgs* args) {
    // 将消息發送到序列槽
    USART_Puts(args->topic);
    USART_Puts(": ");
    USART_Puts(args->message);
    USART_Putc('\n');
}

int main(void) {
    // 初始化W5500晶片
    W5500_Init();
    
    // 初始化序列槽
    USART_Init();
    
    // 建立MQTT用戶端
    MqttClient mqttClient;
    
    // 配置MQTT用戶端選項
    MqttClientOptions options;
    options.clientId = "client1";           // 設定MQTT用戶端ID
    options.serverIp = MQTT_SERVER;         // 設定MQTT伺服器位址
    options.serverPort = MQTT_PORT;         // 設定MQTT伺服器端口号
    options.username = "username";          // 設定MQTT伺服器的使用者名(如果需要)
    options.password = "password";          // 設定MQTT伺服器的密碼(如果需要)
    options.keepAliveInterval = 60;         // 設定心跳間隔時間(機關:秒)
    options.cleanSession = true;            // 設定是否清除會話狀态
    
    // 連接配接到MQTT伺服器
    MqttError connectResult = MQTT_Connect(&mqttClient, &options);
    
    if (connectResult == MQTT_ERROR_NONE) {
        // 訂閱主題
        MqttError subscribeResult = MQTT_Subscribe(&mqttClient, MQTT_TOPIC);
        
        if (subscribeResult == MQTT_ERROR_NONE) {
            // 設定消息接收的回調函數
            MQTT_SetMessageReceivedCallback(&mqttClient, MQTT_HandleReceivedMessage);
            
            while(1) {
                // 處理MQTT消息的接收和發送
                MQTT_Process(&mqttClient);
            }
        }
    }
    
    while(1);
}
           
MQTT協定在物聯網環境中的應用及代碼實作解析(四)

上述代碼中,使用了名為"W5500"的庫來操作W5500晶片,"mqtt"庫來實作MQTT協定。

首先,在W5500_Init函數中,根據具體的網絡設定,初始化了W5500晶片的IP、MAC位址、網關、子網路遮罩和DNS伺服器等參數。

然後,在主函數中,先初始化W5500晶片,然後通過調用USART_Init函數初始化序列槽。

接下來,建立了一個MQTT用戶端執行個體,并配置了MQTT用戶端選項,包括設定MQTT伺服器的位址、端口、使用者名和密碼(如果需要),以及用戶端ID等。

然後,通過調用MQTT_Connect函數連接配接到MQTT伺服器,并進行訂閱主題的操作。如果連接配接和訂閱成功,就設定消息接收的回調函數,并進入一個無限循環中,通過調用MQTT_Process函數來處理MQTT消息的接收和發送。

在MQTT_HandleReceivedMessage函數中,将接收到的MQTT消息發送到序列槽。

請注意,上述代碼僅為示例,具體的實作可能需要根據實際情況進行調整和修改。此外,還需要根據具體的硬體平台和開發環境,包括使用的開發闆、編譯器等進行适配和配置。在代碼中,需要根據實際情況實作W5500_InitSPI、W5500_InitGPIO、W5500_InitPHY、W5500_InitCommonReg、USART_Init、USART_Puts和USART_Putc等函數,以便初始化W5500晶片和序列槽,并進行資料的發送和接收。同時,還需要在項目中添加對"W5500"庫和"mqtt"庫的引用,以便使用相應的函數和資料結構。

繼續閱讀