How to use the GC9D01
160x160 round TFT
with ESP32
What You Need
Parts
- ESP32 Dev Board (38-pin)
- GC9D01 160x160 round TFT module
- Jumper wires
- USB data cable for flashing
Software
- Arduino IDE with ESP32 board support
Arduino_GFX_Libraryby Moon On Our Nation
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.
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 Pin | ESP32 Pin | Notes |
|---|---|---|
| VCC | 3.3V | 3.3V only - no 5V tolerance on this module |
| GND | GND | |
| SCL | GPIO 18 | SPI clock (SCLK) |
| SDA | GPIO 23 | SPI data (MOSI) |
| DC | GPIO 27 | Data / Command select |
| CS | GPIO 5 | Chip select |
| RST | GPIO 4 | Reset |
| BL | 3.3V | Backlight - wire directly to 3.3V for always-on |
| MISO | Not connected | Display is write-only |
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.
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_GC9D01notArduino_GC9A01 - Check the IPS argument in the constructor is
false-trueinverts 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