摘要

  • 这个桌面小盒子是之前的东西,一直放着没有整理好。最近有空了就把他整理整理。

  • 小盒子主要用来显示时间和天气预报,功能比较简单,其实还有很多可以玩的,懒得弄,所以就把最简单的整理出来。

  • 软件是基于rt-thread, UI采用lvgl。

功能主要分为两个部分

第一部分--功能

功能部分主要分为两个部分,一个是NTP获取实时时间,一个是天气等信息。

  1. NTP比较简单,RTT提供了相关API。代码如下:

void get_local_time(void)
{time_t now;now = time(RT_NULL);tab_info.cur_tm = localtime(&now);rt_kprintf("time: %2d:%2d", tab_info.cur_tm->tm_hour, tab_info.cur_tm->tm_min);
}
  1. 获取天气信息,这个也比较简单,通过调用tianqiapi既可以获得。代码如下:

#define GET_WEATHER_URI "http://www.tianqiapi.com/api/?version=v6&cityid=101280601&appid=65251531&appsecret=Yl2bzCYb"struct weather_info
{char *response;cJSON *root;cJSON *date;cJSON *cur_temp;cJSON *humidity;cJSON *wea_img;
};int rp_weather_info_get(void)
{char *uri = RT_NULL;uri = web_strdup(GET_WEATHER_URI);if (webclient_request(uri, RT_NULL, RT_NULL, (unsigned char **)&info.response) < 0){rt_kprintf("get weather fail!\n");return -RT_ERROR;}info.root = cJSON_Parse(info.response);if(info.root != RT_NULL){info.date = cJSON_GetObjectItem(info.root, "date");info.cur_temp = cJSON_GetObjectItem(info.root, "tem");info.humidity = cJSON_GetObjectItem(info.root, "humidity");info.wea_img = cJSON_GetObjectItem(info.root, "wea_img");rt_kprintf("date : %s, cur_temp : %s, humidity : %s, wea_img : %s\n",info.date->valuestring, info.cur_temp->valuestring,info.humidity->valuestring, info.wea_img->valuestring);}return RT_EOK;
}void rp_weather_info_free(void)
{if (info.response != RT_NULL){web_free(info.response);}if(info.root != RT_NULL){cJSON_Delete(info.root);info.root = RT_NULL;}
}

第二部分--UI

  1. UI方面我使用了LVGL,这个开始比较方便的UI框架,可移植性搞。网上的教程也比较多。

  2. 由于rt-thread的LVGL软件包比较旧,而且有些东西没有移植好,所以我自己根据我的平台重新移植一份。

  3. 根据LVGL移植流程,需要对接porting下源文件的API回调。主要包含,disp(显示)、indev(输入设备,如触摸,按键)、fs(文件系统)。而本项目只对接disp(显示)、fs(文件系统, 读取SD卡的图片资源)

  • 其中fs的代码,文件系统我对接的dfs_posix的接口,因为我只使用读文件操作,所以直接对接部分接口,代码如下:

static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
{lv_fs_res_t res = LV_FS_RES_NOT_IMP;int fd = 0;if(mode == LV_FS_MODE_RD){if((fd = open(path, O_RDONLY)) > 0){*(file_t *)file_p = fd;res = LV_FS_RES_OK;}else{res = LV_FS_RES_NOT_EX;}}return res;
}static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
{lv_fs_res_t res = LV_FS_RES_UNKNOWN;int fd = *(file_t *)file_p;if (close(fd) == 0){res = LV_FS_RES_OK;}return res;
}static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{lv_fs_res_t res = LV_FS_RES_UNKNOWN;int fd = *(file_t *)file_p;int read_bytes = read(fd, buf, btr);if (read_bytes >= 0){*br = read_bytes;res = LV_FS_RES_OK;}return res;
}static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos)
{lv_fs_res_t res = LV_FS_RES_UNKNOWN;int fd = *(file_t *)file_p;if (lseek(fd, pos, SEEK_SET) >= 0){res = LV_FS_RES_OK;}return res;
}static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{lv_fs_res_t res = LV_FS_RES_UNKNOWN;int fd = *(file_t *)file_p;off_t pos = lseek(fd, 0, SEEK_CUR);if (pos >= 0){*pos_p = pos;res = LV_FS_RES_OK;}return res;
}void lv_port_fs_init(void)
{lv_fs_drv_t fs_drv;fs_init();lv_fs_drv_init(&fs_drv);fs_drv.file_size = sizeof(file_t);fs_drv.letter = 'S';fs_drv.open_cb = fs_open;fs_drv.close_cb = fs_close;fs_drv.read_cb = fs_read;fs_drv.seek_cb = fs_seek;fs_drv.tell_cb = fs_tell;lv_fs_drv_register(&fs_drv);
}
  • disp代码,因为是软件SPI,所以我采用的是整屏刷新。

