Guition ESP-32-S3 5-Zoll-ips 16m flash 8m psram jc8048w550c LVGL_Demo_Music screen flickering

hi
i use LVGL 8.3.11. The most things work fine but there are 2 things i didn’t get a clue:
If i touch the speaker button a screen comes up i can change the slider but the value in the program doesn’t change so if i comeback to the slider it is set full to the right.
The slider (not in the main .ino but elsewhere) writes changed values to serial and i can see after doing this 2 times:
16
14
12
11
second time
15
11
9
How can i fix this?

The second point is that if i press play the whole screen is shaking slightly. If i pause it stops shaking.
Does anybody know which problem this could be?

Code from all of this (from the internet )http://pan.jczn1688.com/directlink/1/HMI%20display/JC8048W550.zip

Here the .ino code

#include "HAL.h"

Ticker ticker;
Audio audio;

struct audioMessage
{
  uint8_t cmd;
  const char *txt;
  uint32_t value;
  uint32_t ret;
} audioTxMessage, audioRxMessage;

enum : uint8_t
{
  SET_VOLUME,
  GET_VOLUME,
  CONNECTTOHOST,
  CONNECTTOSD
};

QueueHandle_t audioSetQueue = NULL;
QueueHandle_t audioGetQueue = NULL;

// #include "lv_demo_widgets.h"
#include <lvgl.h>
#include "lv_demos.h"
/*******************************************************************************
 ******************************************************************************/
#include <Arduino_GFX_Library.h>

#define GFX_BL 2
#include "Arduino_GFX_dev_device.h"

/*******************************************************************************
 * Please config the touch panel in touch.h
 ******************************************************************************/
#include "touch.h"


/* Change to your screen resolution */
static uint32_t screenWidth;
static uint32_t screenHeight;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *disp_draw_buf1;
static lv_color_t *disp_draw_buf2;
static lv_disp_drv_t disp_drv;

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

