zoukankan      html  css  js  c++  java
  • ESA2GJK1DH1K基础篇: APP使用SmartConfig绑定Wi-Fi 设备并通过MQTT控制设备(V0.1)

    前言

    实现功能概要

       STM32控制WI-Fi模块以AT指令TCP透传方式连接MQTT服务器, 实现MQTT通信控制.

      

    测试准备工作(详细下载步骤请参考 硬件使用说明 )

    一,下载单片机程序

      

      工程目录: STM32F10xTemplateProgect

      hex文件目录: STM32F10xTemplateProgectProgect

        

          

    二,安装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    

        最后的参数 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" ",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目录部分说明

        

  • 相关阅读:
    NEFU84——五指山(Exgcd)
    Scoi2010——传送带(三分套三分=九分)
    POJ3352Road construction(边双联通分量)
    CEOI2005——关键网线(割边)
    ZJOI2004——嗅探器
    POJ1845s——Sumdiv()
    Web 服务器安全
    渗透测试神器Cobalt Strike的使用
    Windows中的用户和组以及用户密码处理
    漏洞及渗透练习平台 【大全】
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/11760590.html
Copyright © 2011-2022 走看看