单片机stm32使用ESP8266MQTT AT指令发送json字符串

  • Post author:
  • Post category:其他


一、问题描述

基于文章

<单片机stm32使用rt-thread软件包at-device的AT指令>

,测试发现使用MQTT AT指令发送主题信息时,直接发送字符串正常,发送json字符串时出问题,提示错误。数据格式的区别如下:

"%s"//正常发送
"\"%s\""//提示错误有,发送失败

二、解决办法

查看文档,发现指令

AT+MQTTPUBRAW:发布 MQTT 消息(二进制),

该指令格式如下:

AT+MQTTPUBRAW=<LinkID>,<"topic">,<length>,<qos>,<retain>

6eb7ee7cdc65693f722b16659d74ff5c.png

参数:

<LinkID>:当前仅支持 link ID 0。

<topic>:MQTT topic,最大长度:128 字节。

<length>:MQTT 消息长度,不同 ESP 设备的最大长度不同:

对于 ESP32 设备:最大长度受到可利用内存的限制;

对于 ESP8266 设备,最大长度受到可利用内存和 MQTT_BUFFER_SIZE_BYTE 宏的限制。该宏的默认值为 512,可在 build.py menuconfig 中设置它的值,以此更改对最大长度的限制。该宏的值 = 消息的最大长度 + MQTT 报头长度(取决于 topic 名称的长度)。

<qos>:发布消息的 QoS,参数可选 0、1、或 2,默认值:0。

<retain>:发布 retain。

三、代码修改

修改代码如下:

#include <rtthread.h>
#include <rtdevice.h>
#include <at.h>
#include <at_device.h>
#include <at_log.h>


#define AT_SEND_MQTT_CMD(client, resp, cmd)                                 \
    do {                                                                   \
        (resp) = at_resp_set_info((resp), 256, 0, 10 * RT_TICK_PER_SECOND); \
        if (at_obj_exec_cmd((client), (resp), (cmd)) < 0)                  \
        {                                                                  \
            result = -RT_ERROR;                                            \
            goto __exit;                                                   \
        }                                                                  \
    } while(0)                                                             \


//mqtt 发布主题,测试不同的信息,看是否可以正常发布json信息
static int mqtt_at_send(int argc, char **argv)
{
    rt_uint8_t retry_num=3;
    at_response_t resp = RT_NULL;
    int result=-RT_ERROR;
    int i=0;
    at_client_t client=RT_NULL;
    struct at_device *device = RT_NULL;


    device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, "esp0");
    if(device == RT_NULL)
    {
        rt_kprintf("no find esp0.\r\n");
        return -1;
    }
    client=device->client;
    resp = at_create_resp(128, 0, 10 * RT_TICK_PER_SECOND);
    if (resp == RT_NULL)
    {
        rt_kprintf("no memory for resp create.\r\n");
        return -1;
    } 
    while (retry_num--)
    { 


            if(argc == 1)//字符串发送
            {
                /*mqtt pubTopic*/
                //AT_SEND_MQTT_CMD(client, resp, "AT+MQTTPUB=0,\"testTopic1\",\"{\"testTopic1\":\"data_test1\"}\",0,0");
                AT_SEND_MQTT_CMD(client, resp, "AT+MQTTPUB=0,\"testTopic1\",\"test123456\",0,0");
            }
            else if(argc == 2)//字符串发送
            {
                AT_SEND_MQTT_CMD(client, resp, "AT+MQTTPUB=0,\"testTopic1\",\"{key0:data_test1}\",0,0");
                
            }
            else if(argc == 3)//二进制发送信息
            {
//                if (at_obj_exec_cmd(client, at_resp_set_info(resp, 128, 0, 20 * RT_TICK_PER_SECOND),
//                    "AT+MQTTPUB=0,\"testTopic1\",\"%s%s\",0,0", argv[1], argv[2]) != RT_EOK)
//                {
//                    LOG_D("device send failed.\r\n");
//                }
                
                    AT_SEND_MQTT_CMD(client, resp, "AT+MQTTPUBRAW=0,\"testTopic1\",30,0,0");
                    /* show pubTopic message */
//                    for (i = 0; i < resp->line_counts - 1; i++)
//                    {
//                        LOG_D("%s", at_resp_get_line(resp, i + 1));
//                    }
                    rt_device_write(client->device,0,"{\"key0\":\"data_test1\",\"key1\":1}",rt_strlen("{\"key0\":\"data_test1\",\"key1\":1}"));
                        
                
            }
            
                
                /* show pubTopic message */
            for (i = 0; i < resp->line_counts - 1; i++)
            {
                LOG_D("%s", at_resp_get_line(resp, i + 1));
            }       
        //rt_thread_mdelay(5000);
        /* initialize successfully  */
        result = RT_EOK;
        break;




    __exit:
        if (result != RT_EOK)
        {
            rt_thread_mdelay(1000);
            rt_kprintf("%s device send retry...", device->name);
        }
    }
    if (resp)
    {
        at_delete_resp(resp);
    }
    if(result != RT_EOK)
    {
        return -1;
    }
    return 0;
    
}
MSH_CMD_EXPORT(mqtt_at_send, esp8266 mqtt at send message);


