ElectronicZoologyfield notes from the garage
Display • ESP32

How to use the GC9D01
160x160 round TFT
with ESP32

Display: GC9D01 - 160x160 round TFT
Board: ESP32 Dev Board (38-pin)
Library: Arduino_GFX by Moon On Our Nation
Interface: SPI
⚙ Under Construction

What You Need

Parts

Software

Install via Arduino IDE Library Manager - search Arduino_GFX.

Not a GC9A01

Many 0.71" 160x160 round displays are sold as "GC9A01" - same listing, same photo, wrong chip. The actual driver is the GC9D01. They share a similar command set but have different init sequences. Using the GC9A01 round display with ESP32 driver on a GC9D01 gives vertical lines, wrong colours, or no output at all.

How to tell which chip you have. Size is the giveaway - the GC9A01 is 240x240, the GC9D01 is 160x160. If your round display is around 0.71" across and the listing says GC9A01, it's almost certainly a GC9D01.

Arduino_GFX v1.6.1+ has native GC9D01 support via Arduino_GC9D01. Use that constructor and the init sequence is correct from the start. TFT_eSPI does not have a GC9D01 driver - Arduino_GFX is the right library for this display.

Wiring

Display PinESP32 PinNotes
VCC3.3V3.3V only - no 5V tolerance on this module
GNDGND
SCLGPIO 18SPI clock (SCLK)
SDAGPIO 23SPI data (MOSI)
DCGPIO 27Data / Command select
CSGPIO 5Chip select
RSTGPIO 4Reset
BL3.3VBacklight - wire directly to 3.3V for always-on
MISONot connectedDisplay is write-only
Do not use GPIO 2 for DC. GPIO 2 is a boot strapping pin on the ESP32. Using it for DC causes upload failures - the display holds it low during SPI transfers, which puts the ESP32 into download mode. GPIO 27 works correctly.

Library Setup

Open Arduino IDE, go to Tools → Manage Libraries, search for Arduino_GFX and install Arduino_GFX Library by Moon On Our Nation. Version 1.6.1 or later is required for GC9D01 support.

IPS must be false. The constructor takes an IPS argument. Setting it to true inverts the colours on this panel. Use false.
Arduino_DataBus *bus = new Arduino_HWSPI(27, 5); // DC, CS
Arduino_GFX *gfx = new Arduino_GC9D01(bus, 4, 0, false); // RST, rotation, IPS=false

Test Sketch

Flash this to confirm wiring and library are both correct. Cycles red, green, blue, white, and black (500ms each), then a 150-star warp speed starfield. Smooth animation means everything is working.

/*
 * We stand on the shoulders of giants when we build
 * with knowledge gained from others' efforts.
 * That doesn't make us giants. Be humble.
 * Create with care. Open source is the way.
 *
 * GC9D01 160x160 Round TFT - Test Sketch
 * ----------------------------------------
 * Cycles red / green / blue / white / black (500ms each),
 * then a 150-star warp speed starfield with site name.
 *
 * Board:   ESP32 Dev Board (38-pin)
 * Library: Arduino_GFX_Library by Moon On Our Nation
 *
 * Wiring:
 *   VCC -> 3.3V (3.3V ONLY)    GND -> GND
 *   SCL -> GPIO 18              SDA -> GPIO 23
 *   DC  -> GPIO 27              CS  -> GPIO 5
 *   RST -> GPIO 4               BL  -> 3.3V
 *
 * Open source - MIT Licence
 * Electronic Zoology - field notes from the garage
 * https://electroniczoology.com/guides/how-to-use-gc9d01-round-tft-esp32
 */

#include <Arduino_GFX_Library.h>

Arduino_DataBus *bus = new Arduino_HWSPI(27, 5);         // DC, CS
Arduino_GFX *gfx = new Arduino_GC9D01(bus, 4, 0, false); // RST, rotation, IPS=false

#define CX        80
#define CY        80
#define NUM_STARS 150
#define SPEED     3.5f

struct Star { float x, y, z; int px, py; };
Star stars[NUM_STARS];

void resetStar(Star &s) {
  s.x  = random(-80, 80);
  s.y  = random(-80, 80);
  s.z  = random(40, 160);
  s.px = -1;
  s.py = -1;
}

uint16_t grey(uint8_t v) {
  return ((v >> 3) << 11) | ((v >> 2) << 5) | (v >> 3);
}

void drawTitle() {
  gfx->setTextColor(0xFFFF);
  gfx->setTextSize(1);
  gfx->setCursor(50, 71);
  gfx->print("Electronic");
  gfx->setCursor(47, 82);
  gfx->print("Zoology.com");
}

void setup() {
  randomSeed(analogRead(0));
  gfx->begin();

  gfx->fillScreen(0xF800); delay(500); // red
  gfx->fillScreen(0x07E0); delay(500); // green
  gfx->fillScreen(0x001F); delay(500); // blue
  gfx->fillScreen(0xFFFF); delay(500); // white
  gfx->fillScreen(0x0000); delay(500); // black

  for (int i = 0; i < NUM_STARS; i++) {
    resetStar(stars[i]);
    stars[i].z = random(1, 160);
  }
}

void loop() {
  for (int i = 0; i < NUM_STARS; i++) {
    Star &s = stars[i];

    if (s.px >= 0) {
      gfx->fillCircle(s.px, s.py, s.z > 80 ? 1 : 2, 0x0000);
    }

    s.z -= SPEED;
    if (s.z <= 1) { resetStar(s); continue; }

    int sx = CX + (int)(s.x * 80.0f / s.z);
    int sy = CY + (int)(s.y * 80.0f / s.z);

    if (sx < 0 || sx >= 160 || sy < 0 || sy >= 160) {
      resetStar(s); continue;
    }

    uint8_t brightness = (uint8_t)((1.0f - s.z / 160.0f) * 220 + 35);
    int     radius     = s.z < 50 ? 2 : 1;

    gfx->fillCircle(sx, sy, radius, grey(brightness));
    s.px = sx;
    s.py = sy;
  }

  drawTitle();
}

Troubleshooting

Vertical lines or wrong colours

  • You're using the GC9A01 driver on a GC9D01 - use Arduino_GC9D01 not Arduino_GC9A01
  • Check the IPS argument in the constructor is false - true inverts colours

Upload fails / goes into download mode

  • DC is wired to GPIO 2 - move it to GPIO 27 (GPIO 2 is a boot strapping pin)

White screen / no output

  • Check wiring - DC and CS are the most commonly swapped pins
  • Confirm RST is connected, not floating
  • Confirm VCC is on 3.3V - this module has no 5V tolerance
  • Confirm BL is connected to 3.3V

Library not found / compile error

  • Make sure you installed Arduino_GFX Library by Moon On Our Nation, version 1.6.1 or later
  • Close and reopen Arduino IDE after installing
Have a GC9A01 instead? See How to wire the GC9A01 round display with ESP32 - the 240x240 version with a different driver.