【小安派R2测评】安信可小安派R2 天气时钟

[复制链接]
查看1825 | 回复6 | 2024-9-30 15:24:31 | 显示全部楼层 |阅读模式

本帖最后由 小浪先生 于 2024-9-30 15:24 编辑

1.工程搭建

工程搭建我遇到的问题,估计大家都会遇到,在我往期的帖子里可以看到。我是利用helloword工程一点点搭建的,对理解工程框架很有帮助,有问题可以留言探讨。以下是我往期的帖子:

环境搭建

查找AiPI-Eyes-R1/R2 特定的 boot2及验证固件

2.工程框架

天气时钟工程大致可以分为三部分,

1.连接wifi;

2.请求api,获取天气;

3.GUI界面显示

2.1连接WiFi

连接wifi和http请求部分我是参考的这篇文章【教程贴】M61-32S系列连接Wifi 且发送HTTP请求。连接wifi部分不需要改动,http请求部分,确实会像这位博主所说的,会有卡死的的几率,我查阅资料发现,使用的recv函数是死等待,请求没有返回时,程序会跑飞,我在recv前面加入了下面几行代码设置了超时时间,算是暂时解决了这个问题,我这边跑程序一两个小时没有卡死,还需进一步验证测试。

    // 设置recv超时时间
    struct timeval tv_out;
    tv_out.tv_sec = 5;
    tv_out.tv_usec = 0;

2.2获取天气

天气api是采用的新知天气api获取近3天的天气,前面http请求获取的数据是json数据,利用开源的cJSON库进行解析。cJSON库下载链接

网上很多人说,在cJSON库解析过程中,很容易卡死,那是因为没有及时删除cJSON对象。每次解析完都要删除,不然解析次数多了就会卡死。

cJSON_Delete(root); /*每次调用cJSON_Parse函数后,都要释放内存*/

解析代码如下:

int weather_info_parse(char *weather_data_buf)
{
    // 对接收到的数据作相应的处理
    uint8_t i, j;
    uint8_t result_array_size = 0;
    uint8_t daily_array_size = 0;

    cJSON *root = NULL;
    cJSON *item = NULL;
    cJSON *results_root = NULL;
    cJSON *daily_root = NULL;

    root = cJSON_Parse(weather_data_buf);
    if (!root)
    {

        // ESP_LOGI(TAG, "Error before: [%s]\n", cJSON_GetErrorPtr());
        LOG_I("Error before: [%s]\r\n", cJSON_GetErrorPtr());
        cJSON_Delete(root); /*每次调用cJSON_Parse函数后,都要释放内存*/
        return -1;
    }

    //    ESP_LOGI(TAG, "%s\r\n", cJSON_Print(root)); /*将完整的数据以JSON格式打印出来*/

    cJSON *Presult = cJSON_GetObjectItem(root, "results"); /*results 的键值对为数组,*/

    result_array_size = cJSON_GetArraySize(Presult); /*求results键值对数组中有多少个元素*/
    //  ESP_LOGI(TAG, "Presult array size is %d\n",result_array_size);

    for (i = 0; i < result_array_size; i++)
    {
        cJSON *item_results = cJSON_GetArrayItem(Presult, i);

        char *sresults = cJSON_PrintUnformatted(item_results);
        results_root = cJSON_Parse(sresults);
        if (!results_root)
        {
            // ESP_LOGI(TAG, "Error before: [%s]\n", cJSON_GetErrorPtr());
            LOG_I("Error before: [%s]\r\n", cJSON_GetErrorPtr());
            cJSON_Delete(root); /*每次调用cJSON_Parse函数后,都要释放内存*/
            return -1;
        }
        /*-------------------------------------------------------------------*/

        cJSON *Plocation = cJSON_GetObjectItem(results_root, "location");

        item = cJSON_GetObjectItem(Plocation, "id");
        user_sen_config.id = cJSON_Print(item);
        // ESP_LOGI(TAG, "id:%s\n",  user_sen_config.id);   /*逐个打印*/

        item = cJSON_GetObjectItem(Plocation, "name");
        user_sen_config.name = cJSON_Print(item);
        //          ESP_LOGI(TAG, "name:%s\n", cJSON_Print(item));

        item = cJSON_GetObjectItem(Plocation, "country");
        user_sen_config.country = cJSON_Print(item);
        //          ESP_LOGI(TAG, "country:%s\n", cJSON_Print(item));

        item = cJSON_GetObjectItem(Plocation, "path");
        user_sen_config.path = cJSON_Print(item);
        //          ESP_LOGI(TAG, "path:%s\n", cJSON_Print(item));

        item = cJSON_GetObjectItem(Plocation, "timezone");
        user_sen_config.timezone = cJSON_Print(item);
        //          ESP_LOGI(TAG, "timezone:%s\n", cJSON_Print(item));

        item = cJSON_GetObjectItem(Plocation, "timezone_offset");
        user_sen_config.timezone_offset = cJSON_Print(item);
        //          ESP_LOGI(TAG, "timezone_offset:%s\n", cJSON_Print(item));
        /*-------------------------------------------------------------------*/
        cJSON *Pdaily = cJSON_GetObjectItem(results_root, "daily");

        daily_array_size = cJSON_GetArraySize(Pdaily);
        //          ESP_LOGI(TAG, "Pdaily array size is %d\n",daily_array_size);

        for (j = 0; j < daily_array_size; j++)
        {
            cJSON *item_daily = cJSON_GetArrayItem(Pdaily, j);

            char *sdaily = cJSON_PrintUnformatted(item_daily);

            daily_root = cJSON_Parse(sdaily);

            if (!daily_root)
            {
                LOG_I("Error before: [%s]\r\n", cJSON_GetErrorPtr());
                return -1;
            }

            item = cJSON_GetObjectItem(daily_root, "date");
            user_sen_config.day_config[j].date = item->valuestring; // cJSON_Print(item)

            item = cJSON_GetObjectItem(daily_root, "text_day");
            user_sen_config.day_config[j].text_day = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "code_day");
            user_sen_config.day_config[j].code_day = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "text_night");
            user_sen_config.day_config[j].text_night = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "code_night");
            user_sen_config.day_config[j].code_night = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "high");
            user_sen_config.day_config[j].high = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "low");
            user_sen_config.day_config[j].low = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "rainfall");
            user_sen_config.day_config[j].rainfall = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "precip");
            user_sen_config.day_config[j].precip = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "wind_direction");
            user_sen_config.day_config[j].wind_direction = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "wind_direction_degree");
            user_sen_config.day_config[j].wind_direction_degree = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "wind_speed");
            user_sen_config.day_config[j].wind_speed = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "wind_scale");
            user_sen_config.day_config[j].wind_scale = cJSON_Print(item);

            item = cJSON_GetObjectItem(daily_root, "humidity");
            user_sen_config.day_config[j].humidity = cJSON_Print(item);

            cJSON_Delete(daily_root); /*每次调用cJSON_Parse函数后,都要释放内存*/
        }
        /*-------------------------------------------------------------------*/
        item = cJSON_GetObjectItem(results_root, "last_update");
        user_sen_config.last_update = cJSON_Print(item);

        cJSON_Delete(results_root); /*每次调用cJSON_Parse函数后,都要释放内存*/
    }

    cJSON_Delete(root); /*每次调用cJSON_Parse函数后,都要释放内存*/

    return 0;
}

