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