static int esp8266_mqtt_at_init(void)
{
    rt_uint8_t retry_num=3;
    at_response_t resp = RT_NULL;
    int result=-RT_ERROR;
    int i=0;
    at_client_t client=RT_NULL;
    struct at_device *device = RT_NULL;


    device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, "esp0");
    if(device == RT_NULL)
    {
        rt_kprintf("no find esp0.\r\n");
        return -1;
    }
    client=device->client;
    resp = at_create_resp(128, 0, 10 * RT_TICK_PER_SECOND);
    if (resp == RT_NULL)
    {
        rt_kprintf("no memory for resp create.\r\n");
        return -1;
    }
    while (retry_num--)
    { 
        /* mqtt para  */
        AT_SEND_MQTT_CMD(client, resp, "AT+MQTTUSERCFG=0,1,\"123cli\",\"\",\"\",0,0,\"\"");
        rt_thread_mdelay(3000);
        /* mqtt connect para*/
        AT_SEND_MQTT_CMD(client, resp, "AT+MQTTCONNCFG=0,120,0,\"lwt_topic\",\"lwt_msg\",0,0");
        rt_thread_mdelay(3000);
        /* mqtt connect */
        AT_SEND_MQTT_CMD(client, resp, "AT+MQTTCONN=0,\"47.107.99.203\",1883,1");
        /* show connect info */
        for (i = 0; i < resp->line_counts - 1; i++)
        {
            rt_kprintf("%s", at_resp_get_line(resp, i + 1));
        }
        //rt_thread_mdelay(5000);
        /*mqtt subTopic*/ 
        AT_SEND_MQTT_CMD(client, resp, "AT+MQTTSUB=0,\"testTopic1\",0");
        rt_thread_mdelay(3000);
        /* initialize successfully  */
        result = RT_EOK;
        break;


    __exit:
        if (result != RT_EOK)
        {
            rt_thread_mdelay(1000);
            rt_kprintf("%s device initialize retry...", device->name);
        }
    }
    if (resp)
    {
        at_delete_resp(resp);
    }
    if(result != RT_EOK)
    {
        return -1;
    }
    return 0;
    
}
//mqtt 参数初始化,订阅主题
void mqtt_at_init(int argc, char **argv)
{
    int result=-1;
    result = esp8266_mqtt_at_init();


    if (result!=RT_EOK)
    {
        rt_kprintf("mqtt at cmd err.\r\n");
    }
}
MSH_CMD_EXPORT(mqtt_at_init, esp8266 mqtt at cmd demo);

四、测试结果

4a884986c7929f48744d9ef9915c25a7.png


欢迎关注个人公众号:嵌入式学习与实践



版权声明:本文为weixin_46158019原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。