0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Renesas GUI挑战—天气日历设计

冬至配饺子 来源:EPTmachine 作者:EPTmachine 2023-09-15 15:53 次阅读

摘要

本次参加HMI-Boardt挑战赛,提交的作品是天气万年历,实现的功能主要有以下几点:
显示当前的日期,包括年月日,本地时间等信息
显示当前的天气、温度等信息;
选择该项目的主要原因是该项目涉及到了Wifi、http客户端、网络数据抓取等,属于典型的物联网应用,同时天气日历的逻辑很简单,很适合作为初学者的入门项目,能够接触到物联网开发的各个关键组件,配合RT-Thread丰富的生态,在培养兴趣的同时,可以将书本上的知识转化为贴近生活的实际应用。

1.1 程序整体介绍

本项目使用到的外设主要有TFT屏幕、RTC模块、RW007Wifi模块。
屏幕的分辨率为480x272,屏幕上显示的信息包括当前月份的日历(以边框形式在日历中显示当天的信息)、城市、温度、天气以及时间信息。程序的整体流程如下所示

1.jpg

项目中使用到的软件包如下所示:

1.jpg

项目中的代码主要集中在hal_entry.c以及lvgl_demo.c中,具体的文件分布如下图所示:

1.jpg

1.2 模块说明

1.2.1 显示部分

RT-Thread提供的HMI-Board的SDK中已经为用户编写了显示和触摸的驱动程序,同时lvgl中以为RT-Thread做了适配,在RT-Thread的启动序列中添加了lvgl线程的创建、调用lvgl初始化以及初始外设的函数,用户只需要编写lv_user_gui_init函数,设计应用相关的代码即可。

本项目的显示代码如下。

//导入额外的字体
LV_FONT_DECLARE(font_calendar_han_bold_20);
/* display demo; you may replace with your LVGL application at here */
//设定城市信息标签的外观和位置
city_label=lv_label_create(lv_scr_act());
lv_obj_set_style_text_font(city_label,&font_calendar_han_bold_20,0);
//lv_label_set_text(city_label, weather_data.name);
lv_obj_set_pos(city_label, 10,5);
//设定温度信息标签的外观和位置
temp_label=lv_label_create(lv_scr_act());
lv_obj_set_style_text_font(temp_label,&font_calendar_han_bold_20,0);
//lv_label_set_text(temp_label, weather_data.temp);
lv_obj_set_pos(temp_label, 10, 30);
//设定天气信息标签的外观和位置
weather_label=lv_label_create(lv_scr_act());
lv_obj_set_style_text_font(weather_label,&font_calendar_han_bold_20,0);
//abel_set_text(weather_label, weather_data.text);
lv_obj_set_pos(weather_label, 90, 30);
//创建时间标签控件,用于显示当前的时间信息
time_label=lv_label_create(lv_scr_act());
lv_obj_set_style_text_font(time_label,&font_calendar_han_bold_20,0);
lv_label_set_text(time_label, time_label_text);
lv_obj_set_pos(time_label, 10, 55);
//设定日历控件的外观和位置
calendar = lv_calendar_create(lv_scr_act());
lv_obj_set_x(calendar,10);
lv_obj_set_y(calendar,80);
lv_obj_set_size(calendar, 185, 185);
lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);
lv_calendar_set_today_date(calendar, 2021, 02, 23);
lv_calendar_set_showed_date(calendar, 2021, 02);
/*Highlight a few days*/
static lv_calendar_date_t highlighted_days[3];       /*Only its pointer will be saved so should be static*/
highlighted_days[0].year = 2021;
highlighted_days[0].month = 02;
highlighted_days[0].day = 6;
highlighted_days[1].year = 2021;
highlighted_days[1].month = 02;
highlighted_days[1].day = 11;
highlighted_days[2].year = 2022;
highlighted_days[2].month = 02;
highlighted_days[2].day = 22;
lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3);

