Guru Meditation Error with PlatformIO and ESP32

Description

Hi,

could you please help me with this kind of usual-looking error so I can run the LVGL library? After I upload my code for ESP32 in PlatformIO it always gives me this kind of error:

I was going through some similar problems in the forum, but I wasn’t able to do anything with that.

What MCU/Processor/Board and compiler are you using?

NodeMCU ESP32

What LVGL version are you using?

LVGL 8.0.1

What do you want to achieve?

After uploading the code, the screen is just blinking, so I would like to run this simple sketch on my ILI9341 display.

Code

#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];

int screenWidth = 320;
int screenHeight = 240;

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp_drv, 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);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors(&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp_drv);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    uint16_t touchX, touchY;

    bool touched = tft.getTouch(&touchX, &touchY, 600);

    if(!touched)
    {
      //return false;
    }

    if(touchX>screenWidth || touchY > screenHeight)
    {
      Serial.println("Y or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else
    {

      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
  
      /*Save the state and save the pressed coordinate*/
      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
     
      /*Set the coordinates (if released use the last pressed coordinates)*/
      data->point.x = touchX;
      data->point.y = touchY;
  
      Serial.print("Data x");
      Serial.println(touchX);
      
      Serial.print("Data y");
      Serial.println(touchY);

    }

    //return false; /*Return `false` because we are not buffering and no more data to read*/
}

void setup()
{
    Serial.begin(115200); /* prepare for possible serial debug */

    lv_init();

    tft.begin(); /* TFT init */
    tft.setRotation(1); /* Landscape orientation */

    uint16_t calData[5] = {196, 3676, 256, 3856, 1};
    tft.setTouch(calData);

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

    /*Initialize the display*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.hor_res = 320;
    disp_drv.ver_res = 240;
    lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
    

    /*Initialize the input device driver*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    /* Create simple label */
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello Arduino! (V7.0.X)");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}


void loop()
{
    lv_task_handler(); /* let the GUI do its work */
    delay(1);
}

Thank you so much in advance!

You should set the lv_tick_handler . This code works for me, If you can’t run it, try to run ESPexceptionDecoder

#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>


#define LVGL_TICK_PERIOD 10
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI();
uint16_t calData[5] = { 464, 3363, 307, 3419, 1 }; 

/* Serial debugging */
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{

    Serial.printf("%s@%d->%s\r\n", file, line, dsc);
    Serial.flush();
}
#endif

/* 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);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors(&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
}



bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    uint16_t touchX, touchY;

    bool touched = tft.getTouch(&touchX, &touchY, 600);

    if(!touched)
    {
      data->state = LV_INDEV_STATE_REL;
      return false;
    }
    else
    {
      data->state = LV_INDEV_STATE_PR;
    }

    if(touchX>screenWidth || touchY > screenHeight)
    {
      Serial.println("Y or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else
    {
      /*Set the coordinates*/
      data->point.x = touchX;
      data->point.y = touchY;
  
      Serial.print("Data x");
      Serial.println(touchX);
      
      Serial.print("Data y");
      Serial.println(touchY);

    }

    return false; /*Return `false` because we are not buffering and no more data to read*/
}

static void lv_tick_handler(void)
{
  lv_tick_inc(LVGL_TICK_PERIOD);
}

void setup()
{
    Serial.begin(115200); /* prepare for possible serial debug */

    lv_init();

    tft.begin(); /* TFT init */
    tft.setRotation(1); /* Landscape orientation */

    uint16_t calData[5] = {196, 3676, 256, 3856, 1};
    tft.setTouch(calData);

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

    /*Initialize the display*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.hor_res = 320;
    disp_drv.ver_res = 240;
    lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
    

    /*Initialize the input device driver*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
    
    xSemaphore = xSemaphoreCreateMutex(); //mutex to handle the processes 

    /* Create simple label */
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello Arduino! (V7.0.X)");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

void loop()
{
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
    lv_task_handler ();
    xSemaphoreGive(xSemaphore);
    delay(5);
    
}
1 Like

Thanks, but this code shows me that the xSemaphore is not defined.

image

Have the same problem

Yeah, true, still trying to solve it, but it’s not working… anyone else with some idea?

I found out how to read the backtrace (something like ESPexceptionDecoder) and it shows this:

Used code:

#include <Arduino.h>
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>

#define LVGL_TICK_PERIOD 20
Ticker tick; /* timer for interrupt handler */

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];

int screenWidth = 320;
int screenHeight = 240;

