GC9A01 Display Not Working with Arduino Nano ESP32

I am trying to get my display to run the test example (color_Test)file that came with the TFT_eSPI library and I get a blank screen. I am confident that I have the user selected setup configured correctly with pin assignments for my setup. The file loads fine to the Arduino Nano ESP32 S3 with no errors but nothing happens. I used an oscilloscope to probe the pins with the program running and all pins show 3.3V except for the SDA pin which shows a square wave and the SCL pin is showing nothing (0V). I believe there should be a signal on the SCL pin. I have tried several different pins for the SCL output with the same result. Any advice is appreciated to get this working.

Try swapping SDA and SCL.
If you're seeing clock signals on SDA, something is likely wired incorrectly SCL is the designated clock line in I2C communication. Swapping SDA and SCL won’t damage anything, and it's a quick way to rule out a wiring issue.

Also, make sure you have appropriate pull-up resistors (typically 4.7kΩ–10kΩ) on both SDA and SCL lines. Many I2C devices include them internally, but some do not, and missing pull-ups can cause unreliable communication.

Thank you. I am certain I have the lines connected properly unless they are mismarked on the GC9A01 device itself. I will try the pull up resistors on the SDA and the SCA lines. (need to go out of town for 5 days so likely won't get to try it until then)
I appreciate the feedback.

You should show your wiring diagram and code.

// See SetupX_Template.h for all options available
#define USER_SETUP_ID 46

#define GC9A01_DRIVER

#define TFT_SPI_PORT -1 //added by PatL to make sure overrides on pin settings are used

#define TFT_MISO -1 //was 19
#define TFT_MOSI 23// was 23 also czlled SDA
#define TFT_SCLK 19 // was 18
#define TFT_CS 22 //was 15 but Don't have it on my board - Chip select control pin
#define TFT_DC 2 //Data Command control pin
#define TFT_RST 4 //Reset pin (could connect to RST pin)

//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST

#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT

#define SPI_FREQUENCY 10000000 // was 40000000

#define SPI_READ_FREQUENCY 20000000

#define SPI_TOUCH_FREQUENCY 2500000

// #define SUPPORT_TRANSACTIONS

Also, in the reviews of this display on Amazon, someone said ..... " I just had to change the spi data mode to spi_mode0 in dev_config.cpp and then everything started working.". I don't see how to do that.

I had watched the suggested video before attempting the setup. His esp32 board is a little different in configurations so I change the pin out to match my board. I only wanted to run the color test that is included as an example with the TFT_eSPI library to verify the display hook up was correct but that's when I got stuck because the screen stays black. I have 3 of these displays and tried another w/o success. I also tried taking the BLK pin high by connecting it to the 3.3V and that didn't help. When I get a chance next week, I plan to try the pull up resistor suggestion on SDA and SCL lines

Wrap your code in a code block...

I think you did not upload the entire sketch.

You are right, I did not upload the entire sketch. I uploaded the setup file just so you can see the pin assignments and the other definitions that are in we set up file The sketch is actually the example called color test from the TFT_eSPI library examples. This is the same test example that he ran in the video that was referenced in this thread.

Did you follow (both understand and execute) the DroneBotWorkshop instructions for editing the library file?

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.

Would you add a "display pin/signal/mcu pin" table in your wiring image? "Purple" is an antenna? Don't make it so you can read it. Make it so everyone can read it.

I am on the road for the next several days and will need to follow up on this next Wed when I am able to . Thank you for the followup though

To answer your questions though, I did follow the instructions for editing the setup files, although I used the user_setup_select process and used the user setup file I posted (046). The purple is simply not hooked up . It is the BKL pin on the display and he had it hooked up to 3.3V. Other people don't hook it up at all. IAs I mentioned above, I did try it with it hooked up to 3.3V and it didn't change anything.
I will add the pin assignment table explicitly to make it more obvious. (it is shown in the picture of the wiring and cross referenced to the setup file pin assignments)
Does anyone have any suggestions on my question of the Mode0 recommendation from the Amazon review?(in the above post)

All wires should connect at both ends, or they act as an antenna. Sensitive micro-electronics might pick up on that (not saying this is the cause, just stating a best practice).

Also not important, but when I see SDA and SCL I think "I2C" rather than "SPI" where I think MISO, MOSI and SCK (and SS). Is there a "SPI" (or the signals) enable or a "I2C" (or the signals) disable?

I do not have a solution. I can only ask questions that (hopefully) help you toward a solution. Sometimes, after you have stared at the same thing for so long that "everything" is right, but "nothing" works... it only takes a second set of eyes and a question that seems irrelevant... and poof, there it is...

Or, it broke in shipping. (but I doubt anything broke)

Thank you for the feedback and the questions, I agree that it is common to stare at a problem repeatedly and not see the issue that is sometimes right in front of us. I am traveling at this time so can't get to my project. I'll be back at it mid next week. I'll have to learn more about your comments on the SPI and 12C.

I am back in town and trying to get the display to work again.
Here are the pin outs in table form:

GC9AA01 Display BLK (Pu) 3.3V
GC9AA01 Display CS (Blu) 22 (A5)
GC9AA01 Display DC (Gr) 2 (D2)
GC9AA01 Display RES (Or) 4 (D4)
GC9AA01 Display SDA(MOSI or DIN) (Y) 23 (A6)
GC9AA01 Display SCL (SCLK or CLK) (W) 19 (A2)
GC9AA01 Display VIN 3.3V
GC9AA01 Display GND GND
and here is the example called color test from the TFT_eSPI library:

//   Diagnostic test for the displayed colour order
//
// Written by Bodmer 17/2/19 for the TFT_eSPI library:
// https://github.com/Bodmer/TFT_eSPI

/* 
 Different hardware manufacturers use different colour order
 configurations at the hardware level.  This may result in
 incorrect colours being displayed.

 Incorrectly displayed colours could also be the result of
 using the wrong display driver in the library setup file.

 Typically displays have a control register (MADCTL) that can
 be used to set the Red Green Blue (RGB) colour order to RGB
 or BRG so that red and blue are swapped on the display.

 This control register is also used to manage the display
 rotation and coordinate mirroring. The control register
 typically has 8 bits, for the ILI9341 these are:

 Bit Function
 7   Mirror Y coordinate (row address order)
 6   Mirror X coordinate (column address order)
 5   Row/column exchange (for rotation)
 4   Refresh direction (top to bottom or bottom to top in portrait orientation)
 3   RGB order (swaps red and blue)
 2   Refresh direction (top to bottom or bottom to top in landscape orientation)
 1   Not used
 0   Not used

 The control register bits can be written with this example command sequence:
 
    tft.writecommand(TFT_MADCTL);
    tft.writedata(0x48);          // Bits 6 and 3 set
    
 0x48 is the default value for ILI9341 (0xA8 for ESP32 M5STACK)
 in rotation 0 orientation.
 
 Another control register can be used to "invert" colours,
 this swaps black and white as well as other colours (e.g.
 green to magenta, red to cyan, blue to yellow).
 
 To invert colours insert this line after tft.init() or tft.begin():

    tft.invertDisplay( invert ); // Where invert is true or false

*/

#include <SPI.h>

#include <TFT_eSPI.h>       // Hardware-specific library

TFT_eSPI tft = TFT_eSPI();  // Invoke custom library

void setup(void) {
  tft.init();

  tft.fillScreen(TFT_BLACK);
  tft.drawRect(0, 0, tft.width(), tft.height(), TFT_GREEN);

  // Set "cursor" at top left corner of display (0,0) and select font 4
  tft.setCursor(0, 4, 4);

  // Set the font colour to be white with a black background
  tft.setTextColor(TFT_WHITE);

  // We can now plot text on screen using the "print" class
  tft.println(" Initialised default\n");
  tft.println(" White text");
  
  tft.setTextColor(TFT_RED);
  tft.println(" Red text");
  
  tft.setTextColor(TFT_GREEN);
  tft.println(" Green text");
  
  tft.setTextColor(TFT_BLUE);
  tft.println(" Blue text");

  delay(5000);

}

void loop() {

  tft.invertDisplay( false ); // Where i is true or false
 
  tft.fillScreen(TFT_BLACK);
  tft.drawRect(0, 0, tft.width(), tft.height(), TFT_GREEN);

  tft.setCursor(0, 4, 4);

  tft.setTextColor(TFT_WHITE);
  tft.println(" Invert OFF\n");

  tft.println(" White text");
  
  tft.setTextColor(TFT_RED);
  tft.println(" Red text");
  
  tft.setTextColor(TFT_GREEN);
  tft.println(" Green text");
  
  tft.setTextColor(TFT_BLUE);
  tft.println(" Blue text");

  delay(5000);


  // Binary inversion of colours
  tft.invertDisplay( true ); // Where i is true or false
 
  tft.fillScreen(TFT_BLACK);
  tft.drawRect(0, 0, tft.width(), tft.height(), TFT_GREEN);

  tft.setCursor(0, 4, 4);

  tft.setTextColor(TFT_WHITE);
  tft.println(" Invert ON\n");

  tft.println(" White text");
  
  tft.setTextColor(TFT_RED);
  tft.println(" Red text");
  
  tft.setTextColor(TFT_GREEN);
  tft.println(" Green text");
  
  tft.setTextColor(TFT_BLUE);
  tft.println(" Blue text");

  delay(5000);
}

Here is a bit of an update. I switched the pin outs to what I was told was a more standard set of pins to possibly eliminate another variable. I am now using:

BLK (Pu) 3.3V
CS (Blu) 10 (D10)
DC (Gr) 2 (D2)
RES (Or) 4 (D4)
SDA(MOSI or DIN) (Y) 11 (D11)
SCL (SCLK or CLK) (W) 12 (D12)
VIN 3.3V
GND GND

Since I am not getting an output signal at all ont he sclk pin but was getting one on the SDA/MOSI pin, I had ChatGPT generate be a simple sketch using the new pinout to simply see if the pins would output the sclk signal. It did generate an oscilloscope signal as expected. The color_test program does not so I suspect there is something missing in the setup process using that example but am not experienced enough to figure out the difference between the code other than that the color_test relies on the User_Setup file that I have checked several times. Here is the code/sketch that will generate a sclk signal. It seems like until I get a signal on the SCLK pin, other actions are not going to help unless I misunderstand how the display works.

#include <SPI.h>

// Define SPI pin numbers explicitly
#define PIN_MOSI 11  // default VSPI MOSI on some Nano ESP32 S3 boards
#define PIN_SCLK 12  // default VSPI SCLK
#define PIN_CS   10


void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Starting SPI signal test...");

  // Start SPI on specified pins
  SPI.begin(PIN_SCLK, -1, PIN_MOSI, PIN_CS); // SCLK, MISO (not used), MOSI, SS

  // Set CS pin to output and high (inactive)
  pinMode(PIN_CS, OUTPUT);
  digitalWrite(PIN_CS, HIGH);

  // Confirm pin setup
  Serial.printf("MOSI: GPIO %d, SCLK: GPIO %d, CS: GPIO %d\n", PIN_MOSI, PIN_SCLK, PIN_CS);
}

void loop() {
  byte data1 = 0xAA;
  byte data2 = 0x55;
  byte data3 = 0xFF;

  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // 1 MHz, Mode 0

  digitalWrite(PIN_CS, LOW); // Select device (CS low)

  SPI.transfer(data1);
  SPI.transfer(data2);
  SPI.transfer(data3);

  digitalWrite(PIN_CS, HIGH); // Deselect device (CS high)

  SPI.endTransaction();

  Serial.print("Sent bytes: 0x");
  Serial.print(data1, HEX);
  Serial.print(", 0x");
  Serial.print(data2, HEX);
  Serial.print(", 0x");
  Serial.println(data3, HEX);

  delay(1000); // Wait 1 second
}....

After many hours/days of beating my head against the wall, I read on github that apparently the more recent versions of the TFT-eSPI library fail with the ESP32. The choice is to revert to a pretty old version or add "#define USE_HSPI_PORT" to the user setup file before pin assignment. This now at least gives me signals as measured on the oscilloscope on both the SCL and MOSI pins.
I still am not getting any display but at least I can narrow my focus a little. I may return the displays I bought (Jessinie GC9A01) and try a different brand

Maybe one of the topics on the bottom of the page has info to help you.

@patl did you find a way to get it to work? I have the same issue. My board is a little different. It's from the Waveshare ESP32-S3 Nano. However, it also uses an Arduino ESP32 on board selection. So both are the same. I'm also stuck with the GC9A01 display, no matter what I do, I get only a black screen. But the display works fine with other boards, such as ESP32 S3 Zero, C3 Super mini, and ESP32 WROOM Devkit. I was about to give up when I saw this thread.