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还是没有收到心跳返回

    重新配置模块

  • 相关阅读:
    大厂Redis高并发场景设计,面试问的都在这!
    POJ1006——中国剩余定理
    HDU3501——欧拉函数裸题
    堆-动态的排序(洛谷1801-黑匣子)
    图中欧拉回路数量
    ip地址
    网络通信概述
    网络通信概述
    软件安装与卸载
    软件安装与卸载
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/11768916.html
Copyright © 2011-2022 走看看