彩屏显示入门二颜色设置与文本显示-ESP32学习之旅Arduino版

43次阅读

共计 7081 个字符,预计需要花费 18 分钟才能阅读完成。

本系列历史文章目录:

  • ESP32 概述与 Arduino 软件准备
  • ESP32 GPIO 接口编程入门
  • 蓝牙翻页笔(PPT 控制器)
  • 新冠肺炎疫情数据实时显示器
  • B 站粉丝计数器
  • Siri 语音识别控制 LED 灯
  • Siri 语音识别获取传感器数据
  • 彩屏显示入门(一):驱动库设置与彩屏效果展示

距离上一篇彩屏显示入门,已经拖更了一个月了。在上一篇中,我们讲解了 ESP32 的彩屏驱动库 TFT_eSPI 的安装与配置方法,并给大家展示了几个彩屏显示的案例,但是并没有教大家如何对彩屏进行编程。那么从这次课程的内容,就教大家 TFT_eSPI 库的最基本的编程方法,比如如何设置颜色以及如何显示文字等。

话不多说那就开始吧。

材料准备

这次的教程也是入门教程,所以除了 ESP32 开发板和彩屏之外,并没有其他的传感器材料。ESP32 开发板和彩屏的选型与上次教程一致。ESP32 开发板仍然以 FireBeetle-ESP32 为例,彩屏选择的还是 ILI9341 2.4 寸 TFT_LCD 彩屏,分辨率为 240×320。如果不明白的地方,可以回去看上一篇教程:彩屏显示入门(一):驱动库设置与彩屏效果展示。

既然材料都是一样的,所以接线图和彩屏库的配置也是一样的,这里不再赘述。

彩屏初始化

在使用彩屏之前,我们先要做一些初始化相关的工作。先来看一下初始化相关代码:

#include <SPI.h>

#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup() {tft.init();

  tft.fillScreen(TFT_BLACK);
}

void loop() {}

本教程使用的彩屏接口是 SPI 接口,所以先要引入 SPI.h 库文件,然后再引入彩屏驱动 TFT_eSPI.h 库文件。接着定义一个彩屏对象 TFT_eSPI tft = TFT_eSPI(),将这个彩屏对象命名为 tft,方便后面调用。当然这里的名称可以随便取,方便记忆即可。

然后在 setup() 中调用 tft.init() 对彩屏进行初始化,注意这里的 tft 就是我们上面定义的彩屏名称,后面也是一样,不再说明。至此,其实彩屏的初始化已经完成了,不过在后面我们还再加一句代码:tft.fillScreen(TFT_BLACK),用来配置彩屏初始化的颜色。这里应该比较容易理解,我们希望初始化之后的屏幕颜色为黑色(TFT_BLACK),你也可以设置为其他颜色,比如红色(TFT_RED)、绿色(TFT_GREEN)等,如下图所示。

彩屏颜色设置

从初识化的代码中,我们看到了几个颜色的设置。在 TFT_eSPI 库中,已经预定义了一些颜色,使用这些颜色时,可以直接使用他们的颜色名称,方便我们的程序编写,比如前面讲到的黑色,它在库中的名称为 TFT_BLACK、红色的名称为 TFT_RED、绿色的名称为 TFT_GREEN 等。

// Default color definitions
#define TFT_BLACK       0x0000      /*   0,   0,   0 */
#define TFT_NAVY        0x000F      /*   0,   0, 128 */
#define TFT_DARKGREEN   0x03E0      /*   0, 128,   0 */
#define TFT_DARKCYAN    0x03EF      /*   0, 128, 128 */
#define TFT_MAROON      0x7800      /* 128,   0,   0 */
#define TFT_PURPLE      0x780F      /* 128,   0, 128 */
#define TFT_OLIVE       0x7BE0      /* 128, 128,   0 */
#define TFT_LIGHTGREY   0xD69A      /* 211, 211, 211 */
#define TFT_DARKGREY    0x7BEF      /* 128, 128, 128 */
#define TFT_BLUE        0x001F      /*   0,   0, 255 */
#define TFT_GREEN       0x07E0      /*   0, 255,   0 */
#define TFT_CYAN        0x07FF      /*   0, 255, 255 */
#define TFT_RED         0xF800      /* 255,   0,   0 */
#define TFT_MAGENTA     0xF81F      /* 255,   0, 255 */
#define TFT_YELLOW      0xFFE0      /* 255, 255,   0 */
#define TFT_WHITE       0xFFFF      /* 255, 255, 255 */
#define TFT_ORANGE      0xFDA0      /* 255, 180,   0 */
#define TFT_GREENYELLOW 0xB7E0      /* 180, 255,   0 */
#define TFT_PINK        0xFE19      /* 255, 192, 203 */    
#define TFT_BROWN       0x9A60      /* 150,  75,   0 */
#define TFT_GOLD        0xFEA0      /* 255, 215,   0 */
#define TFT_SILVER      0xC618      /* 192, 192, 192 */
#define TFT_SKYBLUE     0x867D      /* 135, 206, 235 */
#define TFT_VIOLET      0x915C      /* 180,  46, 226 */