2.3GUI界面设计

在配置完工程所需的LVGL配置后,你可能会发现,自己配置的LVGL程序并不能执行,而且..\AiPi-Open-Kits\aithinker_Ai-M6X_SDK\examples下的lvgl示例也不能正确执行,不要怀疑自己,自己配置可能是没问题的。具体解决方法参考小安派R2工程移植LVGL后不运行【暂时解决】我之前写的这篇帖子。

GUI设计是利用NXP的GUI Guider进行设计的,这里介绍一下怎么移植他的文件,当你程序配置好LVGL组件并能正常执行demo后,将GUI工程中的custom和generated文件夹放入自己的工程中,在Cmake.List文件中配置好路径,可能generated文件夹中的images文件夹中的生成的图片可能会报错,只需要将\lgvl\lvgl.h改为lvgl.h即可。

在mian.c中加入头文件

// lvgl
#include "gui_guider.h"
#include "events_init.h"

在mian函数中实例化对象

    setup_ui(&guider_ui);
    events_init(&guider_ui);

就可以正常显示通过GUI Guider设计的界面了,我这里是用的FreeRTOS的任务调用的lvgl处理函数:

void lvgl_task(void *pvParameters)
{

    while (1)
    {
        // LOG_I("lvgl_task is runing...\r\n");
        lv_task_handler();
        vTaskDelay(1);
        // bflb_mtimer_delay_ms(1);
    }
}

下面是我用GUI Guider设计,很简单的一个界面。 image.png

3.结果展示

99.jpg

回复

使用道具 举报

bzhou830 | 2024-9-30 16:57:45 | 显示全部楼层
很不错哟
选择去发光,而不是被照亮
回复

使用道具 举报

流水源 | 2024-10-2 09:47:01 | 显示全部楼层
不错不错
回复

使用道具 举报

陈世繁华 | 2024-10-3 20:02:45 | 显示全部楼层
楼主lvgl显示是参考的哪个教程?可以分享下吗?
我看的LVGL显示图片教程都不成功,只有RX示例可以成功显示画面
回复 支持 反对

使用道具 举报

qhsj | 2024-10-25 10:53:48 | 显示全部楼层
好漂亮
回复

使用道具 举报

小浪先生 | 2024-10-30 19:50:51 | 显示全部楼层
陈世繁华 发表于 2024-10-3 20:02
楼主lvgl显示是参考的哪个教程?可以分享下吗?
我看的LVGL显示图片教程都不成功,只有RX示例可以成功显示 ...

参考官方例程,论坛也有NXPGUI移植教程
回复 支持 反对

使用道具 举报

silang521 | 2024-10-30 22:01:19 | 显示全部楼层
不错不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则