<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ZLCH579M/ESP8266/my.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
这节说明一下详细的编写程序实现CH579M+ESP8266(WiFi)连接MQTT服务器程序;
这一节可以移植各个单片机搭配各种串口通信模组上.还是那句话:代码不仅是给别人看的,更是给别人用的;
大家伙一定要始终记住一件事情,MQTT服务器就是个TCP服务器.
和MQTT服务器通信实质上就是TCP通信,只不过数据格式要按照MQTT规定.
大家伙要先准备好已经实现控制模组实现TCP通信的程序
我准备了一份程序
先来看移植过程
1.首先打开程序
配置下连接的路由器信息(根据自己的路由器修改)
我是使用的我封装的ConfigModuleNoBlock框架控制的模组连接TCP服务器
配置的模组是透传模式(模组串口接收的数据直接转发到TCP服务器, 模组从TCP服务器接收的数据直接通过串口输出)
模组返回的数据存储到了环形队列里面,使用的内部空闲中断判断的接收到一条完整的数据
主函数中获取数据的地方
2.把mem和mqtt文件夹放到自己的工程
我提供的工程里面已经有了mem.
3.把mqtt_time_data(&mymqtt);放到1ms定时器里面运行
3.编译工程,找到以下错误
4.这个地方写上把数据发送给TCP服务器的函数
我是使用的串口0和模组通信,而且还是透传模式;所以我就直接使用串口0发送数据就可以
这个地方其实是把缓存里面MQTT打包好的协议数据发给服务器.
关于下面的 mymqtt.timer_out_send = 0; 这个是预防有的模块发送数据之后需要等待,按照提示修改就可以
GSM模块透传模式下每条数据的时间间隔需要保持在20ms以上,所以我直接设置的20
5.配置MQTT参数变量,设置回调函数
#include "mqtt.h" /*MQTT*/ char mqtt_connect_flag=0;//1:Á¬½ÓÉÏMQTT·þÎñÆ÷; 0:δÁ¬½ÓÉÏMQTT·þÎñÆ÷ char mqtt_client_id[50] = "11223344";//ClientID char mqtt_username[20] = "yang";//Óû§Ãû char mqtt_password[50] = "11223344";//ÃÜÂë char mqtt_keepalive = 30;//ÐÄÌø°üʱ¼ä /**¶©ÔÄÖ÷Ìâ³É¹¦**/ void subscribedCb(int pdata){ printf(" ³É¹¦¶©ÔÄÖ÷Ìâ "); } /**¶©ÔÄÖ÷Ìâʧ°Ü**/ void failsubscribedCb(int pdata){ printf(" ¶©ÔÄÖ÷Ìâʧ°Ü "); } /**·¢²¼³É¹¦**/ void PublishedCb(){ printf(" ·¢²¼³É¹¦ "); } /*Á¬½ÓÉÏMQTT»Øµ÷º¯Êý*/ void MqttConnect(){ printf(" Á¬½Ó³É¹¦********************************************************** "); mqtt_connect_flag = 1; } /**MQTT¶Ï¿ªÁ¬½Ó»Øµ÷**/ void MqttDisConnect(){ printf(" Á¬½Ó¶Ï¿ª********************************************************** "); mqtt_init(&mymqtt); mqtt_connect_flag=0; } /** * @brief MQTT½ÓÊÕÊý¾Ý»Øµ÷ * @param topic:Ö÷Ìâ * @param topic_len:Ö÷Ìⳤ¶È * @param data:½ÓÊÕµÄÊý¾Ý * @param lengh:½ÓÊÕµÄÊý¾Ý³¤¶È * @retval None * @warning None * @example **/ void MqttReceive(const char* topic, uint32_t topic_len,const char *data, uint32_t lengh) { } /*MQTT*/ mqtt_init(&mymqtt); mqtt_connect_reg(&mymqtt,MqttConnect);//×¢²áÁ¬½Ó»Øµ÷º¯Êý mqtt_disconnect_reg(&mymqtt,MqttDisConnect);//×¢²á¶Ï¿ªÁ¬½Ó»Øµ÷º¯Êý mqtt_received_reg(&mymqtt,MqttReceive);//×¢²á½ÓÊÕÊý¾Ý»Øµ÷º¯Êý
6.在主循环里写上
//Á¬½ÓÉÏMQTT·þÎñÆ÷ if(mqtt_connect_flag) { mqtt_send_function(&mymqtt);//ÌáÈ¡·¢ËÍ»º´æµÄMQTTÐÒé mqtt_keep_alive(&mymqtt);//´¦Àí·¢ËÍÐÄÌø°ü }
7.在主循环里写上轮训发送MQTT连接协议程序
连接上TCP但是没有连接上MQTT,每隔一段时间发送一次连接协议
关于各个参数函数
8.在处理串口接收的数据里面加上处理MQTT连接消息
提示:判断上是连接消息之后,内部会调用mqtt连接回调函数
9.下载程序到开发板测试
10.保证可靠的断线重连
如果发送了几次连接协议还是没有连接上,让单片机重新控制模组连接TCP
/*³¬¹ýÁ¬½Ó´ÎÊý,ÖØÐÂÅäÖÃÄ£×éÁ¬½ÓTCP*/ mqtt_connect_cnt++; if(mqtt_connect_cnt>3) { mqtt_connect_cnt=0; mqtt_connect_flag=0; /*ÖØÐÂÅäÖÃÄ£¿éÁ¬½ÓTCP*/ ConfigModuleNoBlockCaseValue=0; ConfigModuleNoBlockFlage = 0; }
检测到TCP断开以后控制模块重新连接TCP服务器
11.加上解析处理MQTT接收的数据程序
12.订阅主题
只要是连接上MQTT服务器了,从哪里调用订阅函数都可以.一般是在连接回调里面调用;
假设订阅主题为topic