本文是接着上一篇文章的后续来写,上一篇写的太长了后面太累了就没写完,决定就是新开一篇来继续把他写完。

上一篇文章为: STM32使用esp01s上云,MQTT.fx调试

1、程序配置

建议可以看这篇博主讲的,我觉得讲的很好,这里我把他的内容变成我自己的来用下,链接如下:

https://blog.csdn.net/weixin_45488643/article/details/107132066

我们使用的别人库来进行解析和生成json的,库文件地址 https://github.com/DaveGamble/cJSON
在这里插入图片描述
之后就可以配置串口了,这里最好是把工程的堆栈设置的大一点,可能会出现溢出的问题
在这里插入图片描述
新建工程将文件添加到我们工程目录下
在这里插入图片描述

2、新建json数据

下面就可以测试新建json数据和解析json数据了

新建数据,就是上面提到的那个test.c里面提供了我们需要的测试函数,这里我贴出源码,供测试使用

struct record
{
    const char *precision;
    double lat;
    double lon;
    const char *address;
    const char *city;
    const char *state;
    const char *zip;
    const char *country;
};


/* Create a bunch of objects as demonstration. */
static int print_preallocated(cJSON *root)
{
    /* declarations */
    char *out = NULL;
    char *buf = NULL;
    char *buf_fail = NULL;
    size_t len = 0;
    size_t len_fail = 0;

    /* formatted print */
    out = cJSON_Print(root);

    /* create buffer to succeed */
    /* the extra 5 bytes are because of inaccuracies when reserving memory */
    len = strlen(out) + 5;
    buf = (char*)malloc(len);
    if (buf == NULL)
    {
        printf("Failed to allocate memory.\n");
        exit(1);
    }

    /* create buffer to fail */
    len_fail = strlen(out);
    buf_fail = (char*)malloc(len_fail);
    if (buf_fail == NULL)
    {
        printf("Failed to allocate memory.\n");
        exit(1);
    }

    /* Print to buffer */
    if (!cJSON_PrintPreallocated(root, buf, (int)len, 1)) {
        printf("cJSON_PrintPreallocated failed!\n");
        if (strcmp(out, buf) != 0) {
            printf("cJSON_PrintPreallocated not the same as cJSON_Print!\n");
            printf("cJSON_Print result:\n%s\n", out);
            printf("cJSON_PrintPreallocated result:\n%s\n", buf);
        }
        free(out);
        free(buf_fail);
        free(buf);
        return -1;
    }

    /* success */
    printf("%s\n", buf);

    /* force it to fail */
    if (cJSON_PrintPreallocated(root, buf_fail, (int)len_fail, 1)) {
        printf("cJSON_PrintPreallocated failed to show error with insufficient memory!\n");
        printf("cJSON_Print result:\n%s\n", out);
        printf("cJSON_PrintPreallocated result:\n%s\n", buf_fail);
        free(out);
        free(buf_fail);
        free(buf);
        return -1;
    }

    free(out);
    free(buf_fail);
    free(buf);
    return 0;
}
static void create_objects(void)
{
    /* declare a few. */
    cJSON *root = NULL;
    cJSON *fmt = NULL;
    cJSON *img = NULL;
    cJSON *thm = NULL;
    cJSON *fld = NULL;
    int i = 0;

    /* Our "days of the week" array: */
    const char *strings[7] =
    {
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
    };
    /* Our matrix: */
    int numbers[3][3] =
    {
        {0, -1, 0},
        {1, 0, 0},
        {0 ,0, 1}
    };
    /* Our "gallery" item: */
    int ids[4] = { 116, 943, 234, 38793 };
    /* Our array of "records": */
    struct record fields[2] =
    {
        {
            "zip",
            37.7668,
            -1.223959e+2,
            "",
            "SAN FRANCISCO",
            "CA",
            "94107",
            "US"
        },
        {
            "zip",
            37.371991,
            -1.22026e+2,
            "",
            "SUNNYVALE",
            "CA",
            "94085",
            "US"
        }
    };
    volatile double zero = 0.0;

    /* Here we construct some JSON standards, from the JSON site. */

    /* Our "Video" datatype: */
    root = cJSON_CreateObject();
    cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
    cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
    cJSON_AddStringToObject(fmt, "type", "rect");
    cJSON_AddNumberToObject(fmt, "width", 1920);
    cJSON_AddNumberToObject(fmt, "height", 1080);
    cJSON_AddFalseToObject (fmt, "interlace");
    cJSON_AddNumberToObject(fmt, "frame rate", 24);

    /* Print to text */
    if (print_preallocated(root) != 0) {
        cJSON_Delete(root);
        exit(EXIT_FAILURE);
    }
    cJSON_Delete(root);

    /* Our "days of the week" array: */
    root = cJSON_CreateStringArray(strings, 7);

    if (print_preallocated(root) != 0) {
        cJSON_Delete(root);
        exit(EXIT_FAILURE);
    }
    cJSON_Delete(root);

    /* Our matrix: */
    root = cJSON_CreateArray();
    for (i = 0; i < 3; i++)
    {
        cJSON_AddItemToArray(root, cJSON_CreateIntArray(numbers[i], 3));
    }

    /* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */

    if (print_preallocated(root) != 0) {
        cJSON_Delete(root);
        exit(EXIT_FAILURE);
    }
    cJSON_Delete(root);

    /* Our "gallery" item: */
    root = cJSON_CreateObject();
    cJSON_AddItemToObject(root, "Image", img = cJSON_CreateObject());
    cJSON_AddNumberToObject(img, "Width", 800);
    cJSON_AddNumberToObject(img, "Height", 600);
    cJSON_AddStringToObject(img, "Title", "View from 15th Floor");
    cJSON_AddItemToObject(img, "Thumbnail", thm = cJSON_CreateObject());
    cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943");
    cJSON_AddNumberToObject(thm, "Height", 125);
    cJSON_AddStringToObject(thm, "Width", "100");
    cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));

    if (print_preallocated(root) != 0) {
        cJSON_Delete(root);
        exit(EXIT_FAILURE);
    }
    cJSON_Delete(root);

    /* Our array of "records": */
    root = cJSON_CreateArray();
    for (i = 0; i < 2; i++)
    {
        cJSON_AddItemToArray(root, fld = cJSON_CreateObject());
        cJSON_AddStringToObject(fld, "precision", fields[i].precision);
        cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat);
        cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon);
        cJSON_AddStringToObject(fld, "Address", fields[i].address);
        cJSON_AddStringToObject(fld, "City", fields[i].city);
        cJSON_AddStringToObject(fld, "State", fields[i].state);
        cJSON_AddStringToObject(fld, "Zip", fields[i].zip);
        cJSON_AddStringToObject(fld, "Country", fields[i].country);
    }

    /* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */

    if (print_preallocated(root) != 0) {
        cJSON_Delete(root);
        exit(EXIT_FAILURE);
    }
    cJSON_Delete(root);

    root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "number", 1.0 / zero);

    if (print_preallocated(root) != 0) {
        cJSON_Delete(root);
        exit(EXIT_FAILURE);
    }
    cJSON_Delete(root);
}

