ESP32彩屏顯示入門(二):顏色設置與文本顯示 | ESP32學習之旅-Arduino版

用 Arduino 玩轉 ESP32 系列歷史文章目錄:

距離上一篇彩屏顯示入門,已經拖更了一個月了。在上一篇中,我們講解了 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);
}

實際顯示效果如下:

總結

由於篇幅限制,本篇就先講這些內容。

回顧一下,我們主要講解了彩屏初始化、顏色設置、文本顯示、屏幕旋轉等相關內容。在本系列下一篇中,我將向大家介紹幾何圖形顯示與圖像顯示的編程方法。

下期見!記得點贊哦!

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章