#if (LV_COLOR_16_SWAP != 0)
  gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
  gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif

  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  if (touch_has_signal())
  {
    if (touch_touched())
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touch_last_x;
      data->point.y = touch_last_y;
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

void CreateQueues()
{
  audioSetQueue = xQueueCreate(10, sizeof(struct audioMessage));
  audioGetQueue = xQueueCreate(10, sizeof(struct audioMessage));
}

void audioTask(void *parameter)
{
  CreateQueues();
  if (!audioSetQueue || !audioGetQueue)
  {
    log_e("queues are not initialized");
    while (true)
    {
      ; // endless loop
    }
  }

  struct audioMessage audioRxTaskMessage;
  struct audioMessage audioTxTaskMessage;

  while (true)
  {
    if (xQueueReceive(audioSetQueue, &audioRxTaskMessage, 1) == pdPASS)
    {
      if (audioRxTaskMessage.cmd == SET_VOLUME)
      {
        audioTxTaskMessage.cmd = SET_VOLUME;
        audio.setVolume(audioRxTaskMessage.value);
        audioTxTaskMessage.ret = 1;
        xQueueSend(audioGetQueue, &audioTxTaskMessage, portMAX_DELAY);
      }
      else if (audioRxTaskMessage.cmd == CONNECTTOHOST)
      {
        audioTxTaskMessage.cmd = CONNECTTOHOST;
        audioTxTaskMessage.ret = audio.connecttohost(audioRxTaskMessage.txt);
        xQueueSend(audioGetQueue, &audioTxTaskMessage, portMAX_DELAY);
      }
      else if (audioRxTaskMessage.cmd == CONNECTTOSD)
      {
        audioTxTaskMessage.cmd = CONNECTTOSD;
        audioTxTaskMessage.ret = audio.connecttoSD(audioRxTaskMessage.txt);
        xQueueSend(audioGetQueue, &audioTxTaskMessage, portMAX_DELAY);
      }
      else if (audioRxTaskMessage.cmd == GET_VOLUME)
      {
        audioTxTaskMessage.cmd = GET_VOLUME;
        audioTxTaskMessage.ret = audio.getVolume();
        xQueueSend(audioGetQueue, &audioTxTaskMessage, portMAX_DELAY);
      }
      else
      {
        log_i("error");
      }
    }
    audio.loop();
  }
}

void audioInit()
{
  xTaskCreatePinnedToCore(
      audioTask,
      "audioplay",
      5000,
      NULL,
      2 | portPRIVILEGE_BIT,
      NULL,
      0);
}

audioMessage transmitReceive(audioMessage msg)
{
  xQueueSend(audioSetQueue, &msg, portMAX_DELAY);
  if (xQueueReceive(audioGetQueue, &audioRxMessage, portMAX_DELAY) == pdPASS)
  {
    if (msg.cmd != audioRxMessage.cmd)
    {
      log_e("wrong reply from message queue");
    }
  }
  return audioRxMessage;
}
void audioSetVolume(uint8_t vol)
{
  audioTxMessage.cmd = SET_VOLUME;
  audioTxMessage.value = vol;
  audioMessage RX = transmitReceive(audioTxMessage);
}

uint8_t audioGetVolume()
{
  audioTxMessage.cmd = GET_VOLUME;
  audioMessage RX = transmitReceive(audioTxMessage);
  return RX.ret;
}

bool audioConnecttohost(const char *host)
{
  audioTxMessage.cmd = CONNECTTOHOST;
  audioTxMessage.txt = host;
  audioMessage RX = transmitReceive(audioTxMessage);
  return RX.ret;
}

bool audioConnecttoSD(const char *filename)
{
  audioTxMessage.cmd = CONNECTTOSD;
  audioTxMessage.txt = filename;
  audioMessage RX = transmitReceive(audioTxMessage);
  return RX.ret;
}

void tcr1s()
{
  uint32_t act = audio.getAudioCurrentTime();
  uint32_t afd = audio.getAudioFileDuration();
  uint32_t pos = audio.getFilePos();
  // hape change
  //Serial.println(act);
  //Serial.println(afd);
  // ENDE hape change 
  // Serial.println("audioTime: %i:%02d - duration: %i:%02d", (act / 60), (act % 60) , (afd / 60), (afd % 60));
}

// lvgl -ui -------------------------------------------------------------------------------

static void event_handler(lv_event_t *e)
{
  lv_event_code_t code = lv_event_get_code(e);

  if (code == LV_EVENT_CLICKED)
  {
    LV_LOG_USER("Clicked");
    Serial.println("test");
  }
  else if (code == LV_EVENT_VALUE_CHANGED)
  {
    LV_LOG_USER("Toggled");
    Serial.println("test2");
  }
}

void lv_example_btn_1(void)
{
  lv_obj_t *label;

  lv_obj_t *btn1 = lv_btn_create(lv_scr_act());
  lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);
  lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);

  label = lv_label_create(btn1);
  lv_label_set_text(label, "test");
  lv_obj_center(label);

  //        lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
  //        lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);
  //        lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);
  //        lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
  //        lv_obj_set_height(btn2, LV_SIZE_CONTENT);
  //
  //        label = lv_label_create(btn2);
  //        lv_label_set_text(label, "Toggle");
  //        lv_obj_center(label);
}

// lvgl -ui end-----------------------------------------------------------------------------

void setup()
{

//  Serial.begin(115200);
  Serial.begin(115200);
  while(!Serial) delay(10);

  audioInit();

  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  Serial.print("I2S_BCLK: ");
  Serial.println(I2S_BCLK);
  Serial.print("I2S_LRC: ");
  Serial.println(I2S_LRC);  
  Serial.print("I2S_DOUT: ");
  Serial.println(I2S_DOUT);    

  audio.setVolume(20); // 0...21

//  log_i("current volume is: %d", audioGetVolume());
  Serial.print("current volume is: ");
  Serial.println(audioGetVolume());  

  audio.setVolume(15); // 0...21
  Serial.print("current volume is: ");
  Serial.println(audioGetVolume());  

  ticker.attach(1, tcr1s);

  Serial.println("LVGL Widgets Demo");

  // Init touch device

  //
  // Init Display
  if (!gfx->begin())
  // if (!gfx->begin(80000000)) /* specify data bus speed */
  {
    Serial.println("gfx->begin() failed!");
  }
#ifdef GFX_BL
  pinMode(GFX_BL, OUTPUT);
  digitalWrite(GFX_BL, HIGH);
#endif
  //  gfx->fillScreen(RED);
  //  delay(500);
  //  gfx->fillScreen(GREEN);
  //  delay(500);
  //  gfx->fillScreen(BLUE);
  //  delay(500);
  gfx->fillScreen(BLACK);
  delay(50);
  lv_init();
  delay(10);
  touch_init();

  sdcard_init();
  delay(50);

  screenWidth = gfx->width();
  screenHeight = gfx->height();
#ifdef ESP32
  //disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 4, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  disp_draw_buf1 = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 8, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  disp_draw_buf2 = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 8, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
#else
  disp_draw_buf = (lv_color_t *)malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 4);
