TFT_eSPI
by Bodmer
TFT_eSPI is a high-performance driver for SPI colour displays such as the ILI9341 (2.8-inch 320x240), ST7789 and ST7735. It accesses the SPI hardware directly instead of going through the generic Arduino SPI calls, so it draws much faster than a standard GFX-based driver, which makes it a popular choice on ESP32 and ESP8266 for dashboards, menus and animations. It also supports RP2040 and some STM32 boards, but not AVR boards such as the Uno or Nano, so use Adafruit's ILI9341 or ST7789 libraries there. The one thing you must understand is configuration. Your pins and display driver are not set in your sketch. They are set in a file inside the library folder, `User_Setup.h`, which you edit to match your wiring. If you skip this, you get a white or blank screen, and that is the single biggest source of problems with this library. In that file you enable your driver (for example `#define ILI9341_DRIVER`), set the pins `TFT_MOSI`, `TFT_MISO`, `TFT_SCLK`, `TFT_CS`, `TFT_DC` and `TFT_RST`, choose which fonts to load, and set the SPI speed. A ready-made example is in the code section below. There is a catch with this approach: updating or reinstalling the library overwrites `User_Setup.h`, and your settings are lost. Keep a copy of your file, or use the cleaner method of setting everything with `build_flags` in PlatformIO (shown below), which keeps the configuration inside your project. Along with the flags you must add `-DUSER_SETUP_LOADED=1` so that the library ignores `User_Setup.h`. If you use the Arduino IDE, you can also keep a setup file in the library's `User_Setups` folder and include it from `User_Setup_Select.h`. Other usual problems have short fixes. Wrong colours: if black appears white, add `#define TFT_INVERSION_ON` (many ST7789 panels need it), and if red and blue are swapped, add `#define TFT_RGB_ORDER TFT_BGR`. Text not showing or a missing font: make sure that font is enabled with the matching `LOAD_FONTx` line. Garbled picture at high speed: lower `SPI_FREQUENCY`, because long jumper wires cannot handle 40 MHz. White screen on a module with a backlight pin: connect it to 3.3 V, or define `TFT_BL`. Compile errors after updating the ESP32 board package to version 3.x have been reported by users, so if that happens, check the library's issue tracker or use board package 2.0.17. For smooth updates, never clear the whole screen to change one number, because that causes flicker. Draw into a sprite (an off-screen buffer) and push only that area, as in the example below. A sprite takes width x height x 2 bytes at the default 16-bit colour, so a full 320x240 sprite needs about 150 KB and often fails on an ESP32 without PSRAM. Use `setColorDepth(8)` or smaller sprites. The library also supports XPT2046 touch controllers through `getTouch()` once you set `TOUCH_CS`. If you need even more speed or automatic setup for many boards, look at LovyanGFX.
Installation
Arduino IDE — Library Manager
Sketch → Include Library → Manage Libraries → search TFT_eSPI
PlatformIO
lib_deps = bodmer/TFT_eSPISupported boards
Examples
Draw text on a TFT display
Run this after you have configured User_Setup.h. If the screen stays white or blank, the configuration is the first thing to check.
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
void setup() {
tft.init();
tft.setRotation(1); // 1 = landscape
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setCursor(10, 10, 4); // x, y, font number
tft.println("SolderHub");
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.drawString("TFT_eSPI works", 10, 50, 2);
}
void loop() {}User_Setup.h for ESP32 with an ILI9341 display
Edit the file in the TFT_eSPI library folder. Use the pins you actually wired. These are common example values.
#define ILI9341_DRIVER
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4 // or -1 if reset is tied to the board's 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 40000000
#define SPI_READ_FREQUENCY 20000000PlatformIO: configure in platformio.ini instead
Keeps the configuration inside your project so a library update can never overwrite it. USER_SETUP_LOADED tells the library to ignore User_Setup.h.
lib_deps = bodmer/TFT_eSPI
build_flags =
-DUSER_SETUP_LOADED=1
-DILI9341_DRIVER=1
-DTFT_MISO=19
-DTFT_MOSI=23
-DTFT_SCLK=18
-DTFT_CS=15
-DTFT_DC=2
-DTFT_RST=4
-DLOAD_GLCD=1
-DLOAD_FONT2=1
-DLOAD_FONT4=1
-DSMOOTH_FONT=1
-DSPI_FREQUENCY=40000000Flicker-free value updates with a sprite
Draw the number into a small off-screen sprite and push only that area to the screen. An 8-bit sprite uses half the memory of the default 16-bit one.
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);
void setup() {
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
spr.setColorDepth(8); // saves memory
if (!spr.createSprite(120, 40)) {
Serial.println("Not enough memory for the sprite");
}
}
void drawValue(float value) {
spr.fillSprite(TFT_BLACK);
spr.setTextColor(TFT_GREEN, TFT_BLACK);
spr.setTextDatum(MC_DATUM); // centre the text
spr.drawString(String(value, 1) + " C", 60, 20, 4);
spr.pushSprite(100, 100); // x, y on the screen
}Fix inverted or swapped colours
Add one of these lines to User_Setup.h, or the matching -D flag in PlatformIO, depending on what you see.
// Black looks white and colours look like a negative:
#define TFT_INVERSION_ON // if it was already defined, try TFT_INVERSION_OFF
// Red and blue are swapped:
#define TFT_RGB_ORDER TFT_BGR // or TFT_RGB
// Or change inversion at run time:
// tft.invertDisplay(true);