How to use 2,1inch RGB 480x480 round display with ESP32-S3?

Hello everyone! I am a beginner in programming, in the past couple of months i started to use arduino to work with small displays like GC9A01. I was able to make them work and meanwhile i searched for some information i came across 2,1inch RGB 480x480 round displays. I ordered some from aliexpress. Now I having a hard time to make it work, first i would like to use a simple HelloWorld code.

I bought the display from here with a board:
https://www.aliexpress.us/item/1005005966888061.html

To test it out i connected the display and the attached board to my PC with a USB and an HDMI cable, and it was working fine as an extra little touch monitor.

I also ordered this controller for programming:
https://learn.adafruit.com/adafruit-qualia-esp32-s3-for-rgb666-displays

I found CosmicOwl's topic about this type of displays and moononournation github page. CosmicOwl had to make some changes in libraries, but i can't find these: "Arduino_ST7701_RGBPanel.h" and "Arduino_ST7701_RGBPanel.cpp". Are these created by him? Where should i look for them?
https://forum.arduino.cc/t/esp32s3-and-st7701s/1004892/9

I tried to use the HelloWorld example from moononournation library with some changes as you can see below. I could upload to my display without an error, but nothing appears on the screen.

/*******************************************************************************
 * Start of Arduino_GFX setting
 *
 * Arduino_GFX try to find the settings depends on selected board in Arduino IDE
 * Or you can define the display dev kit not in the board list
 * Defalult pin list for non display dev kit:
 * ESP32 various dev board     : CS:  5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
 * ESP32-C3 various dev board  : CS:  7, DC:  2, RST:  1, BL:  3, SCK:  4, MOSI:  6, MISO: nil
 * ESP32-S2 various dev board  : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
 * ESP32-S3 various dev board  : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
 * ESP8266 various dev board   : CS: 15, DC:  4, RST:  2, BL:  5, SCK: 14, MOSI: 13, MISO: 12

 ******************************************************************************/
#include <Arduino_GFX_Library.h>

#define GFX_BL 1 // default backlight pin, you may replace DF_GFX_BL to actual backlight pin

/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
//#if defined(DISPLAY_DEV_KIT)
//Arduino_GFX *gfx = create_default_Arduino_GFX();
//#else /* !defined(DISPLAY_DEV_KIT) */

Arduino_DataBus *bus = new Arduino_SWSPI(
    GFX_NOT_DEFINED /* DC */, 21 /* CS */,
    47 /* SCK */, 41 /* MOSI */, GFX_NOT_DEFINED /* MISO */);
Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
    39 /* DE */, 48 /* VSYNC */, 40 /* HSYNC */, 45 /* PCLK */,
    10 /* R0 */, 16 /* R1 */, 9 /* R2 */, 15 /* R3 */, 46 /* R4 */,
    8 /* G0 */, 13 /* G1 */, 18 /* G2 */, 12 /* G3 */, 11 /* G4 */, 17 /* G5 */,
    47 /* B0 */, 41 /* B1 */, 0 /* B2 */, 42 /* B3 */, 14 /* B4 */,
    1 /* hsync_polarity */, 10 /* hsync_front_porch */, 10 /* hsync_pulse_width */, 10 /* hsync_back_porch */,
    1 /* vsync_polarity */, 14 /* vsync_front_porch */, 2 /* vsync_pulse_width */, 12 /* vsync_back_porch */);
Arduino_RGB_Display *gfx = new Arduino_RGB_Display(
    480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
    bus, GFX_NOT_DEFINED /* RST */, st7701_type7_init_operations, sizeof(st7701_type7_init_operations));

/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
//Arduino_DataBus *bus = create_default_Arduino_DataBus();

/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
//Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 0 /* rotation */, false /* IPS */);

//#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
 * End of Arduino_GFX setting
 ******************************************************************************/

void setup(void)
{
  Serial.begin(115200);
  // Serial.setDebugOutput(true);
  // while(!Serial);
  Serial.println("Arduino_GFX Hello World example");

#ifdef GFX_EXTRA_PRE_INIT
  GFX_EXTRA_PRE_INIT();
#endif

  // Init Display
  if (!gfx->begin())
  {
    Serial.println("gfx->begin() failed!");
  }
  gfx->fillScreen(BLACK);

#ifdef GFX_BL
  pinMode(GFX_BL, OUTPUT);
  digitalWrite(GFX_BL, HIGH);
#endif

  gfx->setCursor(10, 10);
  gfx->setTextColor(RED);
  gfx->println("Hello World!");

  delay(5000); // 5 seconds
}

void loop()
{
  gfx->setCursor(random(gfx->width()), random(gfx->height()));
  gfx->setTextColor(random(0xffff), random(0xffff));
  gfx->setTextSize(random(6) /* x scale */, random(6) /* y scale */, random(2) /* pixel_margin */);
  gfx->println("Hello World!");

  delay(1000); // 1 second
}

I assume that i have a problem with this part of the code and some kind of communication can't happen between the controller and the display:

Arduino_DataBus *bus = new Arduino_SWSPI(
    GFX_NOT_DEFINED /* DC */, 21 /* CS */,
    47 /* SCK */, 41 /* MOSI */, GFX_NOT_DEFINED /* MISO */);
Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
    39 /* DE */, 48 /* VSYNC */, 40 /* HSYNC */, 45 /* PCLK */,
    10 /* R0 */, 16 /* R1 */, 9 /* R2 */, 15 /* R3 */, 46 /* R4 */,
    8 /* G0 */, 13 /* G1 */, 18 /* G2 */, 12 /* G3 */, 11 /* G4 */, 17 /* G5 */,
    47 /* B0 */, 41 /* B1 */, 0 /* B2 */, 42 /* B3 */, 14 /* B4 */,
    1 /* hsync_polarity */, 10 /* hsync_front_porch */, 10 /* hsync_pulse_width */, 10 /* hsync_back_porch */,
    1 /* vsync_polarity */, 14 /* vsync_front_porch */, 2 /* vsync_pulse_width */, 12 /* vsync_back_porch */);
Arduino_RGB_Display *gfx = new Arduino_RGB_Display(
    480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
    bus, GFX_NOT_DEFINED /* RST */, st7701_type7_init_operations, sizeof(st7701_type7_init_operations));

I would be very grateful if someone could explain in detail exactly what is happening in this code snippet and would really appreciate any further information from someone who succesfully used this display!

Thank you in advance! :slightly_smiling_face:
Best regards: Zsolt

Best advice I can offer is to try an easier unit. These are not beginner friendly displays. I have used the larger versions and it was extremely frustrating getting them to work.
There is a github project that aims to provide more documentation, code, and user experience around the entire category.

Have you tried an example for the Qualia board?

DroneBotWorkshop used one:

Thank you for answering!

I believe the ESP32 board delivered with the rainbow example uploaded on it. If i connect the display it works well, you can see on the right side of the picture below. I've done nothing with it, just plugged the USB cable in.

Next thing i tried is to upload the rainbow example to the left board. When i compile the code in IDE, it gives back this error:

AppData\Local\Temp.arduinoIDE-unsaved2024122-8476-1qiifjg.d5oz\sketch_feb22a\sketch_feb22a.ino:10:5: error: 'PCA_TFT_RESET' was not declared in this scope
PCA_TFT_RESET, PCA_TFT_CS, PCA_TFT_SCK, PCA_TFT_MOSI

I thought that i don't have to change PCA_TFT_RESET etc. because they are already declared in the included libraries. I'm not sure if the preuploaded code by the manufacturer is the same or not as the code available on the site. Because of this i thought i have to get the display initialization right and it will solve the problem. But I only got to the point where it uploads (helloworld code) without an error message and the display remains black.

Thank you, i will check it out! :slight_smile:

Hii mate,
I have also been trying to work with this display, Display

Same Error :

 E (247) lcd_panel.rgb: esp_lcd_new_rgb_panel(151): no mem for frame buffer
ESP_ERROR_CHECK failed: esp_err_t 0x101 (ESP_ERR_NO_MEM) at 0x4037d334
file: "lib/Arduino_GFX-master/src/databus/Arduino_ESP32RGBPanel.cpp" line 119
func: uint16_t* Arduino_ESP32RGBPanel::getFrameBuffer(int16_t, int16_t)
expression: esp_lcd_new_rgb_panel(_panel_config, &_panel_handle)

abort() was called at PC 0x4037d337 on core 1

Other peripherals, such as buttons, LEDs, and motors, all work properly separately.
But when it comes to work together, I get this error.
And I want to know how CosmicOwl solved it and where can i find Arduino_ST7701_RGBPanel.h" and "Arduino_ST7701_RGBPanel.cpp" please help with git hub repository

Here is what I am doing.

Install Arduino IDE 1.8.19.

Install arduino-esp32 board support package (BSP) by Espressif version 2.0.14
Stable BSP URL: https://espressif.github.io/arduino-esp32/package_esp32_index.json

WARNING: Version 3.x is UNSTABLE. Do not use.

Set the ESP32 board type to "Adafruit Qualia ESP32-S3 RGB666"

Install the library "GFX Library for Arduino" by "Moon On Our Nation". I do not recall it having any dependencies.

Install the library "Adafruit FT6206 Library" and all its dependencies. If you are using some other dev system that does not install dependencies, the dependencies can be installed manually.

  • Adafruit ILI9341
  • Adafruit GFX Library
  • Adafruit BusIO
  • Adafruit STMPE610
  • Adafruit TouchScreen
  • Adafruit TSC2007
  • Adafruit SH110X

Install the library "Adafruit CST8XX Library" and all its dependencies (currently none).

At this point the raindow example compiles without errors. I do not have a Qualia board yet so this is as far as I can go.

Feel free to offer advice and monitor this topic, but you should start your own topic if you are asking for help. (whispering: you are hijacking)

I am using the qualia ESP32s3 board and a round 480x480 2.1 inch display. I have the examples running without a problem. I am trying to do a ‘pushImage’ or equivalent, for a 8bit color full screen image from PROGMEM to the display as a sprite, but everything I am trying is failing. I had assumed that I would need to use gfx->drawxxxxxxxx as in the example, am I missing something simple?

Could you share your working code and what settings did you use in IDE, please? I would like to compare it with mine, maybe i can find something.
Unfortunately, I can't give you help with displaying image yet.
Thanks!

Thank you for your advice!

I have an old laptop without any installed arduino stuff, so i tried your suggestion on that. I installed everything, but there is no "Adafruit Qualia ESP32-S3 RGB666" option when i want to choose the board. On my desktop PC i can choose it, but when i start to compile it doesn't find this:

cmd /c if not exist "C:\\Users\\\\AppData\\Local\\Temp\\arduino\\sketches\\E894DA3D9AA2CADC914CB7A6B1C2732E\\partitions.csv" COPY "C:\\Arduino\\hardware\\espressif\\esp32\\tools\\partitions\\default.csv" "C:\\Users\\\\AppData\\Local\\Temp\\arduino\\sketches\\E894DA3D9AA2CADC914CB7A6B1C2732E\\partitions.csv"
The system cannot find the path specified.
exit status 1

Compilation error: exit status 1

I have a working display finally. Thanks two of my colleagues for their effort! We followed these steps:

  1. Hardware: previously mentioned display, and ESP32-S3 board and a USB-C cable
  2. Arduino IDE setup:

It is the same what customcontroller suggested, just don't forget to add the additional board manager in the preferences:
image

In the tools menu:

  1. COM port: Not exactly this topic but one of my colleagues had issues with COM port, he didn't have COM ports despite the drivers were installed. The only way he could see them if he turns on the "show hidden devices" or "devices by container" in the device manager. After that we noticed that there were some kind of android drivers installed on his PC along with this hidden devices, we just had to delete those and this solved the problem. Maybe you experiencing the same problem that's why i mention this.
    I have two COM ports, COM17 and COM18 in my case. It uses COM17 when i'm in boot mode (press and hold boot button--> press and release reset button-->release boot button to enter boot mode), you can upload your code in this mode (sometimes you have to press boot button when the compiler waiting for a port to upload). After that, press reset button once, and the device change COM port, COM17 to COM18 in my case and the code will run.

With this setup i can upload the rainbow code without any problem. I also have a simple "hello world" code:

 
#include <Arduino_GFX_Library.h>

/*-------------------------------------------------
Data Bus Initialization:
Arduino_DataBus *bus = new Arduino_SWSPI(...): This line creates an instance of the Arduino_SWSPI data bus class. It specifies the pins for communication with the display using SPI (Serial Peripheral Interface).
The parameters passed to Arduino_SWSPI include pin numbers for Data/Command (DC), Chip Select (CS), Serial Clock (SCK), and Master Out Slave In (MOSI).
The GFX_NOT_DEFINED placeholder is used for the Master In Slave Out (MISO) pin, indicating that it is not used in this configuration.*/

Arduino_XCA9554SWSPI *expander = new Arduino_XCA9554SWSPI(
    PCA_TFT_RESET, PCA_TFT_CS, PCA_TFT_SCK, PCA_TFT_MOSI,
    &Wire, 0x3F);
    
/*-------------------------------------------------
RGB Panel Initialization:
Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(...): This line creates an instance of the Arduino_ESP32RGBPanel class, representing the RGB display panel.
The parameters specify various pins for controlling the display, including Data Enable (DE), Vertical Sync (VSYNC), Horizontal Sync (HSYNC), Pixel Clock (PCLK), and color channels (R, G, B).
Additional parameters define synchronization timings (polarity, front porch, pulse width, and back porch).*/

Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
    TFT_DE, TFT_VSYNC, TFT_HSYNC, TFT_PCLK,
    TFT_R1, TFT_R2, TFT_R3, TFT_R4, TFT_R5,
    TFT_G0, TFT_G1, TFT_G2, TFT_G3, TFT_G4, TFT_G5,
    TFT_B1, TFT_B2, TFT_B3, TFT_B4, TFT_B5,
    1 /* hsync_polarity */, 50 /* hsync_front_porch */, 2 /* hsync_pulse_width */, 44 /* hsync_back_porch */,
    1 /* vsync_polarity */, 16 /* vsync_front_porch */, 2 /* vsync_pulse_width */, 18 /* vsync_back_porch */
//    ,1, 30000000
    );

/*-------------------------------------------------
Display Initialization:
Arduino_RGB_Display *gfx = new Arduino_RGB_Display(...): This line creates an instance of the Arduino_RGB_Display class, which manages the display.
The parameters include the display dimensions (width and height), the RGB panel instance (rgbpanel),
rotation (0 for no rotation), auto-flush mode (true), the data bus (bus), and initialization operations for the display controller (ST7701 in this case).*/

Arduino_RGB_Display *gfx = new Arduino_RGB_Display(
// 2.1" 480x480 round display
    480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
    expander, GFX_NOT_DEFINED /* RST */, TL021WVC02_init_operations, sizeof(TL021WVC02_init_operations));

// 2.8" 480x480 round display
//    480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
//    expander, GFX_NOT_DEFINED /* RST */, TL028WVC01_init_operations, sizeof(TL028WVC01_init_operations));

// 3.4" 480x480 square display
//    480 /* width */, 480 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
//    expander, GFX_NOT_DEFINED /* RST */, tl034wvs05_b1477a_init_operations, sizeof(tl034wvs05_b1477a_init_operations));

// 3.2" 320x820 rectangle bar display
//    320 /* width */, 820 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
//    expander, GFX_NOT_DEFINED /* RST */, tl032fwv01_init_operations, sizeof(tl032fwv01_init_operations));

// 4.0" 720x720 square display
//    720 /* width */, 720 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
//    expander, GFX_NOT_DEFINED /* RST */, NULL, 0);

// 4.0" 720x720 round display
//    720 /* width */, 720 /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
//    expander, GFX_NOT_DEFINED /* RST */, hd40015c40_init_operations, sizeof(hd40015c40_init_operations));
// needs also the rgbpanel to have these pulse/sync values:
//    1 /* hync_polarity */, 46 /* hsync_front_porch */, 2 /* hsync_pulse_width */, 44 /* hsync_back_porch */,
//    1 /* vsync_polarity */, 50 /* vsync_front_porch */, 16 /* vsync_pulse_width */, 16 /* vsync_back_porch */

/*******************************************************************************
 * End of Arduino_GFX setting
 ******************************************************************************/


void setup(void)
{  
  Serial.begin(115200);
  //while (!Serial) delay(100);
  
#ifdef GFX_EXTRA_PRE_INIT
  GFX_EXTRA_PRE_INIT();
#endif

  Serial.println("Beginning");
  // Init Display

  Wire.setClock(1000000); // speed up I2C 
  if (!gfx->begin()) {
    Serial.println("gfx->begin() failed!");
  }

  Serial.println("Initialized!");

  gfx->fillScreen(WHITE);
  gfx->setCursor(70, 220);
  gfx->setTextSize(5);
  gfx->setTextColor(RED);
  gfx->println("Hello World!");
}

void loop()
{
}


We are having issues right now with the touch screen (with the driver board which you can buy with the display on aliexpress it works fine). There are two options in the rainbow exapmle:

// The Capacitive touchscreen overlays uses hardware I2C (SCL/SDA)

// Most touchscreens use FocalTouch with I2C Address often but not always 0x48!
//#define I2C_TOUCH_ADDR 0x48

// 2.1" 480x480 round display use CST826 touchscreen with I2C Address at 0x15
#define I2C_TOUCH_ADDR 0x15  // often but not always 0x48!

None of the addresses working. I get this message in serial monitor:
image

How can i find the I2C address for the touchscreen?
I hope that the shared information will help somebody!

I am using the Qualia and 2.1 inch display to build an aircraft gauge for my simulator cockpit. To replicate the process I have used on smaller displays using TFT_eSPI, I have a background sprite and then a needle sprite that I apply on top of it at the appropriate angle.
I have the background image sprite working using:

cabinPressureBackground.pushImage (0, 0, 480, 480, cabinPressBackground);
gfx->draw16bitBeRGBBitmap(0, 0, (uint16_t *)cabinPressureBackground.getPointer(), 480, 480);

but for the needle I need to replace the 'draw16bit' command with something that will allow the needle sprite to be pushed to the screen at the right angle. Normally I would use 'pushRotated' from the TFT library. Any ideas?

Have you looked at TFT_eWidgets to replicate what they're doing? I think it's a similar concept to what you're describing.

However, I stopped using them in favor of LVGL. The LVGL dials are very nice and much better than the TFT_eWidgets.

The problem is that TFT_eSPI does not support the ST7701S display, so whilst I can use TFT functions to manipulate the sprites, I need something else (GFX?) to actually to write to the display. It needs to be able to rotate the needle sprite to any angle, which if I could use TFT would be ‘pushRotated’.

I didn't mean replace what you're doing with eWidgets. I meant that the dial widget probably does something similar, so look at that code to see how they do it.

Hi! I found these in Arduino_GFX.h:

Maybe you can use one of them.

Thanks, I had a look at these, but couldn’t see anything capable of rotating a bitmap sprite (unless I am missing something).

I had a look at the meter example, but the meter style appears fixed. More importantly, it relies on TFT_eSPI to be able to write to the display, and TFT_eSPI does not support the ST7701S display I am using, via the Qualia. So I can use TFT to create and manipulate sprites up the the point of writing the sprite to the display, where I need something else.