ESA2GJK1DH1K基礎篇: APP使用SmartConfig綁定Wi-Fi 設備並通過MQTT控制設備-單片機源碼說明


 

前言

注:

本程序發送心跳包,發送溫濕度,返回控制數據這三個發送是單獨的,有可能湊到一起發.

由於本身程序就是復雜性的程序,所以這節程序沒有使用中斷發送,沒有使用環形隊列發送,為了避免多條消息可能湊到一起發

 

如果嫌棄這個延時請自行優化,或者采用自己的方式解決,謝謝支持!

抱歉哈!我首先期望的是大部分人都先要看懂程序,至於其他優化我會提供個思路和源碼,大家可以根據自己的情況自行優化.

 

 

 

用戶須知

整個程序是STM32使用AT指令控制Wi-Fi模塊實現SmartConfig配網和MQTT通信控制

  

  程序的整體結構:   https://www.cnblogs.com/yangfengwu/p/11669323.html

  程序的按鍵處理:   https://www.cnblogs.com/yangfengwu/p/11669354.html

  串口接收數據   :    https://www.cnblogs.com/yangfengwu/p/11669373.html

  配置AT指令模板(阻塞版):  https://www.cnblogs.com/yangfengwu/p/11673439.html

  配置AT指令模板(非阻塞版): https://www.cnblogs.com/yangfengwu/p/11674814.html

 

打開這節源碼

 

修改連接自己的服務器

  一,如果想連接自己的MQTT服務器,可以直接更改

    

 

 

 

SmartConfig配網

  一,主循環

    

  二,AT指令配置模塊啟動SmartConfig的程序處理模板是:配置AT指令模板(阻塞版) 

 

  三,按鍵按下3S以后 變量 SmartConfigFlage = 1;

    

 

    定時器里面開始控制 指示燈100Ms閃耀

    

 

  四,AT指令控制Wi-Fi模塊執行SmartConfig 配網程序部分

    

 

    

 

  五,SmartConfig執行流程-連接路由器

    

 

    

 

    實際上啟用SmartConfig指令是   AT+CWSTARTSMART=3\r\n    

 

    最后的參數 1-SmartConfig配網    2-微信Airkiss配網    3-SmartConfig配網+微信Airkiss配網

 

    下面進入了 while(1) 循環    我設置的30S超時

 

    實際上此時Wi-Fi模塊正在監聽APP在空氣中發出的無線信號

 

    下圖只要執行了搜索設備,APP就在不停的發出無線信號

 

 

 

        

 

 

 

    Wi-Fi模塊接收到APP發出的路由器信息以后,就會根據信息去連接路由器

 

    Wi-Fi模塊連接上了路由器以后便會返回  WIFI CONNECTED  和  WIFI GOT IP

 

    注:只要配網一次,以后Wi-Fi模塊便會自動連接此路由器,不需要重復配網!

 

 

 

  六,SmartConfig執行流程-等待路由器把自己的MAC信息返回給APP

 

 

 

        

 

 

 

 

 

    為了讓APP確定Wi-Fi模塊確實連接上了路由器,Wi-Fi連接上路由器以后

 

    需要返回給APP自己的MAC地址和自己連接路由器后分得的IP地址

 

    所以延時了5S時間,讓Wi-Fi模塊把信息發給APP

 

    下圖中,顯示的就是所配網的Wi-Fi模塊的MAC地址信息

 

    當然MAC地址很有用(全球唯一),通信的時候可以用來區分設備.

 

 

 

        

 

 

 

 

 

 

控制Wi-Fi模塊連接TCP服務器

 

    配置Wi-Fi模塊連接TCP服務器是使用的  "AT+SAVETRANSLINK=1,\"%s\",%s,\"TCP\"\r\n",IP,Port

 

    這個指令配置好以后,Wi-Fi模塊便是透傳模式,而且是自動連接

 

    (串口接收的數據,自動發給TCP服務器)

 

    (從TCP服務器接收的數據自動發給串口)

 

 

 

 

MQTT服務器規定ClientID必須每個設備不能一樣,Wi-Fi模塊的MAC作為了ClientID