#if LV_USE_CALENDAR_HEADER_DROPDOWN
lv_calendar_header_dropdown_create(calendar);
#elif LV_USE_CALENDAR_HEADER_ARROW
lv_calendar_header_arrow_create(calendar);
#endif
lv_calendar_set_showed_date(calendar, 2021, 10);

为了在屏幕上显示中文,首先准备需要用到的字体文件(项目中使用的是),在lvgl官方提供的字体转换工具中,根据自己的需要对字体的大小和字符集进行选择,最后得到字体文件,添加到项目中,使用lvgl的字体导入命令将要使用的字体导入,在需要使用的控件上使用该字体即可。

项目的界面效果如图所示。

1.2.2 Wifi连接、NTP校时部分

开发板上带有RW007Wifi模块,通过其可以连接到互联网,从而可以获取互联上提供的信息服务,比如NTP(网络时间协议)用于更新本地的RTC时间。

根据HMI-Board指南中的RW007模块使用,开启RW007模块的Wifi通讯功能,调用rt_wlan_connect函数连接到指定的Wifi,从而可以方位互联网服务。

开启物联网服务中的NTP服务和本地的RTC服务,可以通过访问NTP服务器,从而获取网络时间,对本地的时间进行校准。

1.jpg

相关的代码如下所示:

rt_device_t device = RT_NULL;
//连接到指定的Wifi
app_connect_wifi();
/*寻找设备*/
device = rt_device_find(RTC_NAME);
if (!device)
{
  rt_kprintf("find %s failed!", RTC_NAME);
  return;
}
/*初始化RTC设备*/
if(rt_device_open(device, 0) != RT_EOK)
{
  rt_kprintf("open %s failed!", RTC_NAME);
  return;
}
//同步NTP到RTC
while(!ntp_sync_to_rtc(RT_NULL));
rt_sem_release(time_sync);

lvgl中提供了定时功能,初始化定时器后,设定定时器的回调函数以及寻魂次数(这里参数给-1,表示无限循环),回调函数用于更新时间以及发送获取天气信息的信号量,具体代码如下:

sec_timer=lv_timer_create(sec_timer_cb, 500, NULL);
lv_timer_set_repeat_count(sec_timer, -1);

void sec_timer_cb(lv_timer_t* timer)
{
static uint16_t count=0;
count++;
app_get_time();
lv_label_set_text(time_label, time_label_text);
if(count==1800)
{
count=0;
rt_sem_release(get_weather);
}
}

1.2.3 获取天气信息并提取相应的信息

在main中hal_entry函数中,获取到访问天气数据的信号量后,创建WebClient,通过心知天气的API访问当前的天气信息,数据形式为JSON字符,根据官方提供的数据格式,对其中的数据进行解析,提取出相应的字段,用于在标签控件上显示信息。相关的代码如下所示:

#define GET_HEADER_BUFSZ 1024 //头部大小
#define GET_RESP_BUFSZ 1024 //响应缓冲区大小
static char *weather_url = "http://api.seniverse.com/v3/weather/now.json?key=SG-nLPzA3pyLEy9Tw&location=wuxi&language=zh-Hans&unit=c";
weather_t weather_data;
/* 天气数据解析 */
void weather_data_parse(rt_uint8_t *data)
{
cJSON *root = RT_NULL, *array=RT_NULL,*object = RT_NULL, *element=RT_NULL, *item=RT_NULL;
memset(&weather_data,0,sizeof(weather_data));
root = cJSON_Parse((const char *)data);
if (!root)
{
rt_kprintf("No memory for cJSON root!n");
return;
}
//获取结果对象
array = cJSON_GetObjectItem(root, "results");
//获取数组中的第一个元素
object = cJSON_GetArrayItem(array, 0);
//提取location的信息
element=cJSON_GetObjectItem(object,"location");
item=cJSON_GetObjectItem(element,"id");
memcpy(weather_data.id,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"name");
memcpy(weather_data.name,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"country");
memcpy(weather_data.country,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"path");
memcpy(weather_data.country,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"timezone");
memcpy(weather_data.country,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"tz_offset");
memcpy(weather_data.country,item->valuestring,strlen(item->valuestring));
//提取当前的天气信息
element=cJSON_GetObjectItem(object,"now");
item=cJSON_GetObjectItem(element,"text");
memcpy(weather_data.text,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"code");
memcpy(weather_data.code,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(element,"temperature");
memcpy(weather_data.temp,item->valuestring,strlen(item->valuestring));
//提取上次天气更新的时间信息
element=cJSON_GetObjectItem(object,"last_update");
memcpy(weather_data.last_update,element->valuestring,strlen(element->valuestring));
if (root != RT_NULL)
cJSON_Delete(root);
}
void weather(void)
{
rt_uint8_t *buffer = RT_NULL;
int resp_status;
struct webclient_session *session = RT_NULL;
int content_length = -1, bytes_read = 0;
int content_pos = 0;
/* 创建会话并且设置响应的大小 */
session = webclient_session_create(GET_HEADER_BUFSZ);
if (session == RT_NULL)
{
rt_kprintf("No memory for get header!n");
goto __exit;
}
/* 发送 GET 请求使用默认的头部 */
if ((resp_status = webclient_get(session, weather_url)) != 200)
{
rt_kprintf("webclient GET request failed, response(%d) error.n", resp_status);
goto __exit;
}
/* 分配用于存放接收数据的缓冲 */
buffer = rt_calloc(1, GET_RESP_BUFSZ);
if (buffer == RT_NULL)
{
rt_kprintf("No memory for data receive buffer!n");
goto __exit;
}
content_length = webclient_content_length_get(session);
if (content_length < 0)
{
/* 返回的数据是分块传输的. */
do
{
bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ);
if (bytes_read <= 0)
{
break;
}
}while (1);
}
else
{
do
{
bytes_read = webclient_read(session, buffer,
content_length - content_pos > GET_RESP_BUFSZ ?
GET_RESP_BUFSZ : content_length - content_pos);
if (bytes_read <= 0)
{
break;
}
content_pos += bytes_read;
}while (content_pos < content_length);
}
/* 天气数据解析 */
weather_data_parse(buffer);
__exit:
/* 关闭会话 */
if (session != RT_NULL)
webclient_close(session);
/* 释放缓冲区空间 */
if (buffer != RT_NULL)
rt_free(buffer);
}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 物联网
    +关注

    关注

    2900

    文章

    43949

    浏览量

    369712
  • GUI
    GUI
    +关注

    关注

    3

    文章

    634

    浏览量

    39467
  • WLAN技术
    +关注

    关注

    0

    文章

    23

    浏览量

    9256
  • wifi模块
    +关注

    关注

    60

    文章

    376

    浏览量

    73237
  • RT-Thread
    +关注

    关注

    31

    文章

    1256

    浏览量

    39791
