[TH] ST7735s

บทความนี้กล่าวถึงการตั้งค่าไลบรารี TFT_eSPI ของ Arduino เพื่อใช้งาน TFT LCD ที่ควบคุมด้วยชิพ ST7735s ที่ได้เคยเขียนเป็นตัวอย่างในบทความก่อนหน้านี้ด้วยภาษาไพธอน แต่จากการใช้งานของทีมงานเราพบว่า ST7735s ที่เป็น LCD IPS ขนาด 0.96″ นั้นมี 2 รุ่น ซึ่งเป็น GREENTAB160x80 กับ REDTAB160x80 โดยโมดูลทั้ง 2 ประเภทแตกต่างกันที่การเว้นวรรคช่องว่างระหว่างกันดังภาพที่ 1 ซึ่งในบทความนี้ใช้ ESP8266, ESP32 รุ่น DO-IT DevKit กับ ESP32CAM และ STM32F103C8T6 เป็นบอร์ดทดสอบการทำงานของโปรแกรม

ภาพที่ 1 โมดูลแสดงผล TFT ขนาด 0.96″ แบบ IPS

ความแตกต่างของ lcd ทั้ง 2 ประเภท คือ มีค่าเริ่มต้นการทำงานที่ไม่เหมือนกัน การกลับค่าไม่เหมือนกัน การกลับสีไม่เหมือนกัน ซึ่งการเชื่อมต่อและชิพสั่งงานเหมือนกันทำให้พวกเราเสียเวลาในการหาข้อผิดพลาดที่อาจจะเกิดจากการต่อสายและโค้ดโปรแกรม และสุดท้ายพบความแตกต่างข้างต้น จึงเกิดบทความนี้ขึ้น เพื่อใช้เป็นบันทึกการทำงานของพวกเรา ก่อนอื่นให้ติดตั้งไลบรารี TFT_eSPI เป็นอันดับแรก ดังภาพที่ 2

ภาพที่ 2 ติดตั้ง  TFT_eSPI

กำหนดค่า TFT_eSPI

ให้ดำเนินการแก้ไขการเรียกใช้การตั้งค่าไดรเวอร์ของ TFT_eSPI ในไฟล์ User_Setup_Select.h ในโฟลเดอร์ Arduino/libraries/TFT_eSPI เพื่อให้เรียกใช้การตั้งค่าเฉพาะที่กำหนดขึ้นดังภาพที่ 3

ภาพที่ 3 การกำหนดในไฟล์ User_Setup_Select.h

การตั้งค่าสำหรับ GREENTAB160x80 ให้แก้ไขไฟล์ User_Setup.h ในโฟลเดอร์ Arduino/libraries/TFT_eSPI ให้เป็นดังภาพที่ 4

ภาพที่ 4 การกำหนดค่าสำหรับ GREENTAB160x80

กรณีที่ใช้กับ REDTAB160x80 ให้ใช้การตั้งค่าในไฟล์ User_Setup.h ดังภาพที่ 5

ภาพที่ 5 การกำหนดค่าสำหรับREDTAB160x80

ตัวอย่างโปรแกรม

โปรแกรมเป็นการอ่านประเภทและขนาดของ SD-Card โดยเชื่อมต่อ SD-Card Reader ดังตารางต่อไปนี้ ซึ่งตัวอย่างบอร์ดการใช้งคือบอร์ด dCore-miniML ที่ใช้ ESP32-CAM เป็นบอร์ดหลักและขยายวงจรการโปรแกรมชิพ สวิตช์ใช้งาน (SW1/SW2) และแสดงผลด้วย TFT LCD ดังภาพที่ 6

SD-Card ReaderESP32
Vcc5V
GNDGND
MISO19
MOSI23
SCK18
CS5
ตารางที่ 1 การเชื่อมต่อกับ ESP32
ภาพที่ 6 บอร์ด dCore-miniML

หลังจากโปรแกรมทำการเชื่อมต่อและตรวจสอบประเภทพร้อมกับขนาดของการ์ดเพื่อแสดงผล จะเป็นส่วนของการวนรอบเพื่อแสดงสีพื้นฐานโดยแสดงชื่อสีประกอบ ซึ่งในส่วนของการเลือกสีสำหรับเป็นสีตัวอักษรนั้นใช้หลักของการหาสีคู่ตรงข้ามด้วยการใช้ค่าตามสมการต่อไปนี้