static void disp_init(void)
{}static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{int32_t x;int32_t y;rt_uint8_t *frame_buffer = (rt_uint8_t *)psram_malloc(240 * 240 * 2);if(frame_buffer !=RT_NULL){for(y = area->y1; y <= area->y2; y++){for(x = area->x1; x <= area->x2; x++){frame_buffer[(y * 240 * 2)+(x * 2)] = color_p->full >> 8;frame_buffer[(y * 240 * 2)+(x * 2 + 1)] = color_p->full;color_p++;}}lcd_show_page((rt_uint8_t *)frame_buffer);psram_free(frame_buffer);frame_buffer = RT_NULL;}lv_disp_flush_ready(disp_drv);
}void lv_port_disp_init(void)
{lv_disp_drv_t disp_drv;disp_init();static lv_disp_buf_t draw_buf_dsc;static lv_color_t draw_buf[LV_HOR_RES_MAX * LV_VER_RES_MAX];lv_disp_buf_init(&draw_buf_dsc, draw_buf, NULL, LV_HOR_RES_MAX * LV_VER_RES_MAX);lv_disp_drv_init(&disp_drv);disp_drv.hor_res = LV_HOR_RES_MAX;disp_drv.ver_res = LV_VER_RES_MAX;disp_drv.flush_cb = disp_flush;disp_drv.buffer = &draw_buf_dsc;lv_disp_drv_register(&disp_drv);
}
  1. 这个盒子的UI设计比较简单,主要实现在main_tab_hander中实现,会先调用同步一下时间和天气信息。然后创建了一个task,来更新页面信息。

