TFT-Station基于TFT显示屏的桌面时钟摆件

【DIY】基于TFT显示屏的桌面时钟摆件

1.需求分析

算是电子墨水屏摆件的TFT版本吧。。家里用的。主要因为家里缺一个桌面时钟摆件。

2.材料准备

主控: ESP8266 NodeMCU,还是8266便宜点,32的一半价格。(后面又换回32了……)

TFT屏幕: 2.8寸 SPI TFT屏幕,某宝购买分辨率320*240,带触摸功能。

外壳: 家里买了台3D打印机,随便自己设计一个壳子就行。

3.硬件连接

TFT显示屏分显示和触控两部分硬件。两部分都是要通过SPI总线进行控制。

显示部分:CS、RESET、DC、SDI、SCK、SDO。注意屏幕驱动本身其实没有什么数据读取,也就是SDO其实没有用的。

触控部分:T_CLK、T_CS、T_DO、T_DIN、T_IRQ。注意触控部分其实没有数据输入,只要读取即可,也就是T_DO其实没有用。T_IRQ一般也不使用。

这里首先要讲下TFT_eSPI库,这是目前TFT屏幕最常用的驱动库。关于引脚配置需要修改该库的配置文件,具体可以参考

注意,显示部分和触控部分是共用一个SPI总线的,通过CS来片选,并且显示部分的SDO引脚必须置空。

4.软件编写

4.0主体逻辑

时间显示,要到秒级别。

天气显示。

每日一句诗句。古诗词显示接口

上班时间显示。高德地图接口

4.1软件模块

4.1.1 TFT_eSPI移植

TFT_eSPI库。移植过程商家给了操作手册。主要就是管脚的配置和驱动IC的配置,网上也有一堆教程。

注意自己的主控,商家给的是esp32教程,我用的是esp8266,配置头文件中搜一下关键字看看注释就差不多知道怎么配置了。

4.1.3 TFT_eSprite

用这个类是因为有时间按秒刷新显示的需要,可以实现屏幕局部实时刷新,避免了全屏刷新造成的闪屏。

TFT_eSprite类继承自TFT_eSPI类,基本操作几乎一样。注意,清屏幕(局部)要用fillSprite(),否则清除不完全。

4.1.3 触控配置

参考前面硬件连接。

4.1.4 ESP8266 HttpClient库

8266和32使用wifi和http库的时候存在不同,32用的是

#include <HTTPClient.h>
#include <WiFi.h>
#include <WiFiMulti.h>

ESP8266WiFiMulti WiFiMulti;

8266用的是

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

WiFiMulti WiFiMulti;

并且8266在连接https网址的时候会报错,需要使用这个客户端并进行相应初始化

// 采用此定义是为了消除 The plain HTTP request was sent to HTTPS port 的报错
std::unique_ptr<BearSSL::WiFiClientSecure> client(new BearSSL::WiFiClientSecure);

client->setInsecure();
4.1.5 LVGL

lvgl库代码库
lvgl可以用来再嵌入式设备上设计炫酷的ui界面,很多组件可以直接使用。开发到这里的时候,添加了一些自定义的字体后,发现8266的flash和sram捉襟见肘了,遂后面还是换回了32,不想因为空间不够阻碍开发进度…

参考https://zhuanlan.zhihu.com/p/524253698,但是代码有点问题,见后面触控问题6.7。

4.1.5.1 lvgl基础库移植

移植方法网上有很多。 在调试开发阶段,lv_conf.h配置文件中LV_USE_MEM_MONITOR和LV_USE_PERF_MONITOR 可以都打开,下方可以显示使用率。

调试日志:LV_USE_LOG,可以设置级别。

性能分析:LV_USE_PERF_MONITORLV_USE_MEM_MONITOR,分别会在下面左右显示内存cpu。

4.1.5.2 lvgl+ardunio开发

可以直接把lvgl库放在arduino配置的系统库中,这样所有工程都可以用这个库,缺点是个性化配置的时候会影响到其它工程,所以准备放在本项目目录下使用。
新建了src文件夹,把lvgl和后面gui guider生成代码也都放进去。

4.1.5.3 gui guider

gui guider是恩智浦开发的基于lvgl库的ui设计软件,可以直接生成基于lvgl的模版代码,对于设计开发非常方便。
使用教程可以网上搜。
建议直接把gui guider生成的lvgl文件夹直接拿过来,供项目自身使用的,这样自己不用去关心lvgl版本问题,也就不会出现太多莫名其妙的编译问题了。