สีคู่ตรงข้าม = สีขาว – สีที่เป็นพื้นหลัง

ตัวอย่างโปรแกรมสำหรับ GREENTAB160x80 เป็นดังนี้

#include <SPI.h>
#include <TFT_eSPI.h>
#include "SD_MMC.h"
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory

// Use hardware SPI
TFT_eSPI tft = TFT_eSPI();

#define SW1 0
#define SW2 16

uint16_t colorsBg[] = {
  TFT_BLACK, TFT_NAVY, TFT_DARKGREEN, TFT_DARKCYAN,    
  TFT_MAROON, TFT_PURPLE,TFT_OLIVE,  TFT_LIGHTGREY,  
  TFT_DARKGREY,TFT_BLUE,TFT_GREEN, TFT_CYAN,TFT_RED,
  TFT_MAGENTA,TFT_YELLOW,TFT_WHITE,TFT_ORANGE,
  TFT_GREENYELLOW,TFT_PINK, TFT_BROWN, TFT_GOLD,
  TFT_SILVER,TFT_SKYBLUE, TFT_VIOLET  
};
uint16_t colorsFg[] = {
  TFT_WHITE - TFT_BLACK,
  TFT_WHITE - TFT_NAVY, 
  TFT_WHITE - TFT_DARKGREEN, 
  TFT_WHITE - TFT_DARKCYAN, 
  TFT_WHITE - TFT_MAROON, 
  TFT_WHITE - TFT_PURPLE,  
  TFT_WHITE - TFT_OLIVE, 
  TFT_WHITE - TFT_LIGHTGREY, 
  TFT_BLACK,
  TFT_WHITE - TFT_BLUE,  
  TFT_WHITE - TFT_GREEN,
  TFT_WHITE - TFT_CYAN, 
  TFT_WHITE - TFT_RED,
  TFT_WHITE - TFT_MAGENTA,
  TFT_WHITE - TFT_YELLOW,
  TFT_WHITE - TFT_WHITE , 
  TFT_WHITE - TFT_ORANGE, 
  TFT_WHITE - TFT_GREENYELLOW, 
  TFT_WHITE - TFT_PINK,
  TFT_WHITE - TFT_BROWN, 
  TFT_WHITE - TFT_GOLD, 
  TFT_WHITE - TFT_SILVER, 
  TFT_WHITE - TFT_SKYBLUE,
  TFT_WHITE - TFT_VIOLET
};

char colorsName[][16] = {
  {"TFT_BLACK"} ,{"TFT_NAVY"}, {"TFT_DARKGREEN"}, {"TFT_DARKCYAN"}, {"TFT_MAROON"},
  {"TFT_PURPLE"}, {"TFT_OLIVE"}, {"TFT_LIGHTGREY"}, {"TFT_DARKGREY"}, {"TFT_BLUE"},
  {"TFT_GREEN"}, {"TFT_CYAN"}, {"TFT_RED"}, {"TFT_MAGENTA"}, {"TFT_YELLOW"},
  {"TFT_WHITE"}, {"TFT_ORANGE"}, {"TFT_GREENYELLOW"}, {"TFT_PINK"}, {"TFT_BROWN"},
  {"TFT_GOLD"}, {"TFT_SILVER"}, {"TFT_SKYBLUE"}, {"TFT_VIOLET"}
};

int colorIdx = 0;
char msg[32];
uint8_t cardType;
uint64_t cardSize = 0;
bool sdCardStatus = true;

inline bool sw(int swX) {
  return (1 - digitalRead(swX));
}

void waitKey() {
  while (true) {
    if (sw(SW1) || sw(SW2)) {
      break;
    }
  }
}