将函数添加到初始话并打印数据,结果如下
在这里插入图片描述
将串口的数据复制到VSCODE中,进行格式化这样更方便我们查看数据
在这里插入图片描述
这里我们截取一段,可以看到就是比较标准的数据格式了
在这里插入图片描述
当然就是我们一般也用不到这么复杂啊,这多麻烦啊,因此我们这里在来做一个精简版的看看效果
在这里插入图片描述

源码如下

void Create_BJTime_JSON(void)
{
    cJSON *root;    cJSON *result;
    root = cJSON_CreateObject();
    result = cJSON_CreateObject();

    cJSON_AddItemToObject(result, "姓名", cJSON_CreateString("水语茗言"));
    cJSON_AddItemToObject(result, "时间", cJSON_CreateString("2020/03/09"));
    cJSON_AddItemToObject(result, "place", cJSON_CreateString("安徽合肥"));
    cJSON_AddItemToObject(result, "星期", cJSON_CreateString("周五"));
    cJSON_AddItemToObject(result, "xxx", cJSON_CreateString("xxx1"));
    cJSON_AddItemToObject(result, "xxx2", cJSON_CreateString("xxx3"));
    cJSON_AddItemToObject(result, "xxx3", cJSON_CreateString("xxx4"));

    cJSON_AddItemToObject(root, "status", cJSON_CreateString("success"));
    cJSON_AddItemToObject(root, "result", result);
    cJSON_AddStringToObject(root, "wiki", "https://blog.csdn.net/m0_51220742?spm=1010.2135.3001.5343");
    printf("\n%s\r\n", cJSON_Print(root));    cJSON_Delete(root);
}