收藏 人收藏

    评论

    相关推荐

    为全志D1开发板移植LVGL日历控件和显示天气

    利用TCP封装HTTP包请求天气信息 Linux还真是逐步熟悉中,现在才了解到Linux即没有原生的GUI,也没有应用层协议栈,所以要实现HTTP应用,必须利用TCP然后自己封装HTTP数据包。本篇
    发表于 02-21 09:59

    飞雪桌面日历 V6.5.0 官方版

    日历、月历、世界时钟、倒计时时钟、定时关机、备忘录、便签、节日生日定制、系统热键、光驱控制、网络校时、壁纸切换、邮件检查、语音报时、网络收音机、天气预报、MD5计算等。内含从公元1580-5000年
    发表于 04-01 22:21

    天气预警收音机方案

    天气预警收音机是在天气和灾害预警监测下, 提供安全的信息。天气预警收音机接收国家气象服务颁发的所有危险、天气警报、紧急信息提供给公众。功能/规格:一、 液晶显示:NOAA 警报/
    发表于 05-20 17:56

    DIY电子日历

    把以前做的电子日历那出来晒晒,有点灰尘了,不过好像还能用,只是最后的那个8*8点阵好像坏了一条线。我设计开发的是一种新型“电子日历钟”它可以全方面显示时间,年,月,日。星期,提供中文显示,农历显示
    发表于 02-15 08:45

    项目源码--Android天气日历精致UI源码

    技术要点:1. 天气日历精致UI2. Android的Http通信技术3. Android的天气信息解析4. Android的日历信息的统计5. Andorid的地理位置的管理6.源码
    发表于 08-24 16:33

    项目源码--Android天气日历精致UI源码

    ` 本帖最后由 2yuanma 于 2013-8-24 16:37 编辑 下载源码:技术要点:1. 天气日历精致UI2. Android的Http通信技术3. Android的天气信息解析4. Android的
    发表于 08-24 16:35

    树莓派多功能数码壁挂日历

    本帖最后由 348081236 于 2016-1-12 11:29 编辑 还在用笔在日历上的重要日子画圈写字吗?如果是那你就OUT了。上图这个数码壁挂日历除了日历的基本功能,它还能预测
    发表于 01-12 11:27

    RENESAS的相关资料推荐

    品牌:RENESAS型号:R5F1006AASP#X0封装:SSOP20包装:2500年份:1825+产地:JP数量:750000瑞利诚科技(深圳)有限公司RENESAS 诚信经销商瑞利诚科技(深圳
    发表于 11-29 07:41

    360携手HarmonyOS打造独特的“天气大师”

    大师。 选择天气这个品类,首先是因为成本低,因为我们已有360天气的设计经验和全套代码,是可以快速复用的。 其次则是认为用户对天气日历的需求,天然适合用HarmonyOS所倡导的
    发表于 03-03 17:29

    基于静态分析的Android GUI遍历方法

    分析Android应用程序数据流的基础之上,构建程序活动转换图和函数调用图,解析程序CUI元素,进而编写测试脚本动态遍历应用程序CUI元素。将该方法应用于订票日历、WiFi万能钥匙和360天气应用的实际测试,结果表明:Activity的平均覆盖率达到76%,明显高于人工测
    发表于 12-11 11:32 0次下载
    基于静态分析的Android <b class='flag-5'>GUI</b>遍历方法

    日历列表视图控件使用案例

    日历列表视图提供了一种日历选择日期的简便方法 用法 1.在布局xml文件中声明一个DayPickerView
    发表于 03-30 11:18 1次下载

    基于STM32设计的指针式电子钟与日历

    这是基于STM32设计的一个指针式电子钟+万年历小项目,采用3.5寸的LCD屏显示时钟,日历、温度、天气,支持触摸屏调整设置时间,设置闹钟,查看日历等等。整体项目主要是技术点就是LCD屏的图形绘制。比如: 时钟的时针绘制、分针、
    的头像 发表于 05-18 11:10 6116次阅读
    基于STM32设计的指针式电子钟与<b class='flag-5'>日历</b>

    二三极管在电子日历产品中的应用

    、闹钟、记事本等。电子日历的简单、简洁特点深得广大用户喜爱,很多电子日历还有闹钟、播报天气、装饰和电子画册的功能。
    的头像 发表于 02-20 11:24 874次阅读

    开发活动 | 嵌入式GUI挑战赛报名开启!参赛申领开发板

    开发挑战赛 RT-Thread社区联合LVGL社区,及合作伙伴瑞萨电子正式开启2023嵌入式GUI挑战赛,欢迎你来挑战! 在本次大赛中,我们欢迎所有参赛者来构建全面的嵌入式
    的头像 发表于 07-03 12:10 683次阅读
    开发活动 | 嵌入式<b class='flag-5'>GUI</b><b class='flag-5'>挑战</b>赛报名开启!参赛申领开发板

    嵌入式GUI挑战赛获奖名单公布!

    6月份RT-Thread 社区联合 LVGL 社区,及合作伙伴瑞萨电子正式开启2023嵌入式GUI挑战赛!经过3个月的激烈角逐,参赛者们提交了许多令人惊喜的作品,以超酷的新方式在嵌入式设备上去
    的头像 发表于 10-18 16:05 528次阅读
    嵌入式<b class='flag-5'>GUI</b><b class='flag-5'>挑战</b>赛获奖名单公布!