发帖
6 0 1

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

小浪先生
高级会员

7

主题

22

回帖

610

积分

高级会员

积分
610
小安派·Eyes-R2 2108 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

──── 0人觉得很赞 ────

使用道具 举报

2024-9-30 16:57:45
很不错哟
2024-10-2 09:47:01
不错不错
2024-10-3 20:02:45
楼主lvgl显示是参考的哪个教程?可以分享下吗?
我看的LVGL显示图片教程都不成功,只有RX示例可以成功显示画面
2024-10-25 10:53:48
好漂亮
2024-10-30 19:50:51
陈世繁华 发表于 2024-10-3 20:02
楼主lvgl显示是参考的哪个教程?可以分享下吗?
我看的LVGL显示图片教程都不成功,只有RX示例可以成功显示 ...

参考官方例程,论坛也有NXPGUI移植教程
2024-10-30 22:01:19
不错不错
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 28072 个
  • 话题数: 39647 篇