Download PDF Parts List View on YouTube

We have used Liquid Crystal Displays in the DroneBot Workshop many times before, but the one we are working with today has a bit of a twist – it’s a circle!  Perfect for creating electronic gauges and special effects.



LCD, or Liquid Crystal Displays, are great choices for many applications. They aren’t that power-hungry, they are available in monochrome or full-color models, and they are available in all shapes and sizes.

And speaking about shapes and sizes, the LCD module that we have on the workbench today is circular.  

Today we will see how to use this display with both an Arduino and an ESP32. We will also use a pair of them to make some rather spooky animated eyeballs!

GC9A01 IPS Display

The display we are using today is manufactured by Waveshare, there are also similar displays made by other manufacturers.

Waveshare actually has several round LCD modules, I chose the 1.28-inch model as it was readily available on Amazon. You could probably perform the same experiments using a different module, although you may require a different driver.

The module I used has the following specifications:

  • Operating voltage: 3.3V/5V
  • Interface: SPI
  • LCD type: IPS
  • Controller: GC9A01
  • Resolution: 240(H)RGB x 240(V)
  • Display size: Φ32.4mm
  • Pixel size: 0.135(H)x0.135(V)mm
  • Dimension: 40.4×37.5(mm) Φ37.5(mm)

It’s a pretty inexpensive module, so I picked up a couple to “play” with!

SPI Interface

We have used the SPI interface several times before, it’s a common interface for both displays and memory cards.

This device uses a 4-wire SPI bus configuration, a common configuration that consists of the following four wires:

  • CS – This line selects the SPI device. There can be multiple CS lines for multiple devices.
  • SCK – The Clock line, which provides timing for the SPI device.
  • MOSI – The output from the controlling device.
  • MISO – The input to the controlling device.

The display actually only uses three of these wires, MISO is not used as the display is purely an output device.

There are also some additional connections to the display. One of them, DC, sets the display into either Data or Command mode. Another, BL, is a control for the display’s backlight.

The above illustration shows the connections to the display.  The Waveshare display can be used with either 3.3 or 5-volt logic, the power supply voltage should match the logic level (although you CAN use a 5-volt supply with 3.3-volt logic).

Similar GC9A01 Modules

There is another common round display that is also built around the GC9A01, you’ll find it on eBay and other common sources. 

One difference with this model of GC9A01 is that it has no onboard voltage regulator, so it is limited to working with 3.3-volt logic. 

Another difference is simply with the labeling on the display. There are two pins, one labeled SDA and the other labeled SCL. At a glance, you would assume that this is an I2C device, but it isn’t, it’s SPI just like the Waveshare device.

SDA is just the data input (DIN on the Waveshare display) and SCL is the clock input (CLK on the Waveshare device).

This display can be used for the experiments we will be doing with the ESP32, as that is a 3.3-volt logic microcontroller. You would need to use a voltage level converter if you wanted to use one of these with an Arduino Uno.

GC9A01 with Arduino Uno

The Arduino Uno is arguably the most common microcontroller on the planet, certainly for experiments it is. However, it is also quite old and compared to more modern devices its 16-MHz clock is pretty slow.

Nonetheless, it is possible to use the display with an Arduino Uno, especially if your application doesn’t require a lot of display refreshing.

Arduino Hookup

Hooking up the display to the Arduino Uno is pretty simple, and is illustrated here:

Note that as we are using 5-volt logic, we are powering the display with the Arduino’s 5-volt power output.

The Waveshare device comes with a cable for use with the display. Unfortunately, it only has female ends, which would be excellent for a Raspberry Pi (which is also supported) but not too handy for an Arduino Uno. I used short breadboard jumper wires to convert the ends into male ones suitable for the Arduino.

Running the Waveshare Sample Code

Once you have everything hooked up, you can start coding for the display. There are a few ways to do this, one of them is to grab the sample code that Waveshare provides on their Wiki.

The Waveshare Wiki does provide some information about the display and a bit of sample code for a few common controllers. It’s a reasonable support page, unfortunately, it is the only support that Waveshare provides(I would have liked to see more examples and a tutorial, but I guess I’m spoiled by Adafruit and Sparkfun LOL).

You’ll find a link to download the code at the bottom of the Wiki page.  It’s a ZIP file, with samples for the Raspberry Pi, Arduino, and STM32,

After downloading the file, you’ll need to unzip it. Once you do, you’ll find three folders, one for each supported processor.

Open the Arduino folder. Inside you’ll find quite a few folders, one for each display size that Waveshare supports. As I’m using the 1.28-inch model, I selected the LCD_1inch28 folder.

You’ll need to copy the selected folder in its entirety to your Arduino directory or folder.

Once you do that, you can open your Arduino IDE and then navigate to that folder. Inside the folder, there is a sketch file named LCD_1inch28.ino which you will want to open.

When you open the sketch, you’ll be greeted by an error message in your Arduino IDE. The error is that two of the files included in the sketch contain unrecognized characters. The IDE offers the suggestion of fixing these with the “Fix Encoder & Reload” function (in the Tools menu), but that won’t work.

The error just seems to be with a couple of the Chinese characters used in the comments of the sketch. You can just ignore the error, the sketch will compile correctly in spite of it.

The code is pretty basic, I’m not repeating all of it here, as it consists of several files.  But we can gather quite a bit of knowledge from the main file, as shown here.

You can see from the code that after loading some libraries we initialize the display, set its backlight level (you can use PWM on the BL pin to set the level), and paint a new image. We then proceed to draw lines and strings onto the display.

Unfortunately, Waveshare doesn’t offer documentation for this, but you can gather quite a bit of information by reading the LCD_Driver.cpp file, where the functions are somewhat documented.

After uploading the code, you will see the display show a fake “clock”. It’s a static display, but it does illustrate how you can use this with the Waveshare code.

Using the Adafruit_GC9A01A Library

While the Waveshare sample code is OK, there are other libraries that are better documented and may be more suitable for this display.

One of these libraries is the Adafruit_GC9A01A Library, which you can obtain from GitHub.

This library is an extension of the Adafruit GFX library, which itself is one of the most popular display libraries around. Because of this, there is extensive documentation for this library available from Adafruit.  This makes the library an excellent choice for those who want to write their own applications.

Grab the library from GitHub in ZIP format and use your Arduino IDE to install it as shown in the accompanying video.

The library has one example sketch called “graphicstest”, which is shown here:

You will need to edit the sketch on line #5 to change DC from 9 to 7, this reflects the way we wired up our Arduino to the display.

As with the Waveshare sample, this file just prints shapes and text to the display. It is quite an easy sketch to understand, especially with the Adafruit documentation.

The sketch finishes by printing some bizarre text on the display. The text is an excerpt from The Hitchhiker’s Guide to the Galaxy by Douglas Adams, and it’s a sample of Vogon poetry, which is considered to be the third-worst in the Galaxy!

GC9A01 with ESP32

An ESP32 is a much faster microcontroller than the Arduino Uno, and it is ideal for use with our circular LCD module.

I used an ESP32 WROVER module for these experiments, but most other ESP32 modules will work as well.

ESP32 Hookup

Here is the hookup for the ESP32 and the GC9A01 display.  As with most ESP32 hookup diagrams, it is important to use the correct GPIO numbers instead of physical pins. The diagram shows the WROVER, so if you are using a different module you’ll need to consult its documentation to ensure that you hook it up properly.

You’ll also notice that we have a potentiometer hooked up to GPIO pin 14.  We will be using this in one of our experiments.

Setting up the TFT_eSPI Library

After you get everything hooked up, you’ll need to grab a suitable library. 

The TFT_eSPI library is ideal for this, and several other, displays. You can install it through your Arduino IDE Library Manager, just search for “TFT_eSPI”.

You will need to make a couple of modifications in order to get the library working, as it was meant for several types of displays and processors.

Here is what you need to do:

  • Use your File Manager (Finder on a Mac) to navigate to your Arduino Libraries folder, which is inside your Arduino folder.
  • Look for the TFT_eSPI folder. Open it once you find it.
  • Inside the folder, you’ll find several files. Look for the User_Setup.h file.
  • Open the User_Setup.h file with a text editor.

