111-STM32+ESP8266+AIR202基本控制篇-移植單片機MQTT包,實現stm32+esp8266連接MQTT服務器(透傳和非透傳模式下都有)


<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_A/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

 

說明

此節適用於所有支持TCP通信的模組!

 

准備一份程序(先看透傳版)

透傳版就是配置好模組以后直接發送數據給模組,模組就把信息直接轉發到網絡

模組從網絡接收到數據就直接輸出.

 

1.准備一份已經實現TCP通信的程序

 

 

2.TCP連接

注:因為是WiFi模塊,所以需要連接路由器(連接的路由器名稱和密碼根據自己的修改)

連接的IP地址是MQTT服務器的地址

 

 

連接TCP以后模塊進入透傳模式

 

 

 

2.我把網絡接收的數據緩存到了環形隊列

 

 

 

 

 

開始移植

1.把這節里面的mem和MQTT文件夾拷貝到工程目錄

注:我提供的STM32F10xTemplate工程里面已經有了mem,可不用拷貝

 

 

2.把mem和MQTT添加到工程

 

 

3.寫上下面的程序

注:MQTT信息根據自己的修改

 

 

 

 

 

 

 

 

 

 

 

 

#include "mqtt.h"

char mqtt_connect_flag=0;//1:Á¬½ÓÉÏMQTT·þÎñÆ÷; 0:δÁ¬½ÓÉÏMQTT·þÎñÆ÷
char mqtt_id[50] = "11223344";//ClientID
char mqtt_username[20] = "yang";//Óû§Ãû
char mqtt_password[50] = "11223344";//ÃÜÂë
char mqtt_keepalive = 30;//ÐÄÌø°üʱ¼ä
unsigned char mqtt_publish_topic[30]="";//´æ´¢MQTT·¢²¼µÄÖ÷Ìâ
unsigned char mqtt_subscribe_topic[30]="";//´æ´¢MQTT¶©ÔĵÄÖ÷Ìâ


/**¶©ÔÄÖ÷Ìâ³É¹¦**/
void subscribedCb(int pdata){
    printf("\r\n³É¹¦¶©ÔÄÖ÷Ìâ\r\n");
}
/**¶©ÔÄÖ÷Ìâʧ°Ü**/
void failsubscribedCb(int pdata){
    printf("\r\n¶©ÔÄÖ÷Ìâʧ°Ü\r\n");
}
/**·¢²¼³É¹¦**/
void PublishedCb(){
    printf("\r\n·¢²¼³É¹¦\r\n");
}

/*Á¬½ÓÉÏMQTT»Øµ÷º¯Êý*/
void MqttConnect(){
    printf("\r\nÁ¬½Ó³É¹¦**********************************************************\r\n");
    mqtt_connect_flag = 1;
}
/**MQTT¶Ï¿ªÁ¬½Ó»Øµ÷**/
void MqttDisConnect(){
    printf("\r\nÁ¬½Ó¶Ï¿ª**********************************************************\r\n");
    mqtt_init(&mymqtt);
    mqtt_connect_flag=0;
}
/**
* @brief   MQTT½ÓÊÕÊý¾Ý»Øµ÷
* @param   topic:Ö÷Ìâ
* @param   topic_len:Ö÷Ìⳤ¶È
* @param   data:½ÓÊÕµÄÊý¾Ý
* @param   lengh:½ÓÊÕµÄÊý¾Ý³¤¶È
* @retval  None
* @warning None
* @example
**/
void MqttReceive(const char* topic, uint32_t topic_len,const char *data, uint32_t lengh)
{    
}


void MqttConnect(void);//Á¬½ÓÉÏMQTT»Øµ÷
void MqttDisConnect(void);//MQTT¶Ï¿ªÁ¬½Ó»Øµ÷
void subscribedCb(int pdata);//¶©Ôijɹ¦»Øµ÷
void failsubscribedCb(int pdata);//¶©ÔÄʧ°Ü»Øµ÷
void PublishedCb(void);//³É¹¦·¢²¼ÏûÏ¢»Øµ÷
void MqttReceive(const char* topic, uint32_t topic_len,const char *data, uint32_t lengh);//½ÓÊÕµ½Êý¾Ý»Øµ÷

    mqtt_init(&mymqtt);
    mqtt_connect_reg(&mymqtt,MqttConnect);//×¢²áÁ¬½Ó»Øµ÷º¯Êý
    mqtt_disconnect_reg(&mymqtt,MqttDisConnect);//×¢²á¶Ï¿ªÁ¬½Ó»Øµ÷º¯Êý
    mqtt_received_reg(&mymqtt,MqttReceive);//×¢²á½ÓÊÕÊý¾Ý»Øµ÷º¯Êý

 

 

