Need help with the new Module

Hello everyone,

some days ago i have purchased this module: 3.5" ESP32-S3 IPS Display Capacitive Touch Screen JC3248W535C ESP32-S3-WROOM-1 TFT LCD Module 320 x 480 AXS15231B.
I searched on the web for a guide but i didn't find a guide.
I want to ask here if someone has already experienced this module.
According to the datasheet this module should have AXS15231B as a driver.
This module uses ESP32-S3 as micro controller.
But i am not realy sure if this driver is the LCD driver or something else.
I have already tried to use this work written by NorthernMan54 but i had no success (compiler error), it cann't find some libraries.
So please if someone can guide me to the right way to play with this module, i will appreciate that.
EDIT:
I have downloaded this library LVGL and tried to compile an example provided by it but i get the following comlipe error:

h:\Documents\Arduino\libraries\lvgl\src\examples\styles\lv_example_style_14.c:1:10: fatal error: ../lvgl/src/themes/lv_theme_private.h: No such file or directory
    1 | #include "../lvgl/src/themes/lv_theme_private.h"

Although the path to the "lv_theme_private.h" is correct as it int the "lv_example_style_14.h".
What am i missing here?

Links to cookie sites are not accepted. Please extract the info You want to refer to and post it here.

Post the full code in code tags. Post the full verbose error log also in code tags.
Post a link to where you purchased the board.

Here is where i have purchased this module
And here is the default example from the lvgl library which i use:

/*Using LVGL with Arduino requires some extra steps:
 *Be sure to read the docs here: https://docs.lvgl.io/master/integration/framework/arduino.html  */

#include <lvgl.h>

//#if LV_USE_TFT_ESPI
#include <TFT_eSPI.h>
//#endif

/*To use the built-in examples and demos of LVGL uncomment the includes below respectively.
 *You also need to copy `lvgl/examples` to `lvgl/src/examples`. Similarly for the demos `lvgl/demos` to `lvgl/src/demos`.
 *Note that the `lv_examples` library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
 *as the examples and demos are now part of the main LVGL library. */

#include <examples/lv_examples.h>
#include <demos/lv_demos.h>

/*Set to your screen resolution and rotation*/
#define TFT_HOR_RES   320
#define TFT_VER_RES   240
#define TFT_ROTATION  LV_DISPLAY_ROTATION_0

/*LVGL draw into this buffer, 1/10 screen size usually works well. The size is in bytes*/
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];

TFT_eSPI tft = TFT_eSPI(TFT_HOR_RES, TFT_VER_RES);

#if LV_USE_LOG != 0
void my_print( lv_log_level_t level, const char * buf )
{
    LV_UNUSED(level);
    Serial.println(buf);
    Serial.flush();
}
#endif

/* LVGL calls it when a rendered image needs to copied to the display*/
void my_disp_flush( lv_display_t *disp, const lv_area_t *area, uint8_t * px_map)
{
    /*Copy `px map` to the `area`*/

    /*For example ("my_..." functions needs to be implemented by you)*/
    uint32_t w = lv_area_get_width(area);
    uint32_t h = lv_area_get_height(area);

    tft.startWrite();
    tft.setAddrWindow( area->x1, area->y1, w, h );
    tft.pushColors( ( uint16_t * )&px_map, w * h, true );
    tft.endWrite();
    // my_set_window(area->x1, area->y1, w, h);
    // my_draw_bitmaps(px_map, w * h);
     

    /*Call it to tell LVGL you are ready*/
    lv_display_flush_ready(disp);
}

/*Read the touchpad*/
void my_touchpad_read( lv_indev_t * indev, lv_indev_data_t * data )
{
    /*For example  ("my_..." functions needs to be implemented by you)
    int32_t x, y;
    bool touched = my_get_touch( &x, &y );

    if(!touched) {
        data->state = LV_INDEV_STATE_RELEASED;
    } else {
        data->state = LV_INDEV_STATE_PRESSED;

        data->point.x = x;
        data->point.y = y;
    }
     */
}

/*use Arduinos millis() as tick source*/
static uint32_t my_tick(void)
{
    return millis();
}