void errorMsg(char title[32], char detail[64]) {
  while (true) {
    tft.fillScreen( TFT_RED  );
    tft.setTextColor( TFT_YELLOW );
    tft.drawString( title, 20 , 10, 4 );
    tft.drawString( title , 21 , 10, 4 );
    tft.setTextColor( TFT_WHITE );
    tft.drawString( detail, 20 , 40, 2 );
    waitKey();
    delay(500);
    tft.fillScreen( TFT_BLACK  );
    tft.setTextColor( TFT_YELLOW );
    tft.drawString( title, 20 , 10, 4 );
    tft.drawString( title , 21 , 10, 4 );
    tft.setTextColor( TFT_WHITE );
    tft.drawString( detail, 20 , 40, 2 );
    waitKey();
    delay(250);
  }
}

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
  pinMode( SW1, INPUT );
  pinMode( SW2, INPUT);

  if (!SD_MMC.begin()) {
    sdCardStatus = false;
  }
  
  tft.init();
  tft.setRotation(3);


  if (sdCardStatus) {
    cardType = SD_MMC.cardType();

    if (cardType == CARD_NONE) {
      tft.fillScreen( TFT_RED );
      tft.setTextColor( TFT_YELLOW );
      tft.drawString( "ERROR", 40, 8, 4);
      tft.setTextColor( TFT_WHITE );
      tft.drawString("No SD card attached!", 30, 44, 2);
    } else {
      tft.fillScreen( TFT_BLACK );
      tft.setTextColor( TFT_YELLOW );
      tft.drawString("SD Card", 40, 8, 4);
      tft.setTextColor(TFT_WHITE);
      tft.drawString("Type", 30, 40, 2);
      tft.setTextColor(TFT_CYAN);
      if (cardType == CARD_MMC) {
        tft.drawString("MMC", 80, 40, 2);
      } else if (cardType == CARD_SD) {
        tft.drawString("SDSC", 80, 40, 2);
      } else if (cardType == CARD_SDHC) {
        tft.drawString("SDHC", 80, 40, 2);
      } else {
        tft.drawString("UNKNOWN", 80, 40, 2);
      }
      cardSize = SD_MMC.cardSize();
      tft.setTextColor(TFT_WHITE);
      tft.drawString("Size", 30, 60, 2);
      tft.setTextColor(TFT_CYAN);
      tft.drawNumber( cardSize / (1024 * 1024), 80, 60, 2);
      tft.setTextColor(TFT_WHITE);
      tft.drawString("MB", 120, 60, 2);
    }
  } else {
    tft.fillScreen( TFT_RED );
    tft.setTextColor( TFT_YELLOW );
    tft.drawString( "ERROR", 40, 8, 4);
    tft.setTextColor( TFT_WHITE );
    tft.drawString(" SD Card Mount failed!", 10, 44, 2);
  }
  waitKey();
}

void loop() {
  tft.fillScreen( colorsBg[colorIdx] );
  tft.setTextColor( colorsFg[colorIdx] );
  tft.drawString( colorsName[colorIdx], 10 , 16,  2  ); // Font No.2
  tft.drawString( colorsName[colorIdx], 11 , 16,  2  ); // Font No.2
  sprintf(msg, "Sw2 = %d, Sw3 = %d\n", digitalRead( 0 ), digitalRead( 16 ));
  tft.drawString( msg, 10, 48 );
  delay(3000);
  colorIdx++;
  if (colorIdx == 24) {
    colorIdx = 0;
  }
}

ส่วน REDTAB160x80 มีความแตกต่างเล็กน้อยตรงที่ต้องตั้งค่า MAD Control ให้กลับหัวของการแสดงผล ซึ่งโค้ดตัวอย่างเป็นดังนี้ โดยบอร์ดใช้งานเป็นบอร์ดต่อทดลองดังภาพที่ 7 และกรณีที่ไม่พบ SD Card Reader จะรายงานด้งภาพที่ 8

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

TFT_eSPI tft = TFT_eSPI();

uint16_t colorsBg[] = {
  TFT_BLACK, TFT_NAVY, TFT_DARKGREEN, TFT_DARKCYAN,    
  TFT_MAROON, TFT_PURPLE,TFT_OLIVE,  TFT_LIGHTGREY,  
  TFT_DARKGREY,TFT_BLUE,TFT_GREEN, TFT_CYAN,TFT_RED,
  TFT_MAGENTA,TFT_YELLOW,TFT_WHITE,TFT_ORANGE,
  TFT_GREENYELLOW,TFT_PINK, TFT_BROWN, TFT_GOLD,
  TFT_SILVER,TFT_SKYBLUE, TFT_VIOLET  
};
uint16_t colorsFg[] = {
  TFT_WHITE - TFT_BLACK,
  TFT_WHITE - TFT_NAVY, 
  TFT_WHITE - TFT_DARKGREEN, 
  TFT_WHITE - TFT_DARKCYAN, 
  TFT_WHITE - TFT_MAROON, 
  TFT_WHITE - TFT_PURPLE,  
  TFT_WHITE - TFT_OLIVE, 
  TFT_WHITE - TFT_LIGHTGREY, 
  TFT_BLACK,
  TFT_WHITE - TFT_BLUE,  
  TFT_WHITE - TFT_GREEN,
  TFT_WHITE - TFT_CYAN, 
  TFT_WHITE - TFT_RED,
  TFT_WHITE - TFT_MAGENTA,
  TFT_WHITE - TFT_YELLOW,
  TFT_WHITE - TFT_WHITE , 
  TFT_WHITE - TFT_ORANGE, 
  TFT_WHITE - TFT_GREENYELLOW, 
  TFT_WHITE - TFT_PINK,
  TFT_WHITE - TFT_BROWN, 
  TFT_WHITE - TFT_GOLD, 
  TFT_WHITE - TFT_SILVER, 
  TFT_WHITE - TFT_SKYBLUE,
  TFT_WHITE - TFT_VIOLET
};