custom、generated建议全部拿出来,放到src目录下。注意修改要头文件路径。

编译超内存:要注意guiguider的内存分配设置。一般64k足够了。在ide和lv_conf.h中都可以进行配置:

#define LV_MEM_SIZE (64U * 1024U)

4.3图片显示

用gui guider导入即可。

4.4汉字显示

这一章是开始用esp8266以及没用lvgl原生开发时遇到的一些问题记录。
参考:

Arduino库 <TFT_eSPI> 中文字库的制作与使用_a null pfont was passed to textfont()-CSDN博客

https://blog.csdn.net/qq_41144322/article/details/133315745?spm=1001.2014.3001.5506

发现8266常用2000个汉字可能都放不进去,所以还是老老实实固定汉字生成字库,不多放汉字。

4.4.1字体选择

字体网站:https://font.chinaz.com/

还不错的字体:

数字:Petruck字体https://font.chinaz.com/24080345961.htm

中文:随便选了个行楷。

其他我比较喜欢的:

https://font.chinaz.com/diy/318559.html

https://font.chinaz.com/24080234459.htm

4.4.2 汉字unicode码生成

在线转化非常方便:https://tool.chinaz.com/tools/unicode.aspx

4.4.3 生成TFT_eSPI使用的头文件

TFT_eSPI如果版本比较老,那么生成时只有vlw文件,换最新master的代码中Tools文件夹即可直接生成.h文件。

另外,也可以用这个网址将vlw文件转成.h文件:

4.5页面UI设计

gui guider生成的代码框架非常清晰,但是在具体编写后续代码的时候,需要了解下lvgl库的一些基本知识,比如代码架构、设计理念、自定义代码编写规范。

看了官方的demo以及gui guider生成代码的架构,我理解自定义代码编写方式上是基于事件驱动的。

主逻辑采用timer轮询,固定时间节点执行一系列自定义操作,中间出现一些点击、滑动等事件时通过注册的回调函数处理。 这里要注意注册的回调函数里不能放入太多的页面处理逻辑,因为回调函数里对页面的调整动作是要等到下一次lvgl主函数handler才能处理,所以不能假设已经调整结束而出现一些诸如资源不存在或者panic等异常情况。 官方我也没看到一些对于编程规范的指导,如有大佬看到可以指出。
在这里插入图片描述
在这里插入图片描述

6.写在最后

6.0.自己的代码链接:

https://github.com/CharlesPu/TFT-Station

6.1 exit status 1 'class WiFiClass' has no member named "softAP" in NodeMCU

https://stackoverflow.com/questions/63118195/exit-status-1-class-wificlass-has-no-member-named-softap-in-nodemcu
这是在寻找esp8266适配的wifi和http库遇到的问题。

6.2 #define中有运算

其实是c语言编程的坑,#define在编译阶段是文本简单替换,如果理念有运算符,而使用的地方也有运算就要注意替换后的运算优先级问题。

6.3 arduniojson 解析字符串自己copy防止释放,不用char*(有待验正,我是拷贝出来以防万一)。

在使用http库时如果遇到直接重启了,大概率是接受到的字节数太多爆了,所以推荐用动态分配的json缓存对象JsonDocument doc

6.4 section .bss' is not within region dram0_0_seg'

https://www.cnblogs.com/zhengyun_ustc/p/dram0_0_seg.html
就是程序太大了,一般是字库占用了太大空间。

6.5 使用esp8266的内置flash 通过arduino配置可以开启,esp8266s3n16r8配置如下:

6.6 颜色错乱问题

这是esp32在移植lvgl例程时遇到的问题,颜色显示错乱,但是组件位置都是对的。

#define LV_COLOR_16_SWAP 1

或者my_lcd.pushColors( ( uint16_t * )&color_p->full, w * h, true) 两者二选一试下。

6.7 lvgl触控最值不准问题

初始化TFT_eSPI tft = TFT_eSPI() 时不要传入长宽,否则会出现xy方向对的,但是触控点两个方向的最大值是互换的情况。


这篇文章主要还是自己做完之后的知识点整理总结,各位DIY爱好者遇到什么问题都可以留言交流~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值