将程序下载到开发板,效果如下
在这里插入图片描述

3、读取json数据

读取相对简单点,只要我们稍微进行设置即可

这里我用到了空闲中断+DMA的方式来处理数据,关于处理方法,在我其他的博文中有相关的介绍,这里不作介绍

在这里插入图片描述
这里我准备了一段数据模版
在这里插入图片描述
源代码如下

{
    "state": {
        "desired": {
            "hz": 5,
            "temp_comp": 0.1
        }
    },
    "metadata": {
        "reported": {
            "hz": {
                "timestamp": 1559720433
            },
            "temp_comp": {
                "timestamp": 1559720433
            }
        },
        "desired": {
            "hz": {
                "timestamp": 1559720433
            },
            "temp_comp": {
                "timestamp": 1559720433
            }
        }
    },
    "timestamp": 1559720433,
    "version": 3
}

将程序下载到开发板,效果如下所示,可以看到数据已经成功的打印出来了
在这里插入图片描述
这里还有一点很重要的就是每次用完之后就要吧这个清理掉,不然程序跑一段时间就会莫名其妙出错,据说是动态内存产生的问题
在这里插入图片描述

4、解析心知天气

很多创客项目都会一些桌面天气项目之类的,这个目前资料也比较齐全,使用也很方便,就是去百度搜索然后注册个账号就行了

这里我声明下,看到我博客的请不要用我的私钥,因为一定时间限制使用次数的,虽然免费但不是高频使用的

获取私钥的方法如下所示

在这里插入图片描述
使用API的方法如下。官方提供了说明文档 https://seniverse.yuque.com/books/share/e52aa43f-8fe9-4ffa-860d-96c0f3cf1c49/nyiu3t
在这里插入图片描述
简单说就是把下面的APIke替换为你自己的然后城市也变为自己的,城市只要是名字改用英文名即可,比如合肥 -> hefei

https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c

之后可以测试下输入,最方便的就是浏览器直接输入
在这里插入图片描述
将返回的数据放到VSCODE里面解析就这样了
在这里插入图片描述

5、ESP01S获取数据

那么下面我们用ESP01S来连上获取设备试试

首先第一步还是测试AT是否能用
在这里插入图片描述
设置ESP01S的模式(1是当成手机用,2是路由器,3是两种兼容
在这里插入图片描述
连WIFI
在这里插入图片描述
连上心知天气
在这里插入图片描述
开启透传:
在这里插入图片描述
发送数据:
在这里插入图片描述

向网站发起请求,就是GET加上我们前面说的那个申请的链接,可以看到数据接收OK的
在这里插入图片描述

6、STM32获取数据

前面的一直用的都是ESP01S的模块,这次换个模块试试,好家伙,不换不知道,一换一堆坑,所以使用的一定要注意了,本次我使用正点原子的esp8266wifi模块如下
在这里插入图片描述
常见引脚连接如下所示:

VCC电源(3.3V 5V)
GND电源地
TXD模块串口发送脚(TTL电平,不能直接接RS232电平!),可接单片机的RXD
RXD模块串口接收脚(TTL电平,不能直接接RS232电平!),可接单片机的TXD
RST复位(低电平有效)
IO0用于进入固件烧写模式,低电平是烧写模式,高电平是运行模式(默认状态)

这里提个醒,一定要注意,模块上电是蓝灯常亮的,如果你的模块不亮就给他接上5v,不然固件更新不过去,会一直抱错的!

这里固件更新的页面设置如下

在这里插入图片描述
按照习惯还是先擦除后更新,上面的两个bin文件在官方提供的资料包里面!

更新完成之后拔掉,重新上电(这里要注意啊,一定要重新上电),然后将IO2恢复为悬空状态,这个时候我们在测试AT指令就OK了!
在这里插入图片描述
好,那么我们下面就可以来解析天气了,首相还是一样的就是把我们的这个串口打开并开启DMA接收
在这里插入图片描述
关于串口DMA的这一部分可以看我之前的文章:串口通信中一些常用的小工具

下面可以根据前面AT指令设置的进行调节:
在这里插入图片描述
下面是一个要注意的地方
在这里插入图片描述
下面我们就可以使用串口来查看数据了
在这里插入图片描述
下面调用上面讲的进行解析:
在这里插入图片描述
打印数据如下所示,可以看到是完全ok的!
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