char colorsName[][16] = {
  {"TFT_BLACK"} ,{"TFT_NAVY"}, {"TFT_DARKGREEN"}, {"TFT_DARKCYAN"}, {"TFT_MAROON"},
  {"TFT_PURPLE"}, {"TFT_OLIVE"}, {"TFT_LIGHTGREY"}, {"TFT_DARKGREY"}, {"TFT_BLUE"},
  {"TFT_GREEN"}, {"TFT_CYAN"}, {"TFT_RED"}, {"TFT_MAGENTA"}, {"TFT_YELLOW"},
  {"TFT_WHITE"}, {"TFT_ORANGE"}, {"TFT_GREENYELLOW"}, {"TFT_PINK"}, {"TFT_BROWN"},
  {"TFT_GOLD"}, {"TFT_SILVER"}, {"TFT_SKYBLUE"}, {"TFT_VIOLET"}
};

int colorIdx = 0;
char msg[32];
uint8_t cardType;
uint64_t cardSize = 0;
bool sdCardStatus = true;

void setup() {

  pinMode( SW1, INPUT );
  pinMode( SW2, INPUT);

  if (!SD.begin()) {
    sdCardStatus = false;
  }

  tft.init();
  tft.setRotation(1);
  tft.writecommand(ST7735_MADCTL);
  tft.writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER );

  if (sdCardStatus) {
    cardType = SD.cardType();

    if (cardType == CARD_NONE) {
      tft.fillScreen( TFT_RED );
      tft.setTextColor( TFT_YELLOW );
      tft.drawString( "ERROR", 40, 8, 4);
      tft.setTextColor( TFT_WHITE );
      tft.drawString("No SD card attached!", 30, 44, 2);
    } else {
      tft.fillScreen( TFT_BLACK );
      tft.setTextColor( TFT_YELLOW );
      tft.drawString("SD Card", 40, 8, 4);
      tft.setTextColor(TFT_WHITE);
      tft.drawString("Type", 30, 40, 2);
      tft.setTextColor(TFT_CYAN);
      if (cardType == CARD_MMC) {
        tft.drawString("MMC", 80, 40, 2);
      } else if (cardType == CARD_SD) {
        tft.drawString("SDSC", 80, 40, 2);
      } else if (cardType == CARD_SDHC) {
        tft.drawString("SDHC", 80, 40, 2);
      } else {
        tft.drawString("UNKNOWN", 80, 40, 2);
      }
      cardSize = SD.cardSize();
      tft.setTextColor(TFT_WHITE);
      tft.drawString("Size", 30, 60, 2);
      tft.setTextColor(TFT_CYAN);
      tft.drawNumber( cardSize / (1024 * 1024), 80, 60, 2);
      tft.setTextColor(TFT_WHITE);
      tft.drawString("MB", 120, 60, 2);
    }
  } else {
    tft.fillScreen( TFT_RED );
    tft.setTextColor( TFT_YELLOW );
    tft.drawString( "ERROR", 40, 8, 4);
    tft.setTextColor( TFT_WHITE );
    tft.drawString(" SD Card Mount failed!", 10, 44, 2);
  }
  delay(10000);
}

