RisalDash RisalDash

Guide · Displays · Wiring

How to connect a display to your ESP32

Nearly every hobby display works with both Arduino (5 V) and ESP32 (3.3 V) — and the ESP32 is the better host for graphics, touch and Wi-Fi. There are four types you will actually meet: a mono OLED, a colour TFT, a touch TFT and an E-Ink panel. Here is exactly how each one wires up and the first few lines of code to light it.

DisplaysOLEDTFTTouchE-InkESP32
Four display types for ESP32 and Arduino: OLED, colour TFT, touch TFT and E-Ink
Four screens, four jobs — pick by bus, colour, refresh and power.

Only choosing? The sister guide compares them head-to-head — OLED vs TFT vs E-Paper vs Nextion. This page is the hands-on half: the wiring and a working sketch for each.

TypeChipsetsBusColourRefreshBest for
OLEDSSD1306 · SH1106I²Cmonofastclocks, status, tiny UIs
Colour TFTST7789 · ILI9341 · ST7735SPI65kfastdashboards, charts, images
Touch TFTILI9341 + XPT2046SPI (+touch)65kfastsmart-home panels, remotes
E-InkWaveshare · GDEHSPImono / fewslowbattery signage, tags, clocks

1. OLED (SSD1306 / SH1106) — two wires, real black

The classic 0.96" OLED talks I²C, so it needs only two signal wires — SDA and SCL — plus power. It is high-contrast (pixels are truly off, no backlight), sips power and costs pocket change. 128×64 pixels holds a few lines of text or a small graph — ideal for clocks, weather readouts and a Wi-Fi/IP status line. The SH1106 is a near-drop-in cousin (a small column offset the library handles).

SSD1306 OLED wired to an ESP32 over I²C: SDA, SCL, 3V3 and GND
Two wires plus power. Default ESP32 I²C is SDA = GPIO21, SCL = GPIO22. Built in BoardLab.
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 oled(128, 64, &Wire);   // I2C, address 0x3C (SH1106 is near-identical)

void setup() {
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.clearDisplay();
  oled.setTextSize(2);
  oled.setTextColor(SSD1306_WHITE);
  oled.setCursor(0, 0);
  oled.println("24.7 C");
  oled.display();                        // push the frame to the panel
}

2. Colour TFT (ST7789 / ILI9341 / ST7735) — full colour over SPI

A colour TFT over SPI gives you 65,000 colours and a refresh fast enough for live charts, menus and images — the workhorse when you want a real dashboard. It costs more pins than I²C (SCK, MOSI, DC, CS, RES + backlight) and the backlight draws steady current, but the payoff is a proper UI. The go-to library is TFT_eSPI, where you set the pins once in User_Setup.h. Cheap modules often label SCK/MOSI as SCL/SDA — same SPI, just confusing silkscreen.

ST7789 colour TFT wired to an ESP32 over SPI: SCL, SDA, RES, DC, backlight, 3V3 and GND
SPI display: clock, data, DC and RES on GPIOs; backlight to 3V3.
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();               // SPI pins are set once in User_Setup.h

void setup() {
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_CYAN, TFT_BLACK);
  tft.setTextSize(3);
  tft.drawString("24.7 C", 20, 20);      // a full 65k-colour UI
}

3. Touch TFT (ILI9341 + XPT2046) — a panel you tap

Add a touch layer and the TFT becomes a control surface: home-automation panels, thermostats, handheld remotes. The trick worth knowing — the display and the XPT2046 touch controller share the same SPI bus (SCK/MOSI/MISO); the touch chip only needs its own T_CS chip-select and an optional T_IRQ interrupt. That keeps the pin count sane. The famous Cheap Yellow Display is exactly this: an ESP32 + 2.8" ILI9341 + XPT2046 on one board.

ILI9341 touch TFT on an ESP32: display and XPT2046 touch sharing one SPI bus, with separate T_CS and T_IRQ
One SPI bus for both chips — only T_CS and T_IRQ are extra.
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();               // screen + XPT2046 touch share one SPI bus

void loop() {
  uint16_t x, y;
  if (tft.getTouch(&x, &y)) {            // T_CS + T_IRQ report the press
    tft.fillCircle(x, y, 4, TFT_CYAN);   // draw where the finger landed
  }
}

4. E-Ink (E-Paper) — draws power only when it changes

E-Ink is the battery champion: it pulls current only while the image updates, then holds the picture for free — and it is perfectly readable in direct sunlight, like paper. Perfect for shelf tags, room signs, calendars and slow clocks that run for months on a coin cell. The catch is refresh: a full update takes hundreds of milliseconds to a couple of seconds and often flashes, so it is useless for animation. It wires over SPI much like a TFT, plus a BUSY line the panel drives back to the MCU. The common library is GxEPD2.

E-Paper panel wired to an ESP32 over SPI: DIN, CLK, CS, DC, RST and a BUSY input
SPI plus a BUSY pin the panel asserts while it redraws.
#include <GxEPD2_BW.h>
// 2.9" panel, pins: CS=5, DC=2, RST=4, BUSY=27
GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> epd(GxEPD2_290(5, 2, 4, 27));

void setup() {
  epd.init();
  epd.setFullWindow();
  epd.firstPage();
  do {
    epd.fillScreen(GxEPD_WHITE);
    epd.setCursor(10, 40);
    epd.print("+23 C");                  // then it holds the image on zero power
  } while (epd.nextPage());
}

Before you solder

Two things save the most grief. First, logic level: ESP32 GPIO is 3.3 V — most modules are fine, but a 5 V-only display driven from an Arduino needs care in reverse. Second, pins: a colour or touch screen can claim half your GPIOs, so plan them before you wire — especially on all-in-one screen boards where the display already owns most of the header. Sketch the connections in BoardLab first to see which pins stay free.

Wire your screen visually, then see which GPIOs are left for sensors.