上面的代码在注释中分别写了不同颜色的 R、G、B 值,但是你发现了没有,代码中并不是直接使用颜色的 RGB 值,而是使用了一个四位的 16 进制数,比如蓝色 TFT_BLUE 对应的数字为 0x001F,这些数字是怎么来的?又代表什么意思呢?

这跟颜色表示的标准之一 RGB 色彩模式 有关。它是工业界的一种颜色标准,是通过对红、绿、蓝三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,R、G、B 即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

而 TFT_eSPI 库中所用的颜色表示方法,就是 RGB 色彩模式 中的一种:RGB565RGB565 每个像素点都有红、绿、蓝三个原色,其中 R 原色占用 5 bitG 原色占用 6 bitB 原色占用 5 bit,也就是说一个像素点总占用 5 + 6 + 5 = 16 bit 正好是一个四位的 16 进制数

正常的 RGB 颜色是由 24 位即 3 个字节来描述一个像素,R、G、B 各 8 位。每个字节占 8 bit,正好可以表示 0~255 的范围。而实际使用中为了减少图像数据的尺寸,如视频领域,对 R、G、B 所使用的位数进行的缩减,所以就有了新的表示方法,比如 RGB565、RGB555 等。

  • RGB565 就是 R-5 bit,G-6 bit,B-5 bit,总共 16 bit,相当于 2 字节;
  • RGB555 就是 R-5 bit,G-5 bit,B-5 bit,总共 15 bit;
  • RGB888 其实就是正常的 RGB 表示,其中 R-8 bit,G-8 bit,B-8 bit,总共 24 bit,相当于 3 字节。

我们习惯了用 R、G、B 三个数值来直接表示颜色,那么这里的 RGB565 与 R、G、B 三个数值分开表示有什么区别或关联呢?其实他们之间是有计算公式的,但是本文就不讲公式了,因为 TFT_eSPI 库中直接提供了转换函数 color565(),可以让我们直接用 R、G、B 三个数值来表示颜色:

uint16_t color565(uint8_t red, uint8_t green, uint8_t blue);

比如我们要分别表示红色、绿色、蓝色、黄色,可以直接用下面的代码来表示,其中 color565 前面的 tft 就是我们前面讲过的彩屏对象名称,根据你的实际命名修改即可。

uint16_t red =    tft.color565(255, 0, 0);
uint16_t green =  tft.color565(0, 255, 0);
uint16_t blue =   tft.color565(0, 0, 255);
uint16_t yellow = tft.color565(255, 255, 0);

有了转换函数 color565() 后,我们就可以像平时一样来表示颜色了。试试看下面的两句代码设置的屏幕颜色是不是一致呢?

tft.fillScreen(tft.color565(128, 0, 128));
tft.fillScreen(TFT_PURPLE);

彩屏文本显示

TFT_eSPI 库中,包含了许多跟文本显示相关的函数,这里只介绍最常用的几个,其余的在本文不展开了,感兴趣的读者可以自行去阅读 TFT_eSPI 库中包含的代码。

首先是文本坐标设置相关函数,最常用的是下面两个函数。这两个函数可以用来设置显示文字的 x、y 坐标,以及文本使用的字体。

 // 设置文本显示坐标,默认以文本左上角为参考点,可以改变参考点
void setCursor(int16_t x, int16_t y);

// 设置文本显示坐标,和文本的字体
void setCursor(int16_t x, int16_t y, uint8_t font); 

彩屏的默认坐标系统如下图所示:

然后是设置文本颜色相关的函数,其中的颜色用上面讲到的 RGB565 方式表示。除了设置文本颜色之外,还可以设置文本的背景色(bgcolor = background color)。

// 设置文本颜色
void setTextColor(uint16_t color);

// 设置文本颜色与背景色
void setTextColor(uint16_t fgcolor, uint16_t bgcolor);

接着是设置文本大小:

// 设置文本大小,文本大小范围为 1~7 的整数
void setTextSize(uint8_t size);

字体设置也是 TFT_eSPI 库的一大特色,不仅可以使用预定义的默认字体,还能自己设计字体。由于比较复杂,这里先不展开,后面有机会用专门的篇章来讲解,这里只放出两个最常用的字体设置函数:

// 选择 GFX Free Font
void setFreeFont(const GFXfont *f = NULL);

// 设置字体编号 font,编号范围是 1、2、4、6、7、8,不同的编号代表不同的字体
void setTextFont(uint8_t font);

其中在 User_Setup.h 或你自己的彩屏配置文件中,可以定义下面几种默认字体,每种字体的范围,注释中都有详细的说明:

// Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_GLCD

// Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT2

// Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT4

// Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT6

// Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT7

// Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8

// Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
//#define LOAD_FONT8N

// FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define LOAD_GFXFF

// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT

最后当然是最重要的设置文本内容了,这里其实跟 Serial 串口打印语法是完全一致的,只需要用 print()println() 即可。比如

tft.print("Hello World!"); // 显示:Hello World!tft.print("1234567890"); // 显示:1234567890

下面用一个综合的案例,来展示字体设置的效果。具体显示内容代码中都有详细注释:

#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup(void) {
  // 初始化彩屏
  tft.init();
  tft.fillScreen(TFT_BLACK);
  
  // 设置起始坐标(20, 10),4 号字体
  tft.setCursor(20, 10, 4);
  // 设置文本颜色为白色,黑色文本背景
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  // 设置显示的文字,注意这里有个换行符 \n 产生的效果
  tft.println("White Text\n");
  tft.println("Next White Text");
  
  // 设置起始坐标(10, 100),2 号字体,文本颜色红色,白色文本背景
  tft.setCursor(10, 100);
  tft.setTextFont(2);
  tft.setTextColor(TFT_RED, TFT_WHITE);
  tft.println("Red Text, White Background");
  
  // 设置起始坐标(10, 140),4 号字体,文本颜色绿色,无背景设置
  tft.setCursor(10, 140, 4);
  tft.setTextColor(TFT_GREEN);
  tft.println("Green text");
  
  // 设置起始坐标(70, 180),字体不变,文本颜色蓝色,黄色文本背景
  tft.setCursor(70, 180);
  tft.setTextColor(TFT_BLUE, TFT_YELLOW);
  tft.println("Blue text");

  // 设置起始坐标(50, 220),4 号字体,文本颜色黄色,无背景设置
  tft.setCursor(50, 220);
  tft.setTextFont(4);
  tft.setTextColor(TFT_YELLOW);
  tft.println("2020-06-16");

  // 设置起始坐标(50, 260),7 号字体,文本颜色粉色,无背景设置
  tft.setCursor(50, 260);
  tft.setTextFont(7);
  tft.setTextColor(TFT_PINK);
  tft.println("20:35");
}

void loop() {}

实际显示效果如下:

屏幕旋转

除了默认的方向外,我们还能设置彩屏显示的旋转角度,在 0°、90°、180°、270° 之间变化。注意,屏幕显示旋转设置之后,坐标零点也会跟着改变

// 设置屏幕显示的旋转角度,参数为:0, 1, 2, 3
// 分别代表 0°、90°、180°、270°
void setRotation(uint8_t r); 

通过一个具体的案例来展示一下效果:

#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup(void) {
  // 初始化彩屏
  tft.init();
  tft.fillScreen(TFT_BLACK);

  // 设置 4 号字体,绿色文本颜色
  tft.setTextFont(4);
  tft.setTextColor(TFT_GREEN);
}

void loop() {
   // 设置屏幕旋转 0 度(默认角度)tft.setRotation(0);
   tft.setCursor(18, 147);
   tft.fillScreen(TFT_BLACK);
   tft.println("Rotation: 0 degree");

   delay(1000);

   // 设置屏幕旋转 90 度
   tft.setRotation(1);
   tft.setCursor(55, 107);
   tft.fillScreen(TFT_BLACK);
   tft.println("Rotation: 90 degree");

   delay(1000);

   // 设置屏幕旋转 180 度
   tft.setRotation(2);
   tft.setCursor(0, 147);
   tft.fillScreen(TFT_BLACK);
   tft.println("Rotation: 180 degree");

   delay(1000);

   // 设置屏幕旋转 270 度
   tft.setRotation(3);
   tft.setCursor(45, 107);
   tft.fillScreen(TFT_BLACK);
   tft.println("Rotation: 270 degree");

   delay(1000);
}

实际显示效果如下:

总结

由于篇幅限制,本篇就先讲这些内容。

回顾一下,我们主要讲解了彩屏初始化、颜色设置、文本显示、屏幕旋转等相关内容。在本系列下一篇中,我将向大家介绍几何图形显示与图像显示的编程方法。

下期见!记得点赞哦!

参考资料

  • https://blog.csdn.net/ctthuan…
  • https://blog.csdn.net/byhook/…
  • https://juejin.im/post/5e144d…

正文完
 0