#endif
  if (!disp_draw_buf1 && !disp_draw_buf2)
  {
    Serial.println("LVGL disp_draw_buf allocate failed!");
  }
  else
  {
    lv_disp_draw_buf_init(&draw_buf, disp_draw_buf1, disp_draw_buf2, screenWidth * screenHeight / 8);

    /* Initialize the display */
    lv_disp_drv_init(&disp_drv);
    /* Change the following line to your display resolution */
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    /* Initialize the (dummy) input device driver */
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = my_touchpad_read;
    lv_indev_drv_register(&indev_drv);

#if 0
      lv_example_btn_1();
#else
    // lv_demo_widgets();
    lv_demo_music();

    Serial.println("Setup done");
#endif
  }
}

void loop()
{
  lv_timer_handler(); /* let the GUI do its work */
}

//*****************************************************************************************
//                                  E V E N T S                                           *
//*****************************************************************************************

// optional
void audio_info(const char *info)
{
  Serial.print("info        ");
  Serial.println(info);
}
void audio_id3data(const char *info)
{ // id3 metadata
  Serial.print("id3data     ");
  Serial.println(info);
}
void audio_eof_mp3(const char *info)
{ // end of file
  Serial.print("eof_mp3     ");
  Serial.println(info);
}
void audio_showstation(const char *info)
{
  Serial.print("station     ");
  Serial.println(info);
}
void audio_showstreamtitle(const char *info)
{
  Serial.print("streamtitle ");
  Serial.println(info);
}
void audio_bitrate(const char *info)
{
  Serial.print("bitrate     ");
  Serial.println(info);
}
void audio_commercial(const char *info)
{ // duration in sec
  Serial.print("commercial  ");
  Serial.println(info);
}
void audio_icyurl(const char *info)
{ // homepage
  Serial.print("icyurl      ");
  Serial.println(info);
}
void audio_lasthost(const char *info)
{ // stream URL played
  Serial.print("lasthost    ");
  Serial.println(info);
}

any ideas how to solve are very welcome

hape

It looks like you are doing everything on one core of the ESP. Doing anything audio related is going to be using a hell of a lot of interrupts to get the data so what is more than likely happening is all of those interrupts taking place are causing problems and disruptions in the GUI code. I would set the Arduino IDE so it defaults to core zero and then use the xTaskCreatePinnedToCore function to handle all of the audio functions so they run on core 1. Now remember when you do this you will not be able to have the audio code directly change anything in LVGL without using a mutex or even better would be a task notification that you can pass between 2 tasks.

Another things that will cause the screen to move about is if you are using an RGB display is going to be the pixel clock frequency. You may have to adjust the clock up or down in 500mhz increments to see if it goes away or gets worse. I am not seeing any of the code that sets up the hardware side of the display so I am not able to help in that area.

This here

void loop()
{
  lv_timer_handler(); /* let the GUI do its work */
}

is also a problem because it is causing that core to run balls to the ball all the time and it’s not giving other tasks time to run properly. You need to stall that core in a manner that doesn’t cause a spinning wheel. Use If you use the task notifications you can set up a task that runs for the tick increment so it runs once a millisecond and when it runs send a notification to the main task that is running which will release the stall so it will run lv_task_handler. This same arrangement is what you should also use to pass any data from the audio task that needs to update the GUI. only have the main task doing anything with updating the GUI and calling task_handler.

I am also going to recommend ditching the Arduino IDE. It is using a really old version of the ESP-IDF and the esp_lcd component is not available to use on it either. The Arduino GFX library is a bit bang driver which is slow and it also doesn’t support using DMA memory. You are going to be better off from a performance standpoint if you use the ESP-IDF directly and have it build the firmware for you.

@kdschlosser thx for your very interesting statements. I will take a look on all the things you mentioned and change the program. Afterwards i will tell about my experiences with all of this.
hape