#if USE_LV_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{

  Serial.printf("%s@%d->%s\r\n", file, line, dsc);
  delay(100);
}
#endif

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint16_t c;

  tft.startWrite(); /* Start new TFT transaction */
  tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.writeColor(c, 1);
      color_p++;
    }
  }
  tft.endWrite(); /* terminate TFT transaction */
  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
  lv_tick_inc(LVGL_TICK_PERIOD);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    uint16_t touchX, touchY;

    bool touched = tft.getTouch(&touchX, &touchY, 600);

    if(!touched)
    {
      //return false;
    }

    if(touchX>screenWidth || touchY > screenHeight)
    {
      Serial.println("Y or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else
    {

      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
  
      /*Save the state and save the pressed coordinate*/
      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
     
      /*Set the coordinates (if released use the last pressed coordinates)*/
      data->point.x = touchX;
      data->point.y = touchY;
  
      Serial.print("Data x");
      Serial.println(touchX);
      
      Serial.print("Data y");
      Serial.println(touchY);

    }

    //return false; /*Return `false` because we are not buffering and no more data to read*/
}

void setup()
{
    Serial.begin(115200); /*prepare for possible serial debug*/

    lv_init();

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

    tft.begin(); /*TFT init*/
    tft.setRotation(1); /*Landscape orientation*/

    uint16_t calData[5] = {196, 3676, 256, 3856, 1};
    tft.setTouch(calData);

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

    /*Initialize the display*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.hor_res = 320;
    disp_drv.ver_res = 240;
    lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/

    /*Initialize the graphics library's tick*/
    tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);

    /*Initialize the input device driver*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    /*Create simple label*/
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello Arduino!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}


void loop()
{
    lv_task_handler ();
    delay(5);
    
}

add #include <freertos/semphr.h>
can compile ok,but still not work

Try putting some serial prints in to see where it gets up to. You could also have a power supply thats not providing enough power.

Sorry you must define the semaphore:

SemaphoreHandle_t xSemaphore = NULL;

Your exception its to weird, are you tryed with other esp32? Is it possible that you have a short circuit? Or less than the recommended power supply?

Even with the semaphore it does not work :confused:

Maybe I will try different ESP, because the power supply is totally ok.
I don’t know, it’s really weird…

It always breaks up in the loop…

#include <Arduino.h>
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>

#define LVGL_TICK_PERIOD 20
Ticker tick; /* timer for interrupt handler */

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];

int screenWidth = 320;
int screenHeight = 240;

#if USE_LV_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{

  Serial.printf("%s@%d->%s\r\n", file, line, dsc);
  delay(100);
}
#endif

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint16_t c;

  tft.startWrite(); /* Start new TFT transaction */
  tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.writeColor(c, 1);
      color_p++;
    }
  }
  tft.endWrite(); /* terminate TFT transaction */
  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
  lv_tick_inc(LVGL_TICK_PERIOD);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    uint16_t touchX, touchY;

    bool touched = tft.getTouch(&touchX, &touchY, 600);

    if(!touched)
    {
      //return false;
    }

    if(touchX>screenWidth || touchY > screenHeight)
    {
      Serial.println("Y or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else
    {

      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
  
      /*Save the state and save the pressed coordinate*/
      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
     
      /*Set the coordinates (if released use the last pressed coordinates)*/
      data->point.x = touchX;
      data->point.y = touchY;
  
      Serial.print("Data x");
      Serial.println(touchX);
      
      Serial.print("Data y");
      Serial.println(touchY);

    }

    //return false; /*Return `false` because we are not buffering and no more data to read*/
}

void setup()
{
    Serial.begin(115200); /*prepare for possible serial debug*/

    lv_init();

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

    Serial.println("1");

    tft.begin(); /*TFT init*/
    tft.setRotation(1); /*Landscape orientation*/

    uint16_t calData[5] = {196, 3676, 256, 3856, 1};
    tft.setTouch(calData);

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

    Serial.println("2");

    /*Initialize the disply*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.hor_res = 320;
    disp_drv.ver_res = 240;
    lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/

    /*Initialize the graphics library's tick*/
    tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);

    Serial.println("3");

    /*Initialize the input device driver*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    /*Create simple label*/
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello Arduino!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

    Serial.println("4");
}


void loop()
{
    Serial.println("5");
    lv_task_handler ();
    delay(5);
    Serial.println("6");
}

After putting it to ArduinoIDE and analyzing it with ESPexceptionDecoder, it shows this:

The same problem occurred on my board, the Board will run properly lvgl7

1 Like

What is the pin configuration of the ili9341? Are you sure the declarations in TFT_eSPI are correct? The code I sent you works for me with a 240x320 ILI9341 display and ESP32 nodeMCU with this pin configuration:

#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 5
#define TFT_DC 4
#define TFT_RST 22
#define TOUCH_CS 14

Do you have your lv_conf.h statements okay?

/* Maximal horizontal and vertical resolution to support by the library.*/
#define LV_HOR_RES_MAX          (240)
#define LV_VER_RES_MAX          (320)
1 Like

The TFT_eSPI is definitely correct, because all the TFT_eSPI examples work just fine. My conf is this:

#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS  15
#define TFT_DC    2 
#define TFT_RST   4 
#define TOUCH_CS 21

And the lv.conf.h statemenst are also correct.

Try with lvgl 7 for check if it works

1 Like

Yeah, it’s exactly as you say, the latest v7 is working just fine, but both v8.0 or v8.1 are damaged for my ESP. I will definitely try different controler because I’d like to use the latest version of LVGL, but for now, I think it will be enough.

Thank you all for your effort, especially @Alvaro_Mourazo for your time!

Hopefully there won’t be such problems for next versions. Thanks again!

1 Like