獲取ClientID部分

 

 

 

 

 

 

 

 ClientID 最終存儲在了 MQTTid數組里面

 

發送連接MQTT協議

 

 

 

 

 

 

判斷連接狀態

 

 

 

 

 

 

 

 官方庫里面判斷返回的數據都是使用

MQTTPacket_read(數據解析完存到的數組,數組長度,提取數據函數)

最主要的是這個 提取數據函數

transport_getdata

 

 

 

 

這個函數的格式不能變,官方規定的就是這個格式

 

因為我的模塊是串口透傳模式,所以MQTT服務器返回的數據都返回到了串口數組里面

 

Usart1ReadBuff

 

 

 

假設我現在判斷接收的數據類型,(MQTT協議里面第一個返回的數據就能判斷出來數據類型)

 

MqttAnalyzeStruct.Len=0;

 

transport_getdata(buff,1);

 

 

 

這樣執行以后 我就把第一個數據 拷貝到了 buff里面

 

 

 

 

 

 

 

 

然后我只需要判斷buff數組第一個數據就可以了

其實官方就是這樣做的

 

 

 

提取其它數據

 

 

 

 

接着看訂閱

 

 

 

 

 

 

  

 

 

      此函數一次性可以訂閱多個主題,列如訂閱兩個主題

      char SubTopic1[10]="aaaaa";

      char SubTopic2[10]="bbbbb";

 

      MQTTString MQTTStringSubTopic[2] = MQTTString_initializer;

      int MQTTStringSubTopicQos[2] = {0,1};//第一個主題的消息等級0,第二個消息等級1

 

      MQTTStringSubTopic[0].cstring = SubTopic1;

 

      MQTTStringSubTopic[1].cstring = SubTopic2;

 

      MainLen = MqttSubscribe(MQTTStringSubTopic,MQTTStringSubTopicQos,2,0,1);

      UsartOutStr(MqttSendData,MainLen);

 

      注:我設置的一次性最多訂閱3個主題

 

      

 

 

      

 

 

      定義的主題個數大於了此變量,用戶需要增大此變量

      實際訂閱的主題個數 <= MaxSubTopicCount

 

 

判斷訂閱是否成功

 

 

 

 

 

 

 

 

發送一條上線消息

 

一,定義發布的主題變量

 

      MQTTPublishTopicStruct MqttPublishTopicStruct = MQTTPublishTopicStruct_initializer;

 

      該變量在主函數中定義

      

    二, 使用該變量

      

 

 

      

 

 

      打包數據函數  MqttPublish

      

 

 

 

     三,,定義多個發布的主題變量

      char Publish1[10]="qqqqq";//發布的主題

      char Publish1Msg[8]="11223344";//發布的主題,攜帶的消息

 

      char Publish2[10]="wwww";//發布的主題

      char Publish2Msg[6]="000000";//發布的主題,攜帶的消息

 

      MQTTPublishTopicStruct MqttPublishTopicStruct1 = MQTTPublishTopicStruct_initializer;

      MQTTPublishTopicStruct MqttPublishTopicStruct2 = MQTTPublishTopicStruct_initializer;

 

      MqttPublishTopicStruct1.topicName.cstring = Publish1;// 發布的主題

      MainLen = MqttPublish(MqttPublishTopicStruct1,Publish1Msg,8);

      UsartOutStr(MqttSendData,MainLen);//發送消息

 

      MqttPublishTopicStruct1.topicName.cstring = Publish2;// 發布的主題

      MainLen = MqttPublish(MqttPublishTopicStruct2,Publish2Msg,6);

      UsartOutStr(MqttSendData,MainLen);//發送消息

 

連接好MQTT,訂閱完主題,然后就是處理MQTT數據

 

 

 

 

 

 

 

三,每隔一段時間采集發送溫濕度數據

 

 

 

看下我的心跳包處理

 

 

 

 

 

 

 

 

 

 

 

說下我的處理思路

首先,如果到了發送心跳包的時間了,就發送一次心跳包

然后啟動超時,超過3S如果服務器沒有回復心跳應答

我就再發送一次,然后啟動超時,如果超過3S還是沒有收到心跳返回

重新配置模塊

 


免責聲明!

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



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