void get_main_tab_info(void)
{char hour_h[2] = {'0', '\0'};char hour_l[2] = {'0', '\0'};char min_h[2] = {'0', '\0'};char min_l[2] = {'0', '\0'};time_t now;now = time(RT_NULL);tab_info.cur_tm = localtime(&now);if(tab_info.cur_tm->tm_min == 0){rp_weather_info_get();rt_sprintf(tab_info.date, "%s", info.date->valuestring);rt_sprintf(tab_info.temp, "T: %s C", info.cur_temp->valuestring);rt_sprintf(tab_info.humi, "H: %s", info.humidity->valuestring);rt_sprintf(tab_info.wea_img, "S:/sd/weather_img/%s.bin", info.wea_img->valuestring);rp_weather_info_free();lv_label_set_text(date_label, tab_info.date);lv_label_set_text(temp_label, tab_info.temp);lv_label_set_text(humi_label, tab_info.humi);lv_img_set_src(weather_img, tab_info.wea_img);}hour_h[0] = (tab_info.cur_tm->tm_hour/10) + '0';hour_l[0] = (tab_info.cur_tm->tm_hour%10) + '0';min_h[0] = (tab_info.cur_tm->tm_min/10) + '0';min_l[0] = (tab_info.cur_tm->tm_min%10) + '0';lv_label_set_text(time_label[0], hour_h);lv_label_set_text(time_label[1], hour_l);lv_label_set_text(time_label[2], min_h);lv_label_set_text(time_label[3], min_l);
}void time_task_handle(lv_task_t* task)
{task = NULL;lv_led_toggle(time_led[0]);lv_led_toggle(time_led[1]);get_main_tab_info();
}int main_tab_hander(lv_obj_t* parent, char *name)
{rp_weather_info_get();rt_sprintf(tab_info.date, "%s", info.date->valuestring);rt_sprintf(tab_info.temp, "T: %s C", info.cur_temp->valuestring);rt_sprintf(tab_info.humi, "H: %s", info.humidity->valuestring);rt_sprintf(tab_info.wea_img, "S:/sd/weather_img/%s.bin", info.wea_img->valuestring);rp_weather_info_free();//日期static lv_style_t date_style;lv_style_init(&date_style);lv_style_set_text_font(&date_style, LV_STATE_DEFAULT, &lv_font_montserrat_20);lv_style_set_text_color(&date_style, LV_STATE_DEFAULT, LV_COLOR_WHITE);date_label = lv_label_create(parent, NULL);lv_obj_add_style(date_label, LV_LABEL_PART_MAIN, &date_style);lv_obj_align(date_label, NULL, LV_ALIGN_IN_TOP_MID, -30, 5);lv_label_set_recolor(date_label, true);lv_label_set_text(date_label, tab_info.date);//时间time_cont = lv_cont_create(parent, NULL);lv_obj_clean_style_list(time_cont, LV_OBJ_PART_MAIN);lv_obj_set_size(time_cont, 180, 70);lv_obj_align(time_cont, NULL, LV_ALIGN_IN_TOP_MID, 0, 30);lv_obj_set_style_local_bg_color(time_cont, LV_STATE_DEFAULT, LV_STATE_DEFAULT, LV_COLOR_MAKE(20, 20, 20));for (int i = 0; i < (sizeof(time_led) / sizeof(time_led[0])); i++){time_led[i] = lv_led_create(time_cont, NULL);lv_obj_set_size(time_led[i], 8, 10);lv_obj_align(time_led[i], NULL, LV_ALIGN_CENTER, 0, ((i == 0) ? (-10) : (10)));}static lv_style_t time_style;lv_style_init(&time_style);lv_style_set_text_font(&time_style, LV_STATE_DEFAULT, &lv_font_montserrat_48);lv_style_set_text_color(&time_style, LV_STATE_DEFAULT, LV_COLOR_WHITE);const lv_coord_t time_coord[4] = { -60, -25, 25, 60 };for (int i = 0; i < (sizeof(time_label) / sizeof(time_label[0])); i++){time_label[i] = lv_label_create(time_cont, NULL);lv_obj_add_style(time_label[i], LV_LABEL_PART_MAIN, &time_style);lv_label_set_text(time_label[i], "0");lv_obj_align(time_label[i], NULL, LV_ALIGN_CENTER, time_coord[i], 0);}weather_img = lv_img_create(parent, NULL);lv_obj_align(weather_img, NULL, LV_ALIGN_IN_BOTTOM_MID, -90, -90);lv_img_set_src(weather_img, tab_info.wea_img);//温湿度static lv_style_t humiture_style;lv_style_init(&humiture_style);lv_style_set_text_font(&humiture_style, LV_STATE_DEFAULT, &lv_font_montserrat_20);lv_style_set_text_color(&humiture_style, LV_STATE_DEFAULT, LV_COLOR_WHITE);temp_label = lv_label_create(parent, NULL);lv_obj_add_style(temp_label, LV_LABEL_PART_MAIN, &humiture_style);lv_obj_align(temp_label, NULL, LV_ALIGN_IN_BOTTOM_MID, 40, -70);// lv_label_set_recolor(temp_label, true);lv_label_set_text(temp_label, tab_info.temp);humi_label = lv_label_create(parent, NULL);lv_obj_add_style(humi_label, LV_LABEL_PART_MAIN, &humiture_style);lv_obj_align(humi_label, NULL, LV_ALIGN_IN_BOTTOM_MID, 40, -30);// lv_label_set_recolor(humi_label, true);lv_label_set_text(humi_label, tab_info.humi);time_task = lv_task_create(time_task_handle, 500, LV_TASK_PRIO_MID, NULL);time_task_handle(time_task);return 0;
}

效果:

  • 一个简单的桌面小工具:

  • 放在桌面,和PM2.5来实时监测工作环境。

关注微信公众号『Rice嵌入式开发技术分享』,后台回复“微信”添加作者微信,备注”入群“,便可邀请进入技术交流群。

