ESA2GJK1DH1K基礎篇: APP使用SmartConfig綁定Wi-Fi 設備並通過MQTT控制設備(V0.1)


 

 

前言

 

 

實現功能概要

   STM32控制WI-Fi模塊以AT指令TCP透傳方式連接MQTT服務器, 實現MQTT通信控制.

  

測試准備工作(詳細下載步驟請參考 硬件使用說明 )

一,下載單片機程序

  

  工程目錄: STM32F10xTemplate\Progect

  hex文件目錄: STM32F10xTemplate\Progect\Progect

    

      

二,安裝APP軟件

  

 

 

  

 

 

  

三,調整波動開關位置,STM32和Wi-Fi通信

  

 

 

 

 

四,

V2.4版本需要短接STM32的PB2和Wi-Fi模塊的RST引腳(為了做項目穩定可靠,請使用單片機硬件復位Wi-Fi)

V2.4版本需要短接STM32的PB2和Wi-Fi模塊的RST引腳

V2.4版本需要短接STM32的PB2和Wi-Fi模塊的RST引腳


  

V2.5.1版本內部默認PB2連接了Wi-Fi模塊的RST引腳,不需要短接

V2.5.1版本內部默認PB2連接了Wi-Fi模塊的RST引腳,不需要短接

V2.5.1版本內部默認PB2連接了Wi-Fi模塊的RST引腳,不需要短接

 

 

 

 

 

 

開始測試

一.打開手機APP,點擊右上角菜單 "添加設備" ,手動輸入自家路由器密碼.(路由器名稱為自動獲取,不需要用戶填寫)

             

 

 

 

 

二.長按PB5大約4S,等待指示燈快閃,松開PB5,Wi-Fi模塊進入配網狀態

  

 

 

 

 

三.點擊APP的搜索設備按鈕,開始搜索設備,搜索成功,將自動跳轉到主頁面,並顯示設備

      

 

 

 

 

四.單片機控制Wi-Fi連接上MQTT服務器以后,指示燈1S閃耀

 

  

 

 

 

 

 

 

 

五.點擊設備進入,設備控制頁面,頁面顯示當前溫濕度數據,顯示當前設備的狀態

  

 

 

 

六.遠程控制繼電器吸合

      

 

 

 

 

 

 

七.遠程控制繼電器斷開

      

 

 

 

 

 

 

八.請自行控制家電(最大支持10A,注意安全!)

 

 

 

 

關於程序

  整個程序是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

  

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地址很有用(全球唯一),通信的時候可以用來區分設備.

 

    

 

MQTT實現部分

  一,前言

    對於初學者而言,如果不了解MQTT,可先看后面的關於MQTT的教程,看會以后

    再來看此部分!

    MQTT處理,采用官方C語言MQTT包+本人二次封裝.(方便大家快速的移植使用)

 

    Wi-Fi模塊發布的主題: device/設備MAC  

    Wi-Fi模塊訂閱的主題: user/設備MAC

 

    APP通過SmartConfig獲取Wi-Fi的MAC,然后設置

    訂閱的主題:device/設備MAC  

    發布的主題:user/設備MAC

 

  二,連接TCP服務器(MQTT服務器)

    AT指令配置模塊連接TCP的程序處理模板是:配置AT指令模板(非阻塞版) 

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

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

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

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

    

    

   三,連接MQTT

    SendConfigFunction(NULL,FunctionParseConnectMqtt,NULL,NULL,FunctionParseConnectMqttAck,0);break;

    打包發送連接MQTT服務器是這個函數 FunctionParseConnectMqtt

      

      

 

      注:調用MqttConnectMqtt函數以后,最終打包完成后的數據存儲在 MqttSendData數組里面

      故:在最后的時候是調用  UsartOutStr(MqttSendData,MainLen);

  四,判斷是夠連接成功

    FunctionParseConnectMqttAck

    

 

 

    具體咱再后面說怎么判斷的,這個涉及到官方MQTT庫的數據處理方式

 

 

 

   五,訂閱主題

    SendConfigFunction(NULL,FunctionParseMqttSubscribe,NULL,NULL,FunctionParseMqttSubscribeAck,CompareValue);break;

    訂閱主題看這個函數 FunctionParseMqttSubscribe

      

      

 

 

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

 

      char SubTopic1[10]="aaaaa";

 

      char SubTopic2[10]="bbbbb";

 

 

 

      MQTTString MQTTStringSubTopic[2] = MQTTString_initializer;

 

      int MQTTStringSubTopicQos[2] = {0,1};

 

 

 

      MQTTStringSubTopic[0].cstring = SubTopic1;

 

      MQTTStringSubTopic[1].cstring = SubTopic2;

 

 

 

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

 

      UsartOutStr(MqttSendData,MainLen);

 

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

 

      

 

 

      

 

 

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

 

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

 

 

 

  六,發布消息

 

    6.1,定義發布的主題變量

 

      MQTTPublishTopicStruct MqttPublishTopicStruct = MQTTPublishTopicStruct_initializer;

 

      該變量在主函數中定義

      

    6.2,使用該變量

      

 

 

      

 

 

      打包數據函數  MqttPublish

      

 

 

 

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

      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接收的消息

    

 

 

    

 

 

     7.1 判斷MQTT返回的是什么數據都是調用 MQTTPacket_read函數做判斷

      

    7.2注意這個函數填入的第三個參數 (函數)

      

 

 

      

 

 

    7.3  官方提供的MQTT庫,所有的數據判斷處理都是利用該函數

 

      該函數的寫法固定

 

      

 

      注意:由於模塊配置了透傳模式,Wi-Fi接收的數據直接通過串口發給了單片機

 

        單片機接收的數據存在了  Usart1ReadBuff  數組里面

 

        上面的函數中 才會寫  memcpy(buf,&Usart1ReadBuff[MqttAnalyzeStruct.Len],count);

 

 

    7.4 

 

      if(MQTTPacket_read(MqttAnalyzeStruct.buff,MQTTAnalyzeBuffLen, transport_getdata) == XXXXX)

 

      實際上 MQTTPacket_read函數 就是利用 transport_getdata函數提取數據

 

      

 

 

      然后把提取的數據存在傳進來的 buff 里面

      如果想具體提取數據則

 

      

 

 

  八,心跳包

 

    8.1 實際上 客戶端發送的心跳包數據是  C0 00  服務器返回的是 D0 00

 

    8.2 但是對於沒有監聽過協議的用戶,可調用 MQTTSerialize_pingreq 獲取心跳包數據

 

      

 

 

      

 

 

 

APP程序

  APP目錄部分說明

    

 


免責聲明!

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



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