void setup()
{
    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

    Serial.begin( 115200 );
    Serial.println( LVGL_Arduino );
    Serial.println( "I am LVGL_Arduino" );

    lv_init();

    /*Set a tick source so that LVGL will know how much time elapsed. */
    lv_tick_set_cb(my_tick);

    /* register print function for debugging */
#if LV_USE_LOG != 0
    lv_log_register_print_cb( my_print );
#endif

    tft.begin();
    tft.setRotation(0);

    // lv_disp_draw_buf_init( &draw_buf, buf, NULL, TFT_HOR_RES * TFT_VER_RES / 10 );   // Probably / 4

    lv_display_t * disp;
 #if LV_USE_TFT_ESPI
    /*TFT_eSPI can be enabled lv_conf.h to initialize the display in a simple way*/
    disp = lv_tft_espi_create(TFT_HOR_RES, TFT_VER_RES, draw_buf, sizeof(draw_buf));
    lv_display_set_rotation(disp, TFT_ROTATION);

#else
    /*Else create a display yourself*/
    disp = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
    lv_display_set_flush_cb(disp, my_disp_flush);
    lv_display_set_buffers(disp, draw_buf, NULL, sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
#endif

    /*Initialize the (dummy) input device driver*/
    lv_indev_t * indev = lv_indev_create();
    lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /*Touchpad should have POINTER type*/
    lv_indev_set_read_cb(indev, my_touchpad_read);

    /* Create a simple label
     * ---------------------
     lv_obj_t *label = lv_label_create( lv_screen_active() );
     lv_label_set_text( label, "Hello Arduino, I'm LVGL!" );
     lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );

     * Try an example. See all the examples
     *  - Online: https://docs.lvgl.io/master/examples.html
     *  - Source codes: https://github.com/lvgl/lvgl/tree/master/examples
     * ----------------------------------------------------------------

     lv_example_btn_1();

     * Or try out a demo. Don't forget to enable the demos in lv_conf.h. E.g. LV_USE_DEMO_WIDGETS
     * -------------------------------------------------------------------------------------------

     lv_demo_widgets();
     */

    lv_obj_t *label = lv_label_create( lv_screen_active() );
    lv_label_set_text( label, "Hello Arduino, I'm LVGL!" );
    lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );

    Serial.println( "Setup done" );
}

void loop()
{
    lv_timer_handler(); /* let the GUI do its work */
    delay(5); /* let this time pass */
}

And here is the error message:

In file included from h:\Documents\Arduino\libraries\lvgl\src\examples\styles\lv_example_style_14.c:1:
h:\Documents\Arduino\libraries\lvgl\src\examples\styles\lv_theme_private.h:17:10: fatal error: lv_theme.h: No such file or directory
   17 | #include "lv_theme.h"
      |          ^~~~~~~~~~~~
compilation terminated.

I did excactly what stand in the comment.

Some library is not installed or it is broken.

I found a little solution on the net but it need some modification.
The problem now i am encountring is:
no matter how i set the cursor it does not print on the right position.
Here is the code:

#include "JC3248W535.h"

