Connect TFT Color Screen LCD Display Module Drive ST7735 Interface SPI 128*160 to ESP8266 or ESP32

Hello.

Do you know how to connect this screen 1.8 Inch TFT Color Screen LCD Display Module Drive ST7735 Interface SPI 128*160 to a Wemos D1 Mini board or ESP32?

1.8 Inch TFT Color Screen LCD Display

* 1.8-inch SPI serial screen with backplane module, requires at least 4 IO drivers
* Size: 1.8 inch SPI serial bus
* Resolution: 128*160
* Driver IC: ST7735
* The features of this module:
* 1. Support Arduino various MCU in-line without any wiring
* 2. Integrated voltage regulator IC, support 5V or 3.3V power supply
* 3. Onboard level shifting scheme, truly compatible with 5V/3.3V IO level. Support a variety of microcontroller IO connections
* 4. Integrated SD card expansion circuit,
* 5. Reserve SPI FLASH font circuit to facilitate extended application

I found this pinout table :

Number Pin Label Description
1 VCC 5V/3.3V power input
2 GND Ground
3 CS LCD chip select signal, low level enable
5 A0 LCD register / data selection signal, high level: register, low level: data
6 SDA SPI bus write data signal
7 SCK SPI bus clock signal
8 LED Backlight control, high level lighting, if not controlled, connect 3.3V always bright

Wemos D1 Mini
Here is the Wemos D1 Mini pinout:

So should I connect it like following?

Display pin Board pin AZDelivery D1 mini pin
Display VCC Board 3.3V 3V3
Display GND Board GND G
Display CS Board SS GPIO15 ?
Display RST Board GPIO2
Display A0 Board A0 Analog Input 0 A0
Display SDA Board SDA/MOSI GPIO4 PIN13 D7
Display SCK Board SCK GPIO5 PIN14 D5
Display LED Board 3.3v 3V3

Regards

Start here:

Doesn’t look like the easiest display to configure.

I have read this page (ST7735 Display) several times but on my display board I don’t have the DC pin, only the CS pin.

    reset_pin: D4
    cs_pin: D1
    dc_pin: D2

So, should I use I2C or SPI pins?

  1. I2C interface → SCL + SDA pins
  2. Serial peripheral interface (SPI) → SCK + MOSI + CS pins

Regards

If I get it right, you can pick any GPIO as the D/C

I also tried the following code with ESPHome but the screen remains white:

# Display stuff
# SPI and ST7735 160x80 display
# https://esphome.io/components/display/st7735.html
spi:
  clk_pin: D5
  mosi_pin: D7

display:
  - platform: st7735
    model: "INITR_BLACKTAB"
    reset_pin: D4
    cs_pin: D1
    dc_pin: D2
    rotation: 0
    device_width: 160
    device_height: 80
    col_start: 0
    row_start: 0
    eight_bit_color: True
    use_bgr: True
    update_interval: 5s
    lambda: |-
      // it.print(10, 10, id(mono8), "Hello World!");
      // Draw a line from [0,0] to [100,50]
      it.line(0, 0, 100, 50);
      // Draw the outline of a rectangle with the top left at [50,60], a width of 30 and a height of 42
      it.rectangle(50, 60, 30, 42);
      // Draw the same rectangle, but this time filled.
      it.filled_rectangle(50, 60, 30, 42);

      // Circles! Let's draw one with the center at [25,25] and a radius of 10
      it.circle(25, 25, 10);
      // ... and the same thing filled again
      it.filled_circle(25, 25, 10);
[18:09:22][C][spi:101]: SPI bus:
[18:09:22][C][spi:102]:   CLK Pin: GPIO14
[18:09:22][C][spi:104]:   MOSI Pin: GPIO13
[18:09:22][C][spi:106]:   Using HW SPI: YES
[18:09:22][C][st7735:376]: ST7735
[18:09:22][C][st7735:376]:   Rotations: 0 °
[18:09:22][C][st7735:376]:   Dimensions: 160px x 80px
[18:09:22][C][st7735:377]:   Model: ST7735 BLACKTAB
[18:09:22][C][st7735:378]:   CS Pin: GPIO5
[18:09:22][C][st7735:379]:   DC Pin: GPIO4
[18:09:22][C][st7735:380]:   Reset Pin: GPIO2
[18:09:22][D][st7735:381]:   Buffer Size: 12800
[18:09:22][D][st7735:382]:   Height: 80
[18:09:22][D][st7735:383]:   Width: 160
[18:09:22][D][st7735:384]:   ColStart: 0
[18:09:22][D][st7735:385]:   RowStart: 0

Which one of these two images matches the pinout of your display?

The info in this thread got a similar display working for me.

As indicated in my post I have the 1.8 Inch TFT Color Screen LCD.
I confirm that this same screen works correctly with an Arduino Nano W module so it’s either a wiring problem on my ESP module or a problem in my configuration.

Even if this is an old post I want to share an extremly helpful link.
Here you find a description of the pins that are named not very standard like:

https://techoverflow.net/2023/05/30/minimal-esp32-platformio-128x160px-tft-display-example-using-adafruit-st7735/

My yaml configuration for the ST7735 display 128*160 is like:

# ---------------------------------------------------
# Configuration entry for Display PSI
# ---------------------------------------------------
spi:
  clk_pin: GPIO25
  mosi_pin: GPIO26
#  miso_pin: GPIO27

# ---------------------------------------------------
# Enable time component, time delivered by HA 
# ---------------------------------------------------
time:
  - platform: homeassistant
    id: ha_time    

# ---------------------------------------------------
# Enable outomated switching beween display pages
# ---------------------------------------------------
interval:
  - interval: 10s
    then:
      - display.page.show_next: my_display
      - component.update: my_display
#  - interval: 1s
#    then:
#      - display.page.show_next: my_display
#      - component.update: my_display      

# ---------------------------------------------------
# ST7735 display 128*160 settings
# ---------------------------------------------------
display:
  - platform: ili9xxx
    id: my_display
    model: ST7735
    dc_pin: GPIO27
    reset_pin: GPIO14
    update_interval: 5s
    auto_clear_enabled: false
    transform:
      swap_xy: true
      mirror_x: true
    dimensions:
      height: 128
      width: 160
    pages:
      - id: page01  
        lambda: |-
          it.fill(id(my_black));
          it.line(0, 0, 50, 50);
          it.rectangle(3, 5, 15, 118, id(my_red)); // x,y,width, height
    #      it.print(0, 0, id(my_font), id(my_red), TextAlign::TOP_LEFT, "Hello World!");
      - id: page02  
        lambda: |-
          it.fill(id(my_black));
          it.line(0, 0, 50, 50);
          it.rectangle(3, 5, 15, 118, id(my_blue)); // x,y,width, height
    #      it.print(0, 0, id(my_font), id(my_red), TextAlign::TOP_LEFT, "Hello World!");

Adding my own experience for this thread, using a very similar 1.8" 128x160 TFT display. I’ve been trying to get it working using various MCUs, perhaps my experience will help others keep their sanity…

  • Wemos D1 Mini (original or V3.0.0): display works using ST7735 config (detailed above) but couldn’t get it to work with ILI9xxx. BUT… D1 mini reboots every time I try and read logs (using ESPHome facility) OR send a Wifi command (turn status LED on/off).
  • Wemos D1 Mini (V4.0.0): can’t get reliable WiFi connection under ESPHome (with/without display config), seems a common problem as detailed under other threads which I wish I’d found days ago :frowning: .
  • ESP32-C3mini: display works using ILI9xxx platform config.

My ESP32-C3mini config is “out of the box”, with display sections of config below:

time:
  - platform: homeassistant
    id: homeassistant_time

spi:
  clk_pin: GPIO4   # SCK on display
  mosi_pin: GPIO6  # SDA on display

font:
  - file: "fonts/RobotoCondensed-Regular.ttf"
    id: font_r
    size: 12

display:
  - platform: ili9xxx
    # 1.8" TFT display (red board) 128x160
    model: ST7735
    invert_colors: false
    show_test_card: False
    reset_pin: GPIO1  # Reset on display
    cs_pin: GPIO2     # CS on display
    dc_pin: GPIO0     # A0 on display
    rotation: 0
    update_interval: 5s
    lambda: |-
      auto black = Color(0, 0, 0);
      auto red = Color(255, 0, 0);
      auto green = Color(0, 255, 0);
      auto blue = Color(0, 0, 255);
      auto white = Color(255, 255, 255);    
      // Write some text
      it.print(10, 10, id(font_r), "Hello World!");
      it.strftime(100, 10, id(font_r), "%H:%M", id(homeassistant_time).now());
      // Draw a circle in the middle of the display
      it.filled_circle(it.get_width() / 2, it.get_height() / 2, 20, red);

Adding to the above, noting that ili9xxx (ILI9xxx TFT LCD Series - ESPHome - Smart Home Made Simple) is now marked as redundant to be replaced by mipi-sdi (MIPI SPI Display Driver - ESPHome - Smart Home Made Simple) I changed my config above from platform: ili9xxx to platform: mipi_spi to use the new driver. [My config is ESP32-C3 connected to 128x160 red display, with additional HA parameters imported and displayed.]

After this one code change the C3 becomes unstable after several hours (display starts updating infrequently, or stops altogether) with the onboard power circuitry becoming too hot to touch. Repeatable experiment after 10+ minutes of cool-down time.

Change back to platform: ili9xxx and problem goes away and I see stable operation for days. Have gone back to ili9xxx for my deployment (stable for 6 days since deployment), there must be a difference in driver logic causing a problem?

