• 111-STM32+ESP8266+AIR202基本控制篇-移植单片机MQTT包,实现stm32+esp8266连接MQTT服务器(透传和非透传模式下都有)


    <p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_A/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

    说明

    此节适用于所有支持TCP通信的模组!

    准备一份程序(先看透传版)

    透传版就是配置好模组以后直接发送数据给模组,模组就把信息直接转发到网络

    模组从网络接收到数据就直接输出.

    1.准备一份已经实现TCP通信的程序

    2.TCP连接

    注:因为是WiFi模块,所以需要连接路由器(连接的路由器名称和密码根据自己的修改)

    连接的IP地址是MQTT服务器的地址

    连接TCP以后模块进入透传模式

    2.我把网络接收的数据缓存到了环形队列

     

    开始移植

    1.把这节里面的mem和MQTT文件夹拷贝到工程目录

    注:我提供的STM32F10xTemplate工程里面已经有了mem,可不用拷贝

    2.把mem和MQTT添加到工程

    3.写上下面的程序

    注:MQTT信息根据自己的修改

     

    #include "mqtt.h"
    
    char mqtt_connect_flag=0;//1:Á¬½ÓÉÏMQTT·þÎñÆ÷; 0:δÁ¬½ÓÉÏMQTT·þÎñÆ÷
    char mqtt_id[50] = "11223344";//ClientID
    char mqtt_username[20] = "yang";//̞
    char mqtt_password[50] = "11223344";//ÃÜÂë
    char mqtt_keepalive = 30;//ÐÄÌø°üʱ¼ä
    unsigned char mqtt_publish_topic[30]="";//´æ´¢MQTT·¢²¼µÄÖ÷Ìâ
    unsigned char mqtt_subscribe_topic[30]="";//´æ´¢MQTT¶©ÔĵÄÖ÷Ìâ
    
    
    /**¶©ÔÄÖ÷Ìâ³É¹¦**/
    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)
    {    
    }
    
    
    void MqttConnect(void);//Á¬½ÓÉÏMQTT»Øµ÷
    void MqttDisConnect(void);//MQTT¶Ï¿ªÁ¬½Ó»Øµ÷
    void subscribedCb(int pdata);//¶©Ôijɹ¦»Øµ÷
    void failsubscribedCb(int pdata);//¶©ÔÄʧ°Ü»Øµ÷
    void PublishedCb(void);//³É¹¦·¢²¼ÏûÏ¢»Øµ÷
    void MqttReceive(const char* topic, uint32_t topic_len,const char *data, uint32_t lengh);//½ÓÊÕµ½Êý¾Ý»Øµ÷
    
        mqtt_init(&mymqtt);
        mqtt_connect_reg(&mymqtt,MqttConnect);//×¢²áÁ¬½Ó»Øµ÷º¯Êý
        mqtt_disconnect_reg(&mymqtt,MqttDisConnect);//×¢²á¶Ï¿ªÁ¬½Ó»Øµ÷º¯Êý
        mqtt_received_reg(&mymqtt,MqttReceive);//×¢²á½ÓÊÕÊý¾Ý»Øµ÷º¯Êý
    //Á¬½ÓÉÏMQTT·þÎñÆ÷
            if(mqtt_connect_flag)
            {
                mqtt_send_function(&mymqtt);//ÌáÈ¡·¢ËÍ»º´æµÄMQTTЭÒé
                mqtt_keep_alive(&mymqtt);//´¦Àí·¢ËÍÐÄÌø°ü
            }

    4.把mqtt_time_data(&mymqtt); 放到1ms定时器里面

    5.在mqtt.c里面替换自己的tcp发送数据函数

    注:我的单片机是通过串口2和模组通信

    关于下面的 mymqtt.timer_out_send = 0; 这个是预防有的模块发送数据之后需要等待,按照提示修改就可以

    wifi模块透传模式下每条数据的时间间隔需要保持在20ms以上,所以我直接设置的20

    6.编写组合发送连接MQTT协议函数

    7.连接上TCP服务器以后每隔一段时间发送MQTT连接协议给服务器

    8.把模组接收的网络数据交给mqtt处理函数处理

    注:在未连接上mqtt服务器交给  mqtt_function_connect_ack函数(该函数判断连接成功会调用注册的mqtt连接成功回调)

    注:在连接上mqtt服务器交给  mqtt_read_function 函数

    9.把代码下载测试

    10.断线重连

    典型处理方式:在TCP断开的时候需要重新连接TCP,然后再连接MQTT

    在MQTT断开的时候让模组也重新连接TCP.

    现在wifi模组是透传模式,模组不会返回tcp断开的信息了,所以就只在mqtt断开连接回调里面重新让tcp连接

    11.订阅主题和发布消息

    12.提示

    只要是连接上MQTT服务器了,可以在任意地方调用订阅和发布函数.

    打包的信息都缓存到了内部的缓存管理里面,缓存管理使用的是我在环形队列基础上封装的 BufferManage

    13.如果自己的MQTT数据包超过500不超过16383字节,则只需要修改数据缓存大小

    mqtt_send_buff_len是每个数据包的长度(假设自己的数据包最大是800,则可以设置为802)

    send_buff_loop_len 是保存每个数据包数组的长度(一般设置为mqtt_send_buff_len的整数倍)

    14.如果自己的MQTT数据包超过16383字节,则还需要修改底层

    当前是使用两字节保存数据个数

     

    15.接收数据,如果内存充足,推荐的处理方式

    现在看非透传版

    透传版和非透传版只是发送和接收数据的方式不一样,所以就在透传版的基础上修改

    1.首先模块资料

    2.TCP连接改为非透传多链接模式(使用的socket 0 进行的连接)

    3.改一下接收数据的地方,咱使用另外一个缓存只存储网络数据

     

    3.改一下发送连接协议的方式

    4.串口接收处理数据改一下

    上面只处理连接上MQTT服务器前和连接中出现的问题

    下面是把网络数据交给MQTT处理函数处理

    5.现在应该可以连接上MQTT服务器了

    6.接着修改这里面

    这里也需要改为先发送 AT+CIPSEND 然后再发送真实数据

    发送真实数据咱在透传的时候以后写了.

    我这个底层其实也是支持非透传的.

    7.设置为非透传模式

    8.编写发送数据命令函数

    8.根据下面的提示修改 >

    9.现在已经可以了

    结语

    代码不是重要的,重要的是处理思想和方案.

  • 相关阅读:
    hivesql 迁移spark3.0 sparksql报错如Cannot safely cast '字段':StringType to IntegerType的问题
    sparksql 报错Container killed by YARN for exceeding memory limits. xGB of x GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead or disabling
    hiveSql 迁移spark2.4时报错Error in query: Window function row_number() requires window to be ordered, please add ORDER BY clause
    spark 执行报错 java.io.EOFException: Premature EOF from inputStream
    记录一次线上yarn RM频繁切换的故障
    Linux关闭防火墙、设置端口
    crontab 定时任务
    Yum下载rpm包、不分析依赖关系强制安装
    scp 服务器之间远程复制
    Linux 永久改变系统时间
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/15083819.html
Copyright © 2020-2023  润新知