【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_MONITOR
、LV_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字体选择
还不错的字体:
数字: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爱好者遇到什么问题都可以留言交流~