The operating principle is exactly the same between the two drivers. Show your yaml and logs.

Agreed @clydebarrow, the result wasn’t what I was expecting. Only noticed it as I’m (slowly!) updating all my yaml to the modern format and removing any legacy platforms.

Core elements of my YAML below. This code emulates a clock radio display with a 7-segment numeric emulation, flashing colon in the time (HH:MM) plus a seconds display, and brightness changes for overnight viewing.

esphome:
  name: $devicename
  friendly_name: $upper_devicename
  min_version: 2025.5.0
  name_add_mac_suffix: false

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:
- platform: esphome

substitutions:
  devicename: esp32-c3mini-01
  upper_devicename: ESP32-C3mini-01
  pin_C3_sda: "20"      #GPIO20 - I2C SDA
  pin_C3_scl: "21"      #GPIO21 - I2C SCL
  pin_C3_led: "8"       #GPIO8 - ESP C3 onboard LED
  pin_lcd_reset: "1"    #GPIO1 - LCD reset
  pin_lcd_cs: "2"       #GPIO2 - LCD CS
  pin_lcd_dc: "0"       #GPIO0 - LCD DC
  pin_lcd_bklit: "3"    #GPIO3 - LCD backlight

# FONTS for screen
  font_3: "fonts/DigitalDisplay.ttf"

# ===== Networking =====

wifi:
  networks:
  - ssid: !secret wifi_ssid3
    password: !secret wifi_password3
#    priority: 3 #highest

i2c:
  sda: GPIO${pin_C3_sda} # Non-default
  scl: GPIO${pin_C3_scl} # Non-default

time:
  - platform: homeassistant
    id: homeassistant_time
    on_time: 
      # dim display at 23:00 and full brightness at 06:00
      - seconds: 0
        minutes: 0
        hours: 23
        then:
          - light.turn_on:
              id: back_light
              brightness: 50%
      - seconds: 0
        minutes: 0
        hours: 6
        then:
          - light.turn_on:
              id: back_light
              brightness: 100%

light:
  - platform: status_led
    # Onboard status LED
    name: $upper_devicename Status LED
    id: esp32_c3mini_01_status_led
    pin: 
      number: GPIO${pin_C3_led}
      inverted: true
  - platform: monochromatic
    # Define a monochromatic, dimmable light for the backlight
    output: backlight_pwm
    name: $upper_devicename Display Backlight
    id: back_light
    restore_mode: ALWAYS_ON

output:
  - platform: ledc
    # Define a PWM output on the ESP32
    pin: GPIO${pin_lcd_bklit}
    id: backlight_pwm

font:
  - file: $font_3
    id: font_3r_s1
    size: 40
  - file: $font_3
    id: font_3r_s2
    size: 20


display:
  - platform: ili9xxx
#  - platform: mipi_spi # replaces ili9xxx, but causes C3 failure
    model: ST7735
    # 1.8" TFT display (red board) 128x160
    dimensions: 
      height: 160
      width: 128
    invert_colors: false
    show_test_card: false
    reset_pin: GPIO${pin_lcd_reset}
    cs_pin: GPIO${pin_lcd_cs}
    dc_pin: GPIO${pin_lcd_dc}
    rotation: 180°
    update_interval: 500ms
    lambda: |-
      auto black = Color(0, 0, 0);
      auto red = Color(255, 0, 0);
      auto green = Color(0, 255, 0);
      auto blue = Color(0, 0, 255);
      auto yellow = Color(255, 255, 0);
      auto amber = Color(255, 170, 0);
      auto white = Color(255, 255, 255);
      static bool show_text = true; // Static variable to toggle text visibility
      static unsigned long last_toggle_time = 0;
      unsigned long current_time = millis();

      // Toggle text visibility every 500ms (adjust as needed)
      if (current_time - last_toggle_time >= 500) {
        show_text = !show_text;
        last_toggle_time = current_time;
      }

      // ===== Display time with seconds and flashing colon separator
      if (show_text) {
        it.strftime(3, 5, id(font_3r_s1), amber, "%H:%M", id(homeassistant_time).now());
      } else {
        it.strftime(3, 5, id(font_3r_s1), amber, "%H %M", id(homeassistant_time).now());
      }
      it.strftime(100, 5, id(font_3r_s2), amber, "%S", id(homeassistant_time).now());
      it.strftime(it.get_width(), 35, id(font_2r_s1), amber, TextAlign::RIGHT, "%a %d %b %Y", id(homeassistant_time).now());

It has now been running reliably for around 10 days.

Prior to this run I was using - platform: mipi_spi which caused problems with C3 overheating and failing, so I’ve reverted for reliability. In the HA core logs I didn’t see anything prior to the C3 failure, same in the ESPHome logs. I’ll check further next week when I get a chance to make some updates.