Documentation / Hardware

Boards and displays

Every field on the Board, Display, Touch and Inputs tabs, and the tables behind them.

The Hardware tab describes the board the firmware will run on. A preset fills most of it in; this page explains every field so you can fill in a board that is not listed, or fix a preset that does not match the revision in your hand.

Verify the pinout. Vendors change pinouts between revisions of the same board and sell several variants under one name. Every preset carries a note saying what to check, and the generated README.md repeats it. Two minutes with the board's schematic before the first flash is the cheapest debugging you will do.

Board

The Board tab has the preset list, filterable by brand, and below it the three things a preset decides first: the MCU, whether PSRAM is enabled, and the FQBN - the fully qualified board name the Arduino CLI and PlatformIO use, such as esp32:esp32:esp32s3. Choosing a preset overwrites the Display, Touch and Inputs tabs and the graphics library; it leaves your buses, devices, I/O, variables and automations alone.

The Board tab with a preset chosen. The verify note sits under the list; MCU, PSRAM and FQBN follow.
The Board tab with a preset chosen. The verify note sits under the list; MCU, PSRAM and FQBN follow.

Presets

PresetMCUPanelResolutionTouchLibraryVerify
ESP32 + ILI9341 2.8" SPIESP32 (WROOM / WROVER)ILI9341, SPI240 × 320XPT2046TFT_eSPIWiring template rather than a fixed board - adjust to match how you actually wired it.
ESP32-2432S028R "Cheap Yellow Display"ESP32 (WROOM / WROVER)ILI9341, SPI240 × 320XPT2046TFT_eSPITouch runs on its own VSPI bus, separate from the display HSPI bus. The 2432S028 also ships in a capacitive CST820 variant.
ESP32-2432S028C (capacitive CYD)ESP32 (WROOM / WROVER)ILI9341, SPI240 × 320CST820TFT_eSPIThe capacitive CYD shares GPIO21 between touch INT and the backlight on some revisions - check your board.
WT32-SC01ESP32 (WROOM / WROVER)ST7796 / ST7796S, SPI320 × 480FT6236 / FT6336ULovyanGFXMISO is not broken out - leave it at -1.
M5Stack Core2ESP32 (WROOM / WROVER)ILI9342 / ILI9342C, SPI320 × 240FT6236 / FT6336ULovyanGFXBacklight and panel reset are driven by the AXP192 over I2C, not by a GPIO. Initialise the PMIC before LVGL.
ESP32-S3 + ILI9341 SPIESP32-S3ILI9341, SPI240 × 320XPT2046LovyanGFXWiring template - change the pins to match your build.
ESP32-S3 + GC9A01 1.28" roundESP32-S3GC9A01 / GC9A01A, SPI240 × 240CST816SGFX Library for ArduinoThe CST816S needs its RESET line wired or it will not answer on I2C.
Sunton ESP32-8048S043 (4.3" RGB)ESP32-S3ST7262, RGB800 × 480GT911GFX Library for ArduinoPSRAM must be enabled (OPI, 80 MHz) or the RGB framebuffer will not allocate.
Sunton ESP32-8048S070 (7" RGB)ESP32-S3ST7262, RGB800 × 480GT911GFX Library for ArduinoThe RGB data pin order differs from the 4.3" board. Confirm against your board revision before flashing.
WT32-SC01 PlusESP32-S3ST7796 / ST7796S, PAR8320 × 480FT6236 / FT6336ULovyanGFXCS is tied low on the board, so leave it at -1.
LilyGO T-Display-S3ESP32-S3ST7789, PAR8170 × 320CST816SGFX Library for ArduinoGPIO15 must be driven HIGH to enable the LCD power rail before init. The generated sketch does this for you.
LilyGO T-Display-S3 AMOLEDESP32-S3RM67162, QSPI240 × 536CST226SEGFX Library for ArduinoAMOLED brightness is set by a controller command, not a backlight GPIO.
Waveshare ESP32-S3-Touch-LCD-4.3ESP32-S3Generic RGB565 panel, RGB800 × 480GT911GFX Library for ArduinoTouch RESET and backlight hang off a CH422G I/O expander on I2C, not off GPIOs.
ESP32-S3 + ST7701S 480x480 roundESP32-S3ST7701 / ST7701S, RGB480 × 480CST328GFX Library for ArduinoCS/SCK/MOSI carry the ST7701 init commands only; pixels go over the RGB bus.
STM32F407 + ILI9341 SPISTM32F4 (F401 / F407 / F411)ILI9341, SPI240 × 320XPT2046LovyanGFXNeeds the STM32duino core. SPI1 pins are remappable - check your variant.
STM32F407 + ILI9341 16-bit FSMCSTM32F4 (F401 / F407 / F411)ILI9341, PAR16240 × 320XPT2046LovyanGFXThese are the standard FSMC bank-1 pins. A16 (PD11) is wired to the RS/DC line.
STM32H7 + 800x480 RGB (LTDC)STM32H7Generic RGB565 panel, RGB800 × 480FT5206 / FT5406 / FT5x06LovyanGFXLTDC pin assignments are fixed per package. Generated code is a starting point - confirm against your datasheet.
Raspberry Pi Pico + ILI9341RP2040 (Pico / Pico W)ILI9341, SPI240 × 320XPT2046TFT_eSPIOnly 264 KB of RAM - keep the LVGL draw buffer at roughly 1/10 screen.
Pico + GC9A01 roundRP2040 (Pico / Pico W)GC9A01 / GC9A01A, SPI240 × 240noneTFT_eSPIPair it with a rotary encoder for input.

Custom / breadboard wiring starts from an ESP32-S3 with LovyanGFX and nothing assigned, for hardware you wired yourself.

MCUs

The MCU decides which GPIOs exist, which are input-only, which carry warnings (flash, strapping, UART), which have ADC channels, whether PSRAM is possible, and which graphics libraries and buses are available.

MCUPSRAMInput-only pinsNotes
ESP32 (WROOM / WROVER)yes34, 35, 36, 37, 38, 39No native RGB parallel peripheral - use SPI or an 8/16-bit i80 bus.
ESP32-S3yes-The only common Arduino target with a hardware RGB565 LCD peripheral. PSRAM is effectively required for RGB panels.
ESP32-S2yes46Single core - keep lv_timer_handler() off the same loop as heavy work.
ESP32-C3no-No PSRAM. Keep the draw buffer small and prefer displays up to 320x240.
ESP32-C6no-No PSRAM. SPI displays only in practice.
ESP32-P4yes-Has a MIPI-DSI host and a 2D graphics accelerator (PPA). Arduino core support is newer - verify your core version.
STM32F4 (F401 / F407 / F411)no-Use the STM32duino core. FSMC gives a fast parallel bus on F407 and up.
STM32F7no-Has an LTDC controller for true RGB panels plus DMA2D (Chrom-ART) acceleration.
STM32H7no-The strongest Arduino-compatible target for large panels. LTDC + DMA2D + external SDRAM.
RP2040 (Pico / Pico W)no-PIO can drive an 8-bit parallel bus. Limited RAM - use a small partial draw buffer.
RP2350 (Pico 2)yes-More RAM than RP2040 and optional PSRAM on boards such as the Pimoroni Pico Plus 2.

Display

The Display tab: the panel Controller, the Bus, the pins for that bus, the Width and Height, Rotation (0, 90, 180 or 270), Colour depth, Colour order (RGB or BGR - the fix for red and blue being swapped), Invert (the fix for a negative image), and the bus options - the SPI clock in MHz, the SPI mode, and 3-wire for a 9-bit serial panel with no DC pin. The validator checks the resolution against what the controller documents and warns when it is not one of them.

The Display tab: controller and bus at the top, the pin list, then geometry, colour and backlight.
The Display tab: controller and bus at the top, the pin list, then geometry, colour and backlight.

Buses and their pins

BusPins
SPISCK, MOSI, MISO (optional), CS, DC, RST (optional)
QSPISCK, D0, D1, D2, D3, CS, RST (optional)
PAR8WR, RD (optional), DC, CS, RST (optional), D0, D1, D2, D3, D4, D5, D6, D7
PAR16WR, RD (optional), DC, CS, RST (optional), D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15
RGBDE, VSYNC, HSYNC, PCLK, R0, R1, R2, R3, R4, G0, G1, G2, G3, G4, G5, B0, B1, B2, B3, B4, CS (optional), SCK (optional), MOSI (optional), RST (optional)
DSIRST (optional), SDA (optional), SCL (optional)
I2CSDA, SCL, RST (optional)

Set a pin to -1 when the board does not wire it (a display MISO that is not broken out, a CS tied low). The validator treats optional pins as optional and complains about required ones.

Control lines on an I/O expander

On a growing number of boards the panel reset, the backlight enable and the touch reset are not wired to GPIOs at all - they sit behind an I/O expander on I2C. The Waveshare ESP32-S3-Touch-LCD-4.3 puts all three on a CH422G. For those, the RESET pin of the display and of the touch controller, and the backlight pin, can be set to a pin on one of the project's I/O extenders instead of a GPIO: the pin picker gains an On an I/O extender group once an extender exists on the I/O tab. The generated sketch then brings the expander's bus and the expander up first (hw_init_early()), pulses the resets through it, and drives the backlight through it - on or off, since an expander pin cannot PWM. The pin header records where each line went (#define LCD_RST -1 // RESET - on CH422G pin 3) and the README wiring table says CH422G pin 3 rather than a GPIO.

Presets bring their own kit

Some presets add more than pins. Choosing the Waveshare 4.3" adds the I2C bus on GPIO 8/9 and the CH422G on it, with the three control lines already routed; the two Cheap Yellow Displays add their CN1 connector as an I2C bus on GPIO 27/22; the M5Stack Core2 adds Port A on 32/33. These items are tagged with the board they belong to: they survive re-applying the same preset, are dropped when you choose a different board, and never touch buses or devices you added yourself. Add a sensor to a board bus exactly as you would to one of your own.

Backlight

Pin, Active level, and PWM dimming, which on an ESP32 uses an LEDC channel at the PWM frequency you set, starting at the Default %. Without PWM the pin is simply driven to the active level. An AMOLED has no backlight pin; brightness is a controller command, which the driver handles.

Panel controllers

Thirty-six, across SPI, QSPI, 8- and 16-bit parallel, RGB565 and MIPI-DSI. Each entry knows which buses it supports, the resolutions it is sold in, and the driver symbol every graphics library expects for it.

ControllerBusesDocumented resolutions
ILI9341SPI, PAR8, PAR16240×320, 320×240
ILI9341 (alt init)SPI, PAR8240×320
ILI9342 / ILI9342CSPI320×240
ILI9481SPI, PAR8, PAR16320×480
ILI9486SPI, PAR8, PAR16320×480
ILI9488SPI, PAR8, PAR16320×480
ST7735SPI128×160, 128×128, 80×160
ST7735SSPI128×160, 80×160
ST7789SPI, PAR8240×320, 240×240, 135×240, 172×320
ST7796 / ST7796SSPI, PAR8, PAR16320×480
GC9A01 / GC9A01ASPI240×240
GC9107SPI128×128
HX8357DSPI, PAR8320×480
ILI9225SPI176×220
R61581PAR8, PAR16320×480
NT35510PAR8, PAR16480×800
SSD1963PAR8, PAR16480×272, 800×480, 800×600
RA8875SPI, PAR8480×272, 800×480
SSD1351SPI128×128, 128×96
SSD1331SPI96×64
SSD1306I2C, SPI128×64, 128×32
SH1106I2C, SPI128×64
ST77916QSPI360×360, 400×400
SH8601QSPI368×448, 390×390
CO5300QSPI466×466, 410×502
RM67162QSPI, SPI240×536
NV3041AQSPI480×272
AXS15231BQSPI320×480, 180×640
Generic RGB565 panelRGB800×480, 480×272, 1024×600, 480×480
ST7262RGB800×480
EK9716BD3 / EK73002RGB800×480
ST7701 / ST7701SRGB480×480, 480×800, 368×448
GC9503VRGB480×480
EK79007DSI1024×600
ILI9881CDSI800×1280
JD9365DSI800×1280

Graphics library

The library that drives the panel and gives LVGL its flush callback. Which ones are offered depends on the MCU and the bus:

LibraryBusesMCUsNotes
LovyanGFXSPI, PAR8, PAR16, RGB, I2Cesp32, esp32s3, esp32s2, esp32c3, esp32c6, rp2040, rp2350, stm32f4, stm32f7, stm32h7Widest panel and bus coverage, DMA on ESP32. Configured with a C++ config class.
TFT_eSPISPI, PAR8, PAR16esp32, esp32s3, esp32s2, esp32c3, rp2040, rp2350, stm32f4, stm32f7Fastest for SPI panels on ESP32. Configured via User_Setup.h build defines.
GFX Library for ArduinoSPI, QSPI, PAR8, PAR16, RGB, I2Cesp32, esp32s3, esp32s2, esp32c3, esp32c6, rp2040, rp2350Moshi Liu's library. Best QSPI/AMOLED and RGB coverage. Configured in code.
esp_lcd (ESP-IDF component)SPI, QSPI, PAR8, PAR16, RGB, DSI, I2Cesp32, esp32s3, esp32s2, esp32c3, esp32c6, esp32p4The vendor driver bundled with the ESP32 Arduino core. Lowest overhead, ESP32 only.

TFT_eSPI is configured by a generated User_Setup.h (and the same defines in platformio.ini); LovyanGFX by a generated LGFX_Config.hpp device class; GFX Library for Arduino and esp_lcd in the sketch itself.

Touch

The Touch tab: the Controller, then the pins and options for its bus. An I2C controller takes SDA, SCL, an optional INT and an optional RESET, its I2C address, the I2C clock and whether it shares the display's I2C bus; an SPI controller takes SCK, MOSI, MISO, CS and an optional IRQ, the SPI clock and whether it shares the display's SPI bus (on by default, and right for most boards). Sharing is what lets the validator accept the same SCK on both without flagging a collision.

Below that, Swap X/Y, Invert X and Invert Y fix a touch that lands in the wrong place after rotation, and for a resistive controller a Calibration block holds the raw minimum and maximum in each axis.

The Touch tab for an I2C controller: pins, address and clock, then the axis switches.
The Touch tab for an I2C controller: pins, address and clock, then the axis switches.

Most capacitive controllers are read by generated register code over Wire and need no library; the ones that do list it in LIBRARIES.md.

ControllerBusLibrary
GT911I2CTAMC_GT911
GT9271I2Cbb_captouch
FT6206I2CAdafruit_FT6206
FT6236 / FT6336UI2CFT6236
FT5206 / FT5406 / FT5x06I2Cbb_captouch
CST816SI2CCST816S
CST820I2Cbb_captouch
CST226SEI2Cbb_captouch
CST328I2Cbb_captouch
TT21100I2Cesp_lcd_touch_tt21100
CHSC6540I2Cbb_captouch
AXS15231B (touch half)I2Cbb_captouch
FT3267I2Cbb_captouch
XPT2046SPIXPT2046_Touchscreen
ADS7846SPIXPT2046_Touchscreen
STMPE610SPIAdafruit_STMPE610
NS2009I2Cesp_lcd_touch_ns2009
TSC2007I2CAdafruit_TSC2007

Inputs

The Inputs tab adds LVGL input devices that are not touch:

How pins are checked

Every assigned pin is checked against the MCU on every edit, and the result appears in the Check tab, the Errors tab and the export dialog:

Rendering settings

In the export settings (Export > Export UI code > settings): Buffer height is the partial draw buffer in lines - 40 by default, and the first thing to lower on a small MCU; Double buffer allocates two so LVGL can render one while the other flushes; Buffer in PSRAM puts them in external RAM on boards that have it. The sketch reports draw buffer allocation failed - lower DRAW_BUF_LINES on the serial monitor if it cannot get the memory.