前言
该程序需要的基础知识: https://www.cnblogs.com/yangfengwu/category/1566194.html 所有源码开源,请自行学习
这节代码将在这一节的基础上实现
拷贝第一节测试里面的MQTT文件夹到当前工程
当前工程建个MQTT的文件夹,用于存放那个MQTT文件夹里面的内容
添加文件到里面
添加头文件到 include.h
设置一下头文件路径
注意,如果不是用的我的工程底板,会报错一个地方,自己去定义一个数组去数组大小先设置200吧,放到这里,
这个数组是存放服务器发过来的数据.
具体看我后面的介绍.
控制模块TCP连接上MQTT
注意,我是AT指令通过串口控制GPRS连接的TCP服务器(MQTT软件)
大家如果用的其它不是通过串口控制连接的,请自己写控制模块连接TCP的函数
代码语言:javascript复制 case 0://关闭移动场景,彻底关闭TCP/IP 连接
SendConfigFunction("AT CIPSHUTrn",NULL,"SHUT OK",NULL,FunctionParseCompare,CompareValue);break;
case 1://读取SIM状态正常
SendConfigFunction("AT CPIN?rn",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 2://GPRS注册状态
SendConfigFunction("AT CGREG?rn",NULL," CGREG: 0,1",NULL,FunctionParseCompare,CompareValue);break;
case 3://是否附着了GPRS
SendConfigFunction("AT CGATT?rn",NULL," CGATT: 1",NULL,FunctionParseCompare,CompareValue);break;
case 4://设置为单链接
SendConfigFunction("AT CIPMUX=0rn",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 5://透传模式
SendConfigFunction("AT CIPMODE=1rn",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 6://设置APN
SendConfigFunction("AT CSTTrn",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 7://激活移动场景
SendConfigFunction("AT CIICRrn",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 8://连接TCP 服务器
SendConfigFunction("AT CIPSTART="TCP","47.92.31.46",1883rn",NULL,"CONNECT",NULL,FunctionParseCompare,CompareValue);break;
无论如何你必须先用TCP连接上TCP服务器(MQTT软件),然后说注意的地方
一,先说明
我设置的模块是透传模式,我和GPRS的连接是通过串口
我单片机往串口发数据,串口数据发给了GPRS,GPRS就会自动发给TCP服务器
TCP服务器发给GPRS数据,GPRS就会把数据发到自己的串口,然后就发给单片机了
他们之间的数据不夹杂着乱七八糟的东西,发的什么就是什么.
我的数据全部存到了
现在发送连接MQTT协议
一,调用MqttConnectMqtt函数,我注释已经写的很明白了哈...
二,我为了更形象一点,我只用我的底层架子控制模块连接上TCP服务器
大家根据自己的模块连接上TCP服务器
三,然后主函数里面把打包的数据发给TCP服务器(我刚才说了,我串口发送的数据GPRS会自动转发给TCP服务器)
大家根据自己的修改,找到自己TCP发送数据的地方,把数据发出去
四,判断是否连接上了
MqttConnectMqttAck
该函数没有参数,所有的数据是靠 transport_getdata 这个函数提供
先看一下里面的这个函数MQTTPacket_read 这个函数就是处理MQTT数据的
他把从transport_getdata函数里面提取的数据,拷贝到了 MqttAnalyzeStruct.buff 数组里面了
最后面的== XXXX是判断这个数据是什么类型的数据 CONNACK 就是说是接收的连接成功的应答数据
实质上就是传递函数指针而已,如果你C语言不好,你就先别深究,先学会用
然后看transport_getdata函数, 这个函数是整个MQTT包里面的重点
一,这个函数是固定写法 ,
二,所有的MQTT解析数据都是利用这个函数,
你所做的事情就是,把TCP服务器传过来的数据缓存到一个数组,然后把数组名字放到那里
我设置的我的模块是串口透传
我的数据全部缓存到了Usart1ReadBuff数组,所以我上面才那样写的
所以我直接可以
三,如果你的模块接收的数据缓存到别的数组了,但是数据有各种乱七八糟的数据
那么你需要先剔除
你可以先定义一个数组
然后
连接上以后,订阅主题
一,订阅一个主题
二,订阅两个主题
三,看一下订阅主题的封包的那个函数
判断是否成功订阅了主题
一,调用 MqttSubscribeAck函数判断
二,程序里面就是
三,然后呢咱发送一条消息
现在呢我测试下,
注意哈,实际上没有什么难的,
第一:先连接TCP
第二: 调用连接MQTT的封包函数,封装好连接的数据,然后把数据用TCP发出去
第三: 判断服务器返回的是不是连接成功
第四: 连接以后就可以订阅主题了,其实什么时候都可以订阅,随意
第五 根据服务器返回的数据,判断下是不是订阅成功了
主要是大家一定要把自己接受的数据传到这里
解析接收的MQTT数据
把接收的数据返回回去
然后稍微动了下
最后一个心跳包
你设置的心跳包多少时间,你就多少时间发送一次心跳包!完了没有了
结语
你脑海里面永远记得,先连接TCP 服务器
必须把TCP服务器返回的数据写到那个数组里面
然后就是连接,判断,订阅判断,发送数据,解析数据啦.最后定时发个心跳包.仅此而已
注意:注意:注意:注意:注意:注意:
我给大家提供的都是网络模块串口透传的代码(8266,Air202,SIM800),后面我会提供个W5500的,不过是用另一块板子