void loop() {

  tft.fillScreen( colorsBg[colorIdx] );
  tft.setTextColor( colorsFg[colorIdx] );
  tft.drawString( colorsName[colorIdx], 10 , 16,  2  ); // Font No.2
  tft.drawString( colorsName[colorIdx], 11 , 16,  2  ); // Font No.2
  delay(3000);
  colorIdx++;
  if (colorIdx == 24) {
    colorIdx = 0;
  }
}
ภาพที่ 7 ผลลัพธ์จากการใช้งาน REDTAB160x80
ภาพที่ 8 การรายงานเมือไม่พบโมดูล SD-Card Reader

ตัวอย่างการใช้กับ ESP8266

การเชื่อมต่อโมดูล TFT เข้ากับ ESP8266 ทำดังตารางที่ 2 และได้ดังภาพตัวอย่างที่ 9

ST7735sESP8266
Vcc3V3
GNDGND
MOSID7
SCKD5
DCD6
RSTRST
CSD8
ตารางที่ 2การเชื่อมต่อกับ esp8266
ภาพที่ 9 ตัวอย่างการใช้ ST7735s REDTAB กับ ESP8266

ในภาพที่ 9 เป็นข้อมูลในไฟล์ User_Setup.h สำหรับเชื่อมต่อกับขาของโมดูล TFT ดังภาพที่ 10

ภาพที่ 10 การตั้งค่าเพื่อใช้กับ  esp8266

โค้ดตัวอย่างโปรแกรมเป็นดังนี้

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

TFT_eSPI tft = TFT_eSPI();


uint16_t colorsBg[] = {
  TFT_BLACK,     /*   0,   0,   0 */
  TFT_NAVY,      /*   0,   0, 128 */
  TFT_DARKGREEN,    /*   0, 128,   0 */
  TFT_DARKCYAN,      /*   0, 128, 128 */
  TFT_MAROON,      /* 128,   0,   0 */
  TFT_PURPLE,      /* 128,   0, 128 */
  TFT_OLIVE,      /* 128, 128,   0 */
  TFT_LIGHTGREY,      /* 211, 211, 211 */
  TFT_DARKGREY,      /* 128, 128, 128 */
  TFT_BLUE,      /*   0,   0, 255 */
  TFT_GREEN, /*   0, 255,   0 */
  TFT_CYAN,/*   0, 255, 255 */
  TFT_RED,/* 255,   0,   0 */
  TFT_MAGENTA,/* 255,   0, 255 */
  TFT_YELLOW,/* 255, 255,   0 */
  TFT_WHITE ,/* 255, 255, 255 */
  TFT_ORANGE,/* 255, 180,   0 */
  TFT_GREENYELLOW, /* 180, 255,   0 */
  TFT_PINK, /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
  TFT_BROWN, /* 150,  75,   0 */
  TFT_GOLD, /* 255, 215,   0 */
  TFT_SILVER, /* 192, 192, 192 */
  TFT_SKYBLUE, /* 135, 206, 235 */
  TFT_VIOLET  /* 180,  46, 226 */
};
uint16_t colorsFg[] = {
  TFT_WHITE - TFT_BLACK,   /*   0,   0,   0 */
  TFT_WHITE - TFT_NAVY,    /*   0,   0, 128 */
  TFT_WHITE - TFT_DARKGREEN,  /*   0, 128,   0 */
  TFT_WHITE - TFT_DARKCYAN,    /*   0, 128, 128 */
  TFT_WHITE - TFT_MAROON,    /* 128,   0,   0 */
  TFT_WHITE - TFT_PURPLE,    /* 128,   0, 128 */
  TFT_WHITE - TFT_OLIVE,    /* 128, 128,   0 */
  TFT_WHITE - TFT_LIGHTGREY,    /* 211, 211, 211 */
  // TFT_WHITE - TFT_DARKGREY,    /* 128, 128, 128 */
  TFT_BLACK,
  TFT_WHITE - TFT_BLUE,    /*   0,   0, 255 */
  TFT_WHITE - TFT_GREEN, /*   0, 255,   0 */
  TFT_WHITE - TFT_CYAN, /*   0, 255, 255 */
  TFT_WHITE - TFT_RED, /* 255,   0,   0 */
  TFT_WHITE - TFT_MAGENTA, /* 255,   0, 255 */
  TFT_WHITE - TFT_YELLOW, /* 255, 255,   0 */
  TFT_WHITE - TFT_WHITE , /* 255, 255, 255 */
  TFT_WHITE - TFT_ORANGE, /* 255, 180,   0 */
  TFT_WHITE - TFT_GREENYELLOW, /* 180, 255,   0 */
  TFT_WHITE - TFT_PINK, /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
  TFT_WHITE - TFT_BROWN, /* 150,  75,   0 */
  TFT_WHITE - TFT_GOLD, /* 255, 215,   0 */
  TFT_WHITE - TFT_SILVER, /* 192, 192, 192 */
  TFT_WHITE - TFT_SKYBLUE, /* 135, 206, 235 */
  TFT_WHITE - TFT_VIOLET /* 180,  46, 226 */
};