int16_t W, H;
int16_t X, Y;
int8_t R;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  while(!Serial);
  Serial.println("Initializing Display");

  #ifdef GFX_EXTRA_PRE_INIT
    GFX_EXTRA_PRE_INIT()
  #endif

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

  gfx->fillScreen(WHITE);

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

  Serial.println("gfx has began");
  // gfx->setTextBound(0, 0, 320, 480);

  delay(2000); // 5 seconds

  #ifdef CANVAS
    gfx->flush();
  #endif

  delay(1000);

  W = gfx->width();
  H = gfx->height();

  X = gfx->getCursorX();
  Y = gfx->getCursorY();
  R = gfx->getRotation();

  Serial.println("BEFORE WRITTING: ");
  Serial.print("Width W: ");
  Serial.print(W);
  Serial.print(", Height H: ");
  Serial.print(H);
  Serial.print(", Cursor X: ");
  Serial.print(X);
  Serial.print(", Cursor Y: ");
  Serial.print(Y);
  Serial.print(", Rotation R: ");
  Serial.println(R);

  delay(1500);
  gfx->setCursor(X + 10, Y + 10);
  Serial.println("AFTER SETTING THE CURSOR: ");
  Serial.print("Width W: ");
  Serial.print(W);
  Serial.print(", Height H: ");
  Serial.print(H);
  Serial.print(", Cursor X: ");
  Serial.print(gfx->getCursorX());
  Serial.print(", Cursor Y: ");
  Serial.print(gfx->getCursorY());
  Serial.print(", Rotation R: ");
  Serial.println(R);
  delay(1500);
  gfx->setTextColor(BLACK, WHITE);
  gfx->setTextWrap(false);
  gfx->setTextSize(5);
  gfx->print("Hello World");
  delay(2500);
  
  Serial.println("AFTER WRITTING: ");

  X = gfx->getCursorX();
  Y = gfx->getCursorY();
  R = gfx->getRotation();

  Serial.print("Width W: ");
  Serial.print(W);
  Serial.print(", Height H: ");
  Serial.print(H);
  Serial.print(", Cursor X: ");
  Serial.print(gfx->getCursorX());
  Serial.print(", Cursor Y: ");
  Serial.print(gfx->getCursorY());
  Serial.print(", Rotation R: ");
  Serial.println(R);

  gfx->setCursor(45, Y + 100);

  Serial.println("AFTER NEW SETTING THE CURSOR: ");
  Serial.print("Width W: ");
  Serial.print(W);
  Serial.print(", Height H: ");
  Serial.print(H);
  Serial.print(", Cursor X: ");
  Serial.print(gfx->getCursorX());
  Serial.print(", Cursor Y: ");
  Serial.print(gfx->getCursorY());
  Serial.print(", Rotation R: ");
  Serial.println(R);

  gfx->setTextColor(BLUE, YELLOW);
  gfx->print("123");
  delay(2500);
}

void loop() {
  // put your main code here, to run repeatedly:

}

here is how the display look like:


EDIT:
the JC3248W535.h file:

#pragma once

// Display
#include <Arduino_GFX_Library.h>
#define GFX_BL 1
Arduino_DataBus *bus = new Arduino_ESP32QSPI(
    45 /*CS*/, 47 /*SCK*/, 21 /*D0*/, 48 /*D0*/, 40 /*D2*/, 39 /*D3*/);
// #define CANVAS_R1
#ifdef CANVAS_R1
Arduino_AXS15231B *g = new Arduino_AXS15231B(bus, GFX_NOT_DEFINED /* RST */, 0 /* Rotation */, false /* IPS */, 320 /* Width */, 480 /* Height */);
#define CANVAS
Arduino_Canvas *gfx = new Arduino_Canvas(320 /* Width */, 480 /* Height */, g, 0 /* Output_x */, 0 /* Output_y */, 1 /* Rotation */);
#else
Arduino_AXS15231B *gfx = new Arduino_AXS15231B(bus, GFX_NOT_DEFINED /* RST */, 0 /* Rotation */, false /* IPS */, 320 /* Width */, 480 /* Height */);
#endif
#define GFX_SPEED 4000000UL

// Button
// #define BTN_A_PIN 0
// #define BTN_B_PIN 21

// I2C
#define I2C_SDA 4 // 8
#define I2C_SCL 8 // 4

// Touch schreen
#define TOUCH_MODULES_GT911
#define TOUCH_MODULE_ADDR GT911_SLAVE_ADDRESS1
#define TOUCH_SCL I2C_SCL
#define TOUCH_SDA I2C_SDA
#define TOUCH_RES 38
#define TOUCH_INT 3

// SD card
#define SD_SCK  12
#define SD_MOSI 11 // CMD
#define SD_MISO 13 // D0
// #define SD_D1 1
// #define SD_D2 6
#define SD_CS   10 // D3

// I2S
#define I2S_DEFAULT_GAIN_LEVEL 0.1
#define I2S_OUTPUT_NUM I2S_NUM_0
#define I2S_MCLK -1
#define I2S_BCLK 42
#define I2S_LRCK 2
#define I2S_DOUT 41
#define I2S_DIN -1

// #define AUDIO_MUTE_PIN 48   // LOW for mute

Could anyone successfully make this module to work with arduino ide?

Hey, after a couple of days of grinding I got the LCD to work, I have the same device and don't want to use LVGL. Here is a simple example

