zoukankan      html  css  js  c++  java
  • 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    

        最后的参数 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" ",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还是没有收到心跳返回

    重新配置模块

  • 相关阅读:
    Unique Binary Search Trees 解答
    Unique Paths II 解答
    Unique Paths 解答
    Maximum Subarray 解答
    Climbing Stairs 解答
    House Robber II 解答
    House Robber 解答
    Valid Palindrome 解答
    Container With Most Water 解答
    Remove Duplicates from Sorted List II 解答
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/11768916.html
Copyright © 2011-2022 走看看