char colorsName[][16] = {
  {"TFT_BLACK"} ,
  {"TFT_NAVY"},
  {"TFT_DARKGREEN"},
  {"TFT_DARKCYAN"},
  {"TFT_MAROON"},
  {"TFT_PURPLE"},
  {"TFT_OLIVE"},
  {"TFT_LIGHTGREY"},
  {"TFT_DARKGREY"},
  {"TFT_BLUE"},
  {"TFT_GREEN"},
  {"TFT_CYAN"},
  {"TFT_RED"},
  {"TFT_MAGENTA"},
  {"TFT_YELLOW"},
  {"TFT_WHITE"},
  {"TFT_ORANGE"},
  {"TFT_GREENYELLOW"},
  {"TFT_PINK"},
  {"TFT_BROWN"},
  {"TFT_GOLD"},
  {"TFT_SILVER"},
  {"TFT_SKYBLUE"},
  {"TFT_VIOLET"}
};

int colorIdx = 0;
char msg[32];

void setup() {
  tft.init();
  tft.setRotation(1);
  tft.writecommand(TFT_MADCTL);
  tft.writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER );
}

void loop() {
  tft.fillScreen( colorsBg[colorIdx] );
  tft.setTextColor( colorsFg[colorIdx] );
  tft.drawString( colorsName[colorIdx], 10 , 16,  2  ); // Font No.2
  tft.drawString( colorsName[colorIdx], 11 , 16,  2  ); // Font No.2
  delay(3000);
  colorIdx++;
  if (colorIdx == 24) {
    colorIdx = 0;
  }
}

ตัวอย่างการใช้งานกับ STM32F103C8T6

การเชื่อมต่อ ST7735 รุ่น REDTAB80x160 เข้ากับบอร์ดไมโครคอนโทรลเลอร์ STM32F103C8T6 ตามภาพที่ 10 ซึ่งมีการต่อขาดังนี้

st7735STM32F103C8T6
GNDGND
Vcc3V3
SCLPA5
SDAPA7
RESET3V3
DCPB0
CSPB1
BLK3V3
ภาพที่ 10 การต่อ ST7735 เข้ากับบอร์ด STM32F103C8T6

ข้อมูลในไฟล์ User_Setup.h เป็นดังนี้

#define ST7735_DRIVER


#define TFT_WIDTH  80
#define TFT_HEIGHT 160


#define ST7735_REDTAB160x80
#define TFT_INVERSION_ON

#define TFT_MISO PA6
#define TFT_MOSI PA7
#define TFT_SCLK PA5
#define TFT_CS   PB1  
#define TFT_DC   PB0  
#define TFT_RST  -1  

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters

#define SMOOTH_FONT


#define SPI_FREQUENCY  27000000 

ตัวอย่างโปรแกรมสำหรับทดสอบการทำงานจะพบว่าเหมือนกับบอร์ดคอนโทรลเลอร์ตัวอื่น ๆ ซึ่งเป็นข้อดีของการใช้เฟรมเวิร์ก Arduino ทำให้มีความแตกต่างเรื่องของชุดคำสั่งน้อยลง เมื่อคอมไพล์จะพบว่าใช้รอมไป 29,032 ไบต์ (ภาพที่ 11) ซึ่งผลลัพธ์ของตัวอย่างเป็นดังภาพที่ 12

#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();  // Invoke library, pins defined in User_Setup.h