#include <Arduino_GFX_Library.h>
#define GFX_BL 1  // Backlight pin
Arduino_DataBus *bus = new Arduino_ESP32QSPI(45, 47, 21, 48, 40, 39);
Arduino_GFX *g = new Arduino_AXS15231B(bus, GFX_NOT_DEFINED /* RST */, 0 /* rotation */, false /* IPS */, 320 /* width */, 480 /* height */);
Arduino_Canvas *gfx = new Arduino_Canvas(320 /* width */, 480 /* height */, g, 0 /* output_x */, 0 /* output_y */, 0 /* rotation */);
void setup() {
  if (!gfx->begin()) {
    Serial.println("Display initialization failed!");
    return;
  }

  if (GFX_BL != GFX_NOT_DEFINED) {
    pinMode(GFX_BL, OUTPUT);
    digitalWrite(GFX_BL, HIGH);  // Turn backlight on
  }

  // Clear screen and set background color
  gfx->fillScreen(BLACK);

  // Draw basic shapes
  gfx->fillCircle(160, 120, 50, RED);
  gfx->drawRect(50, 50, 100, 60, BLUE);
  gfx->fillTriangle(200, 200, 250, 100, 300, 200, GREEN);

  // Draw text
  gfx->setTextColor(WHITE);
  gfx->setTextSize(2);
  gfx->setCursor(80, 250);
  gfx->println("Arduino GFX");

  gfx->flush();
}

void loop() {
  // Simple animation
  for (int i = 0; i < 320; i += 10) {
    gfx->fillCircle(i, 300, 10, YELLOW);
    gfx->flush();
    delay(1);
    gfx->fillCircle(i, 300, 10, BLACK);  // Erase previous position
  }
}

1 Like

Does anyone succeed to read the touch pad. Please paste a copy of the relevant code.
Regards
André

Hello,

I'm using your code and just paint a red line in the top left.

Any idea?

Thank you

I've spent a few days fighting the Guition branded JC3248W535C which uses AXS15231B combo driver chip. I've got it working nicely now with either just Arduino_GFX or lvgl (v9).
These were my notes:
Worked through driver files and disabled everything after start up. Still had the problem.

Tracked down to a batch operation run during TFT_Init() and contained in Arduino_AXS15231B.h

Cross referenced commands against AXS data sheet and annotated file.

  1. There was an extraneous sofware reset. Disabling it removed the flicker so there had been a continous reset loop - hence the flickering.

  2. Now half the screen worked and the rest was a mess.
    There were a whole batch of write to buffer memory instructions which had no command equivalent in the data sheet.
    Disabling these got normal operation.

  3. Was also able to disable the first power cycle pair of commands leaving just the final sequence. The final delay (100) was necessary otherwise it didn't work on power up.

  4. Put my modified version of Arduino_AXS15231B.h into the program folder to protect against library updates or reloads.

Didn't need to change anything else.

This is the setup bit in my program

	#include <Arduino_GFX_Library.h>		// driver for axs15231 display
	#include "esp_lcd_touch_axs15231b.h"	// touch driver (NOT the display)
	#include <Wire.h>
	//#include "TCA9554.h"					// I2C 8 output expander not present on Guition JC3248W535C 
	
	#define QSPI_CS   45					// tested correct
	#define QSPI_CLK  47
	#define QSPI_D0   21
	#define QSPI_D1   48
	#define QSPI_D2   40
	#define QSPI_D3   39

	#define LCD_BL 1 						// backlight pin
	#define I2C_SDA       4					// NB reversed on schematic
	#define I2C_SCL       8					// tested correct



//********* INITIALISATIONS ****************************************************************************//
	
// DISPLAY DRIVER
	// copying from 10_lvgl9 example setup which works (screen and touch) 
	Arduino_DataBus *bus = new Arduino_ESP32QSPI(QSPI_CS, QSPI_CLK, QSPI_D0, QSPI_D1, QSPI_D2, QSPI_D3, false);

	Arduino_GFX *gfx_out = new Arduino_AXS15231B(bus, -1, 0, false, 320, 480);	// (port, reset, rotation, ips, w ,h)

	// AXS15231B needs a display buffer. If not using lvgl, use Canvas. PSRAM is essential.
	// buffer contents are transferred to display using gfx->flush()
	
	Arduino_Canvas *gfx = new Arduino_Canvas(320, 480, gfx_out, 0, 0, 0);	// (w, h, output, x , y, rotation)

I hope that helps .

I found something here, but I can't copy the code. The person who posted it can't post links.

https: //www.youtube.com/watch?v=TM-QS3BodIo