//Á¬½ÓÉÏMQTT·þÎñÆ÷
        if(mqtt_connect_flag)
        {
            mqtt_send_function(&mymqtt);//ÌáÈ¡·¢ËÍ»º´æµÄMQTTЭÒé
            mqtt_keep_alive(&mymqtt);//´¦Àí·¢ËÍÐÄÌø°ü
        }

 

4.把mqtt_time_data(&mymqtt); 放到1ms定時器里面

 

 

 

5.在mqtt.c里面替換自己的tcp發送數據函數

注:我的單片機是通過串口2和模組通信

 

 

關於下面的 mymqtt.timer_out_send = 0; 這個是預防有的模塊發送數據之后需要等待,按照提示修改就可以

wifi模塊透傳模式下每條數據的時間間隔需要保持在20ms以上,所以我直接設置的20

 

 

 

6.編寫組合發送連接MQTT協議函數

 

 

 

7.連接上TCP服務器以后每隔一段時間發送MQTT連接協議給服務器

 

 

8.把模組接收的網絡數據交給mqtt處理函數處理

注:在未連接上mqtt服務器交給  mqtt_function_connect_ack函數(該函數判斷連接成功會調用注冊的mqtt連接成功回調)

注:在連接上mqtt服務器交給  mqtt_read_function 函數

 

 

9.把代碼下載測試

 

 

10.斷線重連

典型處理方式:在TCP斷開的時候需要重新連接TCP,然后再連接MQTT

在MQTT斷開的時候讓模組也重新連接TCP.

 

現在wifi模組是透傳模式,模組不會返回tcp斷開的信息了,所以就只在mqtt斷開連接回調里面重新讓tcp連接

 

 

 

 

11.訂閱主題和發布消息

 

 

 

12.提示

只要是連接上MQTT服務器了,可以在任意地方調用訂閱和發布函數.

打包的信息都緩存到了內部的緩存管理里面,緩存管理使用的是我在環形隊列基礎上封裝的 BufferManage

 

 

 

13.如果自己的MQTT數據包超過500不超過16383字節,則只需要修改數據緩存大小

mqtt_send_buff_len是每個數據包的長度(假設自己的數據包最大是800,則可以設置為802)

send_buff_loop_len 是保存每個數據包數組的長度(一般設置為mqtt_send_buff_len的整數倍)

 

 

14.如果自己的MQTT數據包超過16383字節,則還需要修改底層

當前是使用兩字節保存數據個數

 

 

 

 

 

 

15.接收數據,如果內存充足,推薦的處理方式

 

 

 

現在看非透傳版

透傳版和非透傳版只是發送和接收數據的方式不一樣,所以就在透傳版的基礎上修改

 

1.首先模塊資料

 

 

 

 

 

 

 

2.TCP連接改為非透傳多鏈接模式(使用的socket 0 進行的連接)

 

 

3.改一下接收數據的地方,咱使用另外一個緩存只存儲網絡數據

 

 

 

 

 

 

 

 

 

 

3.改一下發送連接協議的方式

 

 

 

4.串口接收處理數據改一下

上面只處理連接上MQTT服務器前和連接中出現的問題

下面是把網絡數據交給MQTT處理函數處理

 

 

5.現在應該可以連接上MQTT服務器了

 

 

6.接着修改這里面

這里也需要改為先發送 AT+CIPSEND 然后再發送真實數據

發送真實數據咱在透傳的時候以后寫了.

我這個底層其實也是支持非透傳的.

 

 

 

7.設置為非透傳模式

 

 

8.編寫發送數據命令函數

 

 

8.根據下面的提示修改 >

 

 

9.現在已經可以了

 

 

 

結語

代碼不是重要的,重要的是處理思想和方案.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM