Issue with ESP32 and ST7798V display

Hello,

I am trying to make a thermostat for my central heating. I decided to include a touchscreen capable display for ease of use. I have bought this display:

I am using this esp32 module:

Using Adafruit_ST7789 library I was able to get things to display (hello,world and a 'blue' background color).

The problem I am facing is that the text is mirrored(or flipped) and blue is actually red(see photo below)

All 4 variants of tft.setRotation do not produce valid results. I tried writing to MADCTL directly from code, but the library defines it and cannot be overwritten.

This is my code:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>

// Define pins
#define TFT_CS   10
#define TFT_RST  9
#define TFT_DC   8

// Initialize display
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
void setup() {
  Serial.begin(115200);

  // Initialize display
  tft.init(240, 320);
  tft.setRotation(0); // Call to ensure basic setup

  // Overwrite MADCTL directly after library setup
  tft.writeCommand(0x36); // MADCTL command
  tft.writedata(0x00);    // Custom value for orientation/mirroring

  // Background and text
  tft.fillScreen(ST77XX_BLUE);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);
  tft.setCursor(50, 100);
  tft.print("Hello, World!");
}

void loop() {
  // Nothing needed here
}

Disclaimer:
1.i know I need to use tft.write16 instead of tft.write.
2.the code is written by ChatGPT so don't quote me on obvious mistakes.

Thank you!

Update : fixed the mirroring of the text, now i am trying to get colors to work right.

Thanks !

Try this:

tft.invertDisplay(true);

https://adafruit.github.io/Adafruit-GFX-Library/html/class_adafruit___g_f_x.html#a45028d348fe4eb23854eb86f5cf99388

Thanks for the reply! I did try setting invertDisplay to true, that only makes red appear yellow on screen. I think my display is of BGR variant. I know I need to change this in the Adafruit_ST7789.h file, I just don't know how. :grin:

If it is the case, unfortunately, I'm not sure if there are any Adafruit products like that.

But TFT_eSPI can support BGR for ST7789.

// For ST7735, ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display
// Try ONE option at a time to find the correct colour order for your display

//  #define TFT_RGB_ORDER TFT_RGB  // Colour order Red-Green-Blue
//  #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red

I considered using TFT_espi , but I can t get it working for nothing :rofl:
I will share my user_setup.h today, and maybe you can tell me what's wrong with it.

Thank you!

this User_Setup.h worked for me

// TFT_eSPI setup.h file for ESP32 Module
// RP2040 Waveshare General 2inch LCD Display Module IPS Screen 240×320 ST7789

#define USER_SETUP_INFO "User_Setup"

#define ST7789_DRIVER      // Full configuration option, define additional parameters below for this display

// For ST7735, ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display
// Try ONE option at a time to find the correct colour order for your display
//  #define TFT_RGB_ORDER TFT_RGB  // Colour order Red-Green-Blue
//  #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red

// For ST7789, ST7735, ILI9163 and GC9A01 ONLY, define the pixel width and height in portrait orientation
#define TFT_WIDTH  240 // ST7789 240 x 240 and 240 x 320
#define TFT_HEIGHT 320 // ST7789 240 x 320

// If colours are inverted (white shows as black) then uncomment one of the next
// 2 lines try both options, one of the options should correct the inversion.

// #define TFT_INVERSION_ON
// #define TFT_INVERSION_OFF

#define TFT_CS   5 
#define TFT_MOSI 23 
#define TFT_SCLK 18 
#define TFT_MISO 19 

#define TFT_DC   17
#define TFT_RST  16

#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF

#define SMOOTH_FONT

#define SPI_FREQUENCY   10000000

#define SPI_TOUCH_FREQUENCY  2500000

running TFT_eSPI library example TFT_Print_Test

Thank you! Valuable information, I will try it soon and give feedback.

Hi,

Still not working for me, i have a black screen showing, any ideas ?

You have to change the following pin assignments to fit your device.

Yours:

I had done that, even switched to @horace wiring, still nothing, i am trying Bodnar's default wiring now, but that should not be a problem since the display worked with Adafruit's library..

Right. At least something was displayed with Adafruit library, so I think the pin assignments at that time is OK.

Hum...

For Adafruit library, it should be as easy as replacing:

switch (rotation) {
  case 0:
    madctl = ST77XX_MADCTL_MY | **ST77XX_MADCTL_RGB**;
    _xstart = _colstart;
    _ystart = _rowstart;
    _width = windowWidth;
    _height = windowHeight;
    break;

With "ST77XX_MADCTL_BGR". But it seems that this is undeclared.

For other .h files (Adafruit_ ST7753.h) in Adafruit library you could be able to do this.

Your display has 2 I/F , 16bit parallel and SPI.

Is the following code for selecting SPI?

No, this is for writing in MADCTL register (see ST7789V datasheet) which should take care of the orientation of the displayed image. However, orientation is working as intended now.

SPI is selected through physical wiring.

if I use the above pins the ESP32 program crashes and goes into a reset loop

looking at ESP32 Pinout Reference: Which GPIO pins should you use?
GPIO8 is connected to the integrated SPI flash
GPIO9 is connected to the integrated SPI flash

what specific ESP32 are you using that you are able to use GPIO8 and 9

This is an error of mine, do not take this in consideration (written by ChatGPT).

going back to post 1 if I attempt to compile the code I get

sketch_dec6a.ino:21:7: error: 'class Adafruit_ST7789' has no member named 'writedata'

also you define

// Define pins
#define TFT_CS   10
#define TFT_RST  9
#define TFT_DC   8

using GPIO 8 and 9 cause my ESP32 to crash and go into a reset loop

yet you show a photo with the display working
did you run the program of post 1 to get the photo or another program?

Hi Horace.

Yes, I know about those errors in that code. That is not the code I used, unfortunately, I've lost the code I used when the screen was working. That tft.writedata should be TFT.write16, and I triple checked the pins, they are correctly wired. You can use the graphicstest_st7789 from the library.

Are you trying to recreate my issue?

I think the OP was trying to solve some problem, but he/she was confused.

So I looked up the ST7789 datasheet and found that MADCTL (Memory Data Access Control) not only controls mirroring/rotation, but also RGB and GBR.

Then, I analyzed the source code of Adafruit and TFT_eSPI and wrote a test program.

My testbed

Test program

This program is a little hard to read, but it uses Adafruit and TFT_eSPI to control RGB and GBR using low-level functions with MADCTL.

#include <Arduino.h>
#include <SPI.h>

// Seeed Studio XIAO ESP32-S3
// https://github.com/espressif/arduino-esp32/blob/master/variants/XIAO_ESP32S3/pins_arduino.h
#define TFT_SCLK  SCK
#define TFT_MISO  MISO
#define TFT_MOSI  MOSI
#define TFT_CS    SS
#define TFT_RST   D1
#define TFT_DC    D0

// Defalult orientation: Portrait
#define TFT_WIDTH   240
#define TFT_HEIGHT  320

/*================================================================================
 * STEP1: Enable or Disable for MADCTL functional test
 *================================================================================*/
#define TEST_MADCTL false

/*================================================================================
 * STEP2: Select GFX library
 *================================================================================*/
#if 1

/*---------------------------------------------------
 * Adafruit GFX Library
 * https://github.com/adafruit/Adafruit-GFX-Library
 * https://github.com/adafruit/Adafruit-ST7735-Library/
 *---------------------------------------------------*/
#include <Adafruit_GFX.h>     // Core graphics library
#include <Adafruit_ST7789.h>  // Hardware-specific library for ST7789

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

#define SCREEN_ROTATION 0
#define INVERT_DSIALAY false

// https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/Adafruit_ST7789.cpp#L40-L77
static const uint8_t PROGMEM
  generic_st7789[] = {                // Init commands for 7789 screens
    9,                                //  9 commands in list:
    ST77XX_SWRESET, ST_CMD_DELAY,     //  1: Software reset, no args, w/delay
    150,                              //     ~150 ms delay
    ST77XX_SLPOUT, ST_CMD_DELAY,      //  2: Out of sleep mode, no args, w/delay
    10,                               //      10 ms delay
    ST77XX_COLMOD, 1 + ST_CMD_DELAY,  //  3: Set color mode, 1 arg + delay:
    0x55,                             //     16-bit color
    10,                               //     10 ms delay
    ST77XX_MADCTL, 1,                 //  4: Mem access ctrl (directions), 1 arg:
    0x08,                             //     Row/col addr, bottom-top refresh
    ST77XX_CASET, 4,                  //  5: Column addr set, 4 args, no delay:
    0x00,
    0,  //     XSTART = 0
    0,
    240,              //     XEND = 240
    ST77XX_RASET, 4,  //  6: Row addr set, 4 args, no delay:
    0x00,
    0,  //     YSTART = 0
    320 >> 8,
    320 & 0xFF,                  //     YEND = 320
    ST77XX_INVON, ST_CMD_DELAY,  //  7: hack
    10,
    ST77XX_NORON, ST_CMD_DELAY,   //  8: Normal display on, no args, w/delay
    10,                           //     10 ms delay
    ST77XX_DISPON, ST_CMD_DELAY,  //  9: Main screen turn on, no args, delay
    10
  };  //    10 ms delay

#else

/*---------------------------------------------------
 * TFT_eSPI Library
 * https://github.com/Bodmer/TFT_eSPI
 *---------------------------------------------------*/
#include <TFT_eSPI.h>

#define SCREEN_ROTATION 0
#define INVERT_DSIALAY false

#define ST77XX_BLUE   TFT_BLUE
#define ST77XX_WHITE  TFT_WHITE

TFT_eSPI tft = TFT_eSPI();

#endif  // Adafruit or TFT_eSPI

/*================================================================================
 * STEP3: Run setup() and loop()
 *================================================================================*/
void setup() {
  Serial.begin(115200);

#if   defined (_ADAFRUIT_GFX_H)

  tft.init(TFT_WIDTH, TFT_HEIGHT);
  tft.invertDisplay(INVERT_DSIALAY);
  tft.setRotation(SCREEN_ROTATION);

#if TEST_MADCTL

  // Adafruit_SPITFT Send Command handles complete sending of commands and data
  // https://github.com/adafruit/Adafruit-GFX-Library/blob/master/Adafruit_SPITFT.cpp#L1973-L2002
  tft.sendCommand(ST77XX_MADCTL, generic_st7789, 1);

#endif  // TEST_MADCTL

#elif defined (_TFT_eSPIH_)

  tft.init();
  tft.invertDisplay(INVERT_DSIALAY);
  tft.setRotation(SCREEN_ROTATION);

#if TEST_MADCTL

  // Overwrite MADCTL directly after library setup
  // https://github.com/Bodmer/TFT_eSPI/blob/master/TFT_eSPI.cpp#L975-L1005
  // https://github.com/Bodmer/TFT_eSPI/blob/master/TFT_Drivers/ST7789_Defines.h#L69-L78
  tft.writecommand(ST7789_MADCTL);  // MADCTL command (0x36)
  tft.writedata(TFT_MAD_RGB);       // TFT_MAD_RGB: 0x00, TFT_MAD_BGR: 0x08

#endif  // TEST_MADCTL

#endif  // _ADAFRUIT_GFX_H or _TFT_eSPIH_

  // Background and text
  tft.fillScreen(ST77XX_BLUE);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);
  tft.setCursor(50, 100);
  tft.print("Hello, World!");
}

void loop() {}

Result of Adafruit


When I run this program, it fails to rewrite the flash unless I start the bootloader. This may be due to the use of low-level functions.

@cpaul09 , I brought up TFT_eSPI because we talked about RGB and BGR, but like @horace did, why not go back to basics and start with something that works with Adafruit?

And please post your full scketch (without MADCTL part). Something should work.