Once you have opened up the User_Setup.h file, you will need to make the following edits:

  • On line 44 comment out (i.e. add “//” in front of the text) the line defining the ILI9341 driver.
  • On line 64 uncomment (i.e. remove the “//”) the line defining the GC9A01 driver.
  • On lines 204 through 209 comment out all the SPI definitions for the ILI9341.
  • On line 215 set MOSI to 23.
  • On line 216 set SCLK to 18.
  • On line 217 set CS to 22.
  • On line 218 set DC to 16.
  • On line 219 set RST to 4.

You can now save the file and are ready to use the library with your GC9A01 display.

Running Demo Code

There is a lot of demo code included with the library. Some of it is intended for other display sizes, but there are a few that you can use with your circular display.

To test out the display, you can use the Colour_Test sketch, found inside the Test and Diagnostic menu item inside the library samples.  While this sketch was not made for this display, it is a good way to confirm that you have everything hooked up and configured properly.

A great demo code sample is the Animated_dial sketch, which is found inside the Sprites menu item.  This demonstration code will produce a “dial” indicator on the display, along with some simulated “data” (really just a random number generator).

In order to run this sketch, you’ll need to install another library. Install the Tjpeg_Decoder Library from Library Manager. Once you do, the sketch will compile, and you can upload it to your ESP32.

It really looks great on our circular display!

Displaying Potentiometer Value

We can modify the Animated_dial sketch to use the potentiometer input instead of the random number. Make the following changes:

  • Add a definition for the potentiometer pin – #define POT_PIN 14
  • On line 100 you can change the text from “degrees” to whatever you like (this step is optional).
  • Remark out or remove the first line in the Loop, line 119. This is the line that connects to the random number generator.
  • Add the following line to the beginning of the Loop:

Uint16_t angle = map(analogRead(POT_PIN),0,4095,0,240)

This will map the value from the potentiometer to a range of 0 to 240, and assign it to the angle variable.

Save the sketch under a new name and upload it to your ESP32.  Now try the potentiometer, the meter should track it and display the value.

You can use this technique for other measurements as well.

GC9A01 Animated Eyes

One of my favorite sketches is the Animated Eyes sketch, which displays a pair of very convincing eyeballs that move. Although it will work on a single display, it is more effective if you use two.

Hooking up the Animated Eyes

The first thing we need to do is to hook up a second display. To do this, you connect every wire in parallel with the first display, except for the CS (chip select) line.

On the first display, we will leave CS on GPIO 22. The second display will use GPIO 21.

You can also hook up some optional components to manually control the two “eyeballs”.  You’ll need an analog joystick and a couple of momentary contact, normally open pushbutton switches.

Once you have it all hooked up, we can look at some code to make our spooky eyeballs!

Animated Eyes Configuration

The Animated Eyes sketch can be found within the sample files for the TFT_eSPI library, under the “generic” folder.  Assuming that you have wired up the second GC9A01 display, you’ll want to use the Animated_Eyes_2 sketch. 

This is a HUGE sketch, one of the largest ones I’ve seen in quite some time. 

To make life easy the developers have included a configuration file, you’ll need to edit this file if you added the joystick and the pushbuttons.

The config.h file is where you will make your changes:

  • On line 41 define the BLINK_PIN as 27.
  • On line 42 define the LH_WINK_PIN as 26.
  • On line 43 define the RH_WINK_PIN as 14.
  • On line 75 define JOYSTICK_X_PIN as 33.
  • On line 76 define JOYSTICK_Y_PIN as 32.

The file is very well documented, and you can make additional edits as you see fit. Once you have edited the file, upload it to the ESP32.

You should be greeted by a pair of spooky eyeballs, which you can control with the joystick and the switches!


The GC9A01 display would make a great indicator or gauge for your next project. Because it is an IPS display, it is very readable from a wide-angle.

I suggest you pick a couple of these up, they are great fun to play with!

Parts List

Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.




Waveshare Wiki – The Waveshare Wiki for the GC9A01 circular display.

Adafruit GC9A01A Library – The Adafruit GFX library for this display.

Adafruit GFX Library – Documentation for programming using the Adafruit GFX library.

Adafruit Animated Eyes – Complete documentation for the Animated Eyes sketch.


Using GC9A01 Round LCD Modules
Using GC9A01 Round LCD Modules
Article Name
Using GC9A01 Round LCD Modules
The GC9A01 LCD module is a 1.28-inch round display that is useful for instrumentation and other similar projects. Today we will learn how to use this display with an Arduino Uno and an ESP32.
Publisher Name
DroneBot Workshop
Publisher Logo
Tagged on:     
Notify of

Inline Feedbacks
View all comments
2 years ago

Love this gadget. Very appropriate for a Halloween trick! Thank you for these great classes. Be blessed.

2 years ago

That’s a really interesting and clear video and article. I’ve just ordered a couple of these from AliExpress, and I’m now looking forward to playing with them when they arrive. 🙂

2 years ago

Sir i have used gc9a01 with esp32 i have setup all the necessary information in user setup file still i am getting nothing on screen, screen blink once only.

1 year ago
Reply to  Dayanand

I know this is an old post but for anyone else, I had the same problem because pin 16 was not connected on my Dev board so changed it to an unused pin.

Last edited 1 year ago by Yep
2 years ago

I also using RTC library but not know how to connect it with which pin using TFT-eSPI Library and RTC. lib. Please help me

1 year ago

If you try the following:

  • Add the following line to the beginning of the Loop:

Uint16_t angle = map(analogRead(POT_PIN),0,4095,0,240)

DO NOT use “U” for Uint. Use “u” for uint.

1 year ago

Thank you for the great Tutorials. I tested the Round LCD GC9A01 with ESP32 Dev V4, Colour_Test sketch OK. But could not compile Animated_dial sketch due to following error:
E:\arduino-1.8.19\portable\sketchbook_1.8.19\libraries\TJpg_Decoder\src/TJpg_Decoder.h:23:26: fatal error: LittleFS.h: No such file or directory
When searched using Library Manager found only LitteleFS_esp32
Could you please help.

1 year ago

Hello and thanks for this great site! I tried to connect this display to the Arduino Nano but nothing happened after loading the sketch on the Nano. I used the same pinning as described above. Do you have any advice for running this display with the nano? Thank you and best regards

1 year ago

yeah, same here. Changed the DC pin to 7 but nothing displays using the Arduino Nano and the code above. Might be good to update this page to remove that part if it is untested. The github and library file makes repeat claims about its lack of possible functioning.
in any case, still Love DroneBotWorkshop, thanks for the amazing guides 🙂

1 year ago

Sir, Thank you for your work If it wouldnt be too much trouble i know you use the Seeed Studio XIAO can you add to this to show how to connect to this display the XIAO also it appears the Seeed Studio is backordered a expansion shield this display can plug into the XIAO i cant wait till i can figure this thing out Xiao Round Display also i am looking for advance use of the display and also the oled display for the XIAO i have learned about all i can on the U8G2 library and looking for more… Read more »

1 year ago

Great tutorial, like all the others you posted. Thanks for your precious work.
In the experiment with ESP32, I centered the eyes’ positions in the 240×240 displays by adjusting the Y position of the draw area as follows:

file “eye_functions.ino” – line 114, replace existing code
tft.setAddrWindow(eye[e].xposition, 0, 128, 128);
with :
tft.setAddrWindow(eye[e].xposition, 60, 128, 128);

9 months ago
Reply to  Rodolfo

Playing with the arguments a bit, trying to enlarge the eyes, I did manage to get two eyes on a single display using:
tft.setAddrWindow(eye[e].xposition, 90, 256, 256);

10 months ago

Sadly seems that the line numbers already changed alot. Lots of compile errors.

9 months ago

I got the sketch to work but also didn’t manage to get some bigger eyes. Tried this file but it resulted in a blank display only :

6 months ago

Dear all, I am experiencing problems with dimming my background light. I bought the display from Dongker on Amazon (link) and it is quite similar to the second one shown in the youtube video, although I cannot be certain as I cannot see the specifics. I was under the impression that just connecting the BLK to a PWM-IO (D9 / PB1) on my Atmega328p AU and then simply adjust the duty cycle using analogWrite() of the pin to regulate the background light but it is not working. I do not see any difference in brightness even when turning down the… Read more »

4 months ago


I have the same display device, but the pins are


and I can’t figure out how to wire this to the ESP32, or get the code to run.

Any help greatly appreciated!

Ken Fellows
2 months ago

When I try the code/project both eyes appear, but one eye is flickering and the non-flickering eye has muted colors. I am using this item, “waveshare 1.28inch Round LCD Display Module 65K RGB Colors 240×240 Resolution with SPI Interface Embedded GC9A01 Driver.” Any help would be appreciated.
Thanks,Ken Fellows

1 month ago

I want to run this code with an raspberry pi pico WH, what is the pinout equivalent for it ?