[TH] Arduino: Using the ST7735s module with an ESP32-S2 via the TFT_eSPI library.

บทความนี้เป็นการใช้โมดูล ST7735s กับไมโครคอนโทรลเลอร์ ESP32-S2 ผ่านไลบรารี TFT_eSPI โดยในก่อนหน้านี้ได้กล่าวถึงการใช้งานกับไมโครคอนโทรลเลอร์ ESP32 และ STM32F103C ไปแล้ว และโมดูล TFT ที่เลือกใช้เป็น REDTAB80x160 (ได้เพิ่มเติมโค้ดสำหรับ GREENTAB80x160 ในตอนท้ายบทความ) แต่สามารถปรับดารตั้งค่าเป็นโมดูลอื่น ๆ ได้ โดยดูรายละเอียดจากไฟล์ User_Setup.h ของไลบรารี TFT_eSPI ดังภาพที่ 1

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

การเชื่อมต่อ

การเชื่อมต่อระหว่างโมดูลแสดงผล TFT ที่ใช้ st7735s แบบ REDTAB80x160 กับไมโครคอนโทรลเลอร์ ESP32-S2 เป็นตามตารางต่อไปนี้

TFT st7735s REDTAB80x160ESP32-S2
Vcc3V3
GNDGND
MISO-1
MOSI35
SCK36
CS34
RES38
DC33
ตารางที่ 1 การเชื่อมต่อกับ ESP32-S2

กำหนดค่า TFT_eSPI

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

#define ST7735_DRIVER 

#define TFT_RGB_ORDER TFT_RGB 
#define TFT_WIDTH  80
#define TFT_HEIGHT 160

#define ST7735_REDTAB160x80   // For 160 x 80 display with 24 pixel offset

#define TFT_INVERSION_ON

// ESP32-S2
#define TFT_MISO -1 // 37
#define TFT_MOSI 35
#define TFT_SCLK 36
#define TFT_CS   34  // Chip select control pin
#define TFT_DC   33  // Data Command control pin
#define TFT_RST  38  // Reset pin (could connect to Arduino RESET pin)

#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 LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

#define SMOOTH_FONT

#define SPI_FREQUENCY  27000000

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

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

#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;
  }
}

ตัวอย่างที่ 2 เป็นการแสดงข้อมูลหน่วยความจำของบอร์ด ESP32-S2 ทางจอแสดงผลดังภาพที่ 2 โดยโค้ดโปรแกรมเป็นดังต่อไปนี้

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

TFT_eSPI tft = TFT_eSPI();

void setup() {
  char msg[64];
  tft.init();
  tft.setRotation(1);
  tft.writecommand(TFT_MADCTL);
  tft.writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER );
  tft.fillScreen( TFT_MAROON );

  sprintf(msg,"Total heap: %d", ESP.getHeapSize());
  tft.setTextColor( TFT_WHITE );
  tft.drawString( msg, 4 , 0,  2  );
  
  sprintf(msg,"Free heap: %d", ESP.getFreeHeap());
  tft.setTextColor( TFT_CYAN );
  tft.drawString( msg, 4 , 12,  2  );

  sprintf(msg,"Total PSRAM: %d", ESP.getPsramSize());
  tft.setTextColor( TFT_WHITE );
  tft.drawString( msg, 4 , 24,  2  );

  sprintf(msg,"Free PSRAM: %d", ESP.getFreePsram());
  tft.setTextColor( TFT_CYAN );
  tft.drawString( msg, 4 , 36,  2  );

  tft.setTextColor( TFT_YELLOW );
  tft.drawString("www.jarutex.com",4,60,2);
}

void loop() {
  // put your main code here, to run repeatedly:

}
ภาพที่ 2 ตัวอย่างผลลัพธ์เมื่อแสดงปริมาณหน่วยความจำ RAM และ SPIRAM

โค้ดสำหรับ GREENTAB80X160

ไฟล์ User_Setup.h เป็นดังนี้

#define ST7735_DRIVER 

#define TFT_RGB_ORDER TFT_BGR
#define TFT_WIDTH  80
#define TFT_HEIGHT 160

#define ST7735_GREENTAB160x80   // For 160 x 80 display with 24 pixel offset

#define TFT_MISO -1 // 37
#define TFT_MOSI 35
#define TFT_SCLK 36
#define TFT_CS   34  // Chip select control pin
#define TFT_DC   33  // Data Command control pin
#define TFT_RST  38  // Reset pin (could connect to Arduino RESET pin)

#define LOAD_GLCD 
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF  
#define SMOOTH_FONT
#define SPI_FREQUENCY  27000000

ตัวอย่างโปรแกรมปรับแก้ด้วยการตัดส่วนของ writecommand()/writedata ใน setup() จึงได้โค้ดดังต่อไปนี้

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

TFT_eSPI tft = TFT_eSPI();

void setup() {
  char msg[64];
  tft.init();
  tft.setRotation(1);
  
  tft.fillScreen( TFT_MAROON );
  tft.setTextColor( TFT_CYAN );
  tft.drawString("HEAP info.",4,0,2);

  sprintf(msg,"%.2f/%.2fKB", ESP.getFreeHeap()/1024.0, ESP.getHeapSize()/1024.0);
  tft.setTextColor( TFT_WHITE );
  tft.drawString( msg, 12 , 12,  2  );

  tft.setTextColor( TFT_CYAN );
  tft.drawString("PSRAM info.",4,32,2);

  sprintf(msg,"%.2f/%.2fMB", ESP.getFreePsram()/1048576.0, ESP.getPsramSize()/1048576.0);
  tft.setTextColor( TFT_WHITE );
  tft.drawString( msg, 12 , 44,  2  );

  tft.setTextColor( TFT_YELLOW );
  tft.drawString("www.jarutex.com",22,60,2);
}

void loop() {

}

ตัวอย่างผลลัพธ์เป็นดังภาพที่ 2

ภาพที่ 2 ตัวอย่างผลลัพธ์จากตัวอย่างโปรแกรมของ ESP32-S2 กับบอร์ด GREENTAB

สรุป

จากบทความนี้จะพบว่า การใช้งานโมดูล TFT กับ ESP32-S2 นั้นเหมือนกับไมโครคอนโทรลเลอร์ตัวอื่น ๆ เนื่องจากไลบรารี TFT_eSPI รองรับการเชื่อมต่อและมีชุดคำสั่งให้ใช้งาน แต่ต้องกำหนดขาให้ตรงกับการทำงาน ส่วนเรื่องประสิทธิภาพนั้นขึ้นอยู่กับการเลือกใช้งานโมดูลเสริมของไมโครคอนโทรลเลอร์ เช่น การเลือกรุ่นที่มีเฉพาะหน่วยความจำภายในจะทำงานได้เร็วกว่ารุ่นที่มี SPIRAM ที่เพิ่มเติมภายนอกเนื่องจากเป็นการสื่อสารภายในโมดูลไม่ได้เชื่อมต่อกับบัสภายนอก แต่ต้องแลกด้วยปริมาณหน่วยความจำที่น้อยกว่า เป็นต้น และสุดท้ายขอให้สนุกกับการเขียนโปรแกรมครับ

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

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

  1. TFT_eSPI

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

ปรับปรุงเมื่อ 2022-01-04, 2022-01-05. 2022-01-06, 2022-02-15, 2024-04-06