uint16_t colorsBg[] = {
  TFT_BLACK, TFT_NAVY, TFT_DARKGREEN, TFT_DARKCYAN,    
  TFT_MAROON, TFT_PURPLE,TFT_OLIVE,  TFT_LIGHTGREY,  
  TFT_DARKGREY,TFT_BLUE,TFT_GREEN, TFT_CYAN,TFT_RED,
  TFT_MAGENTA,TFT_YELLOW,TFT_WHITE,TFT_ORANGE,
  TFT_GREENYELLOW,TFT_PINK, TFT_BROWN, TFT_GOLD,
  TFT_SILVER,TFT_SKYBLUE, TFT_VIOLET  
};
uint16_t colorsFg[] = {
  TFT_WHITE - TFT_BLACK,
  TFT_WHITE - TFT_NAVY, 
  TFT_WHITE - TFT_DARKGREEN, 
  TFT_WHITE - TFT_DARKCYAN, 
  TFT_WHITE - TFT_MAROON, 
  TFT_WHITE - TFT_PURPLE,  
  TFT_WHITE - TFT_OLIVE, 
  TFT_WHITE - TFT_LIGHTGREY, 
  TFT_BLACK,
  TFT_WHITE - TFT_BLUE,  
  TFT_WHITE - TFT_GREEN,
  TFT_WHITE - TFT_CYAN, 
  TFT_WHITE - TFT_RED,
  TFT_WHITE - TFT_MAGENTA,
  TFT_WHITE - TFT_YELLOW,
  TFT_WHITE - TFT_WHITE , 
  TFT_WHITE - TFT_ORANGE, 
  TFT_WHITE - TFT_GREENYELLOW, 
  TFT_WHITE - TFT_PINK,
  TFT_WHITE - TFT_BROWN, 
  TFT_WHITE - TFT_GOLD, 
  TFT_WHITE - TFT_SILVER, 
  TFT_WHITE - TFT_SKYBLUE,
  TFT_WHITE - TFT_VIOLET
};

char colorsName[][16] = {
  {"TFT_BLACK"} ,{"TFT_NAVY"}, {"TFT_DARKGREEN"}, {"TFT_DARKCYAN"}, {"TFT_MAROON"},
  {"TFT_PURPLE"}, {"TFT_OLIVE"}, {"TFT_LIGHTGREY"}, {"TFT_DARKGREY"}, {"TFT_BLUE"},
  {"TFT_GREEN"}, {"TFT_CYAN"}, {"TFT_RED"}, {"TFT_MAGENTA"}, {"TFT_YELLOW"},
  {"TFT_WHITE"}, {"TFT_ORANGE"}, {"TFT_GREENYELLOW"}, {"TFT_PINK"}, {"TFT_BROWN"},
  {"TFT_GOLD"}, {"TFT_SILVER"}, {"TFT_SKYBLUE"}, {"TFT_VIOLET"}
};

int colorIdx = 0;
char msg[32];

void setup() {
  tft.init();
  tft.setRotation(1);
  tft.writecommand(ST7735_MADCTL);
  tft.writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER );
  tft.fillScreen(0x3861);
}

void loop() {
  tft.fillScreen( colorsBg[colorIdx] );
  tft.setTextColor( colorsFg[colorIdx] );
  tft.drawString( colorsName[colorIdx], 10 , 16,  2  ); // Font No.2
  tft.drawString( colorsName[colorIdx], 11 , 16,  2  ); // Font No.2
  delay(3000);
  colorIdx++;
  if (colorIdx == 24) {
    colorIdx = 0;
  }
}
ภาพที่ 11 ตัวอย่างหน้าจอผลของการคอมไพล์โปรแกรมของไมโครคอนโทรลเลอร์ STM32F103C8T6
ภาพที่ 12 ตัวอย่างผลลัพธ์ของการใช้กับ STM32F103C8T6

สรุป

จากบทความนี้จะพบว่า ความแตกต่างเพียงเล็กน้อยส่งผลให้การทำงานแตกต่างกันไป ดังนั้น การอ่านรายละเอียดของเอกสารและการเข้าใจการออกแบบฮาร์ดแวร์ของผู้ผลิตเป็นสิ่งที่ผู้พัฒนาระบบต้องติดตามและอัพเดตความรู้อย่างสม่ำเสมอ สุดท้ายหวังว่าบทความนี้คงมีประโยชน์กับผู้ใช้งานโมดูลแสดงผลประเภทนี้และขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดต้องการพูดคุยสามารถคอมเมนท์ได้เลยครับ

แหล่งอ้างอิง

  1. TFT_eSPI

(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ

ปรับปรุงเมื่อ 2021-08-10, 2021-08-11, 2021-08-12, 2021-09-29, 2021-12-10