基于RT-THREAD的桌面小工具相关推荐

  1. WinForm制作定时显示基金净值的桌面小工具

    基金网每隔一分钟会更新净值估算,每次要打开网站看挺麻烦的,于是制作了一个桌面小工具,在桌面顶层并且透明显示,每隔一分钟抓取数据显示. 净值估算例子如下: http://fund.eastmoney.c ...

  2. 基于rt thread smart构建EtherCAT主站

    我把源码开源到到了gitee,https://gitee.com/rathon/rt-thread-smart-soem 有兴趣的去可以下载下来跑一下 软件工程推荐用vscode 打开.rt thre ...

  3. win7倒计时桌面小工具_iOS 14系统面板截图曝光,新增桌面小工具,越来越像安卓了...

    商务合作请联系QQ:710035765 大家好,我是波老师.随着iOS 14越来越多的爆料,波老师预测距离iOS 14测试版的发布也要越来越近了.近日,有博主在Twitter上曝出了iOS 14墙纸设 ...

  4. 在计算机桌面上添加小工具日历,实用桌面小工具时钟日历在win7中的添加方法...

    我们在win7系统的使用中,小伙伴们都是知道的系统可以直接选择安装不同的小工具在电脑中使用,比如电脑中的时钟日历等都是可以直接安装在桌面来使用的牡丹石有小伙伴对于时钟日历不知道是在哪里添加到桌面的,对 ...

  5. MooTool 1.0.0 发布,开发者常备桌面小工具

    MooTool 1.0.0 已发布,开发者常备桌面小工具. MooTool A handy desktop toolset for developers. 开发者常备桌面小工具 支持的功能 Host切 ...

  6. python制作一个桌面小工具

    python实现一个桌面小工具,制作一个桌面的便签提醒工具 参考代码:https://github.com/cosven/memo 参考链接:https://www.jb51.net/article/ ...

  7. 快捷键调出计算机桌面小工具,工具推荐:巧用快捷键秒变电脑高手

    - 前言 - 最近迷上了新剧<西部世界>,美国西部丶科幻丶人工智能丶完美结合,大爱,这次的图就用剧照啦,回归正题. 如果电脑是你工作的主要方式,那么熟练使用键盘快捷键可以帮助提高工作效率, ...

  8. 如何在计算机桌面上添加小工具,怎么在电脑的桌面小工具里添加便签

    原标题:怎么在电脑的桌面小工具里添加便签 用便签小工具记事,是很多用电脑用户的常规操作.有的人找不到电脑便签,打开电脑开始菜单栏一看,记事工具居然只有记事本. 用记事本很多人不愿意,毕竟记事本比较适合 ...

  9. python课程小作业之桌面小工具系统

    from tkinter import *#图形界面包 from tkinter import messagebox import os.path import os import math impo ...

最新文章

  1. 由各大企业移除MongoDB,回看关系模型与文档模型之争
  2. python输入字母判断大小写_Python-检查输入的数字、大写字母、小写字母和特殊字符...
  3. php图片自动裁剪工具,php图片自动裁剪工具,解决图片变形问题,缩略图问题
  4. 历年计算机一级考试题库及答案,全国计算机一级考试试题库及答案
  5. unity3d技术摄像头跟随_堪比灯厂,新时代智能安全灯光技术,体验大众迈腾GTE IQ.LIGHT...
  6. 启明云端分享| ESP32-S3 + 480*480分辨率的2.1寸圆屏旋钮方案
  7. 最新cocoaPods安装、升级、卸载及删除库命令(持续更新)
  8. C#中不常见的运算符功能汇总
  9. 网易云容器服务基于Kubernetes的实践探索
  10. 获取当前上下文Activity
  11. github 改善网速
  12. 梭子鱼下一代防火墙在对比研究中名列榜首
  13. python数据分析推荐课程_coursera上有哪些值得学习的Python,数据分析的课程
  14. Burp Suite 扫描工具
  15. DRF总结(三)Serializer的使用
  16. php设计器中文版,PhpDesigner
  17. 未来物联网的一些问题
  18. 微信小程序的购物车功能
  19. matlab计算两向量的乘积,matlab中两个函数相乘
  20. 京东月薪8万快递员:真正牛逼的人,都拥有这个特质

热门文章

  1. 百度云管家 v5.4.5 SVIP 单文件版
  2. 不用代码快速将Excel的数据导入SQL Server数据库中
  3. JavaScript调用cs中带参数的函数
  4. 视频教程-Openlayers实例详解-其他
  5. 【Azure】微软 Azure 基础解析(三)描述云计算运营中的 CapEx 与 OpEx,如何区分 CapEx 与 OpEx
  6. User limit of inotify instances reached or too many open files
  7. 进程的IPC操作 之 共享内存
  8. Microsoft Office Visio Professional 之用例图
  9. 视频网站中的推荐系统
  10. 【研究生学术英语读写教程翻译 中国科学院大学Unit1-Unit5】