Crash when use lv_qrcode_update function on my code

In my code below, everything works correctly, but when I call the lv_qrcode_update() function, ESP32-S3 keeps restarting, am I initializing something incorrectly? can anybody help me?

Here is the example code:

#include <lvgl.h>
#include <lv_qrcode.h>
#include <Arduino_GFX_Library.h>
#define TFT_BL 2
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */

Arduino_ESP32RGBPanel *bus = new Arduino_ESP32RGBPanel(
    GFX_NOT_DEFINED /* CS */, GFX_NOT_DEFINED /* SCK */, GFX_NOT_DEFINED /* SDA */,
    41 /* DE */, 40 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
    14 /* R0 */, 21 /* R1 */, 47 /* R2 */, 48 /* R3 */, 45 /* R4 */,
    9 /* G0 */, 46 /* G1 */, 3 /* G2 */, 8 /* G3 */, 16 /* G4 */, 1 /* G5 */,
    15 /* B0 */, 7 /* B1 */, 6 /* B2 */, 5 /* B3 */, 4 /* B4 */
);
// option 1:
// 7寸 50PIN 800*480
Arduino_RPi_DPI_RGBPanel *gfx = new Arduino_RPi_DPI_RGBPanel(bus,
                                                             800 /* width */, 0 /* hsync_polarity */, 210 /* hsync_front_porch */, 30 /* hsync_pulse_width */, 16 /* hsync_back_porch */,
                                                             480 /* height */, 0 /* vsync_polarity */, 22 /* vsync_front_porch */, 13 /* vsync_pulse_width */, 10 /* vsync_back_porch */,
                                                             1 /* pclk_active_neg */, 16000000 /* prefer_speed */, true /* auto_flush */);

#endif /* !defined(DISPLAY_DEV_KIT) */
#include "touch.h"

/* Change to your screen resolution */
static uint32_t screenWidth = 800;
static uint32_t screenHeight = 480;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *disp_draw_buf;

lv_obj_t *mainScreen;
lv_obj_t *title;
lv_obj_t *PixQrCode;
LV_IMG_DECLARE(ui_logo_img_obj);

/* 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;
      Serial.print("Data x ");
      Serial.println(data->point.x);
      Serial.print("Data y ");
      Serial.println(data->point.y);
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup()
{
  Serial.begin(115200);
  // while (!Serial);
  Serial.println("LVGL Widgets Demo");
  // Init Display
  gfx->begin();
  gfx->setRotation(0);

#ifdef TFT_BL
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);

  ledcSetup(0, 300, 8);
  ledcAttachPin(TFT_BL, 0);
  ledcWrite(0, 255); /* Screen brightness can be modified by adjusting this parameter. (0-255) */

#endif
  lv_init();
  disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 4, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight / 4);

  /* Initialize the display */
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  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);

  // Init touch device
  // pinMode(TOUCH_GT911_RST, OUTPUT);
  // digitalWrite(TOUCH_GT911_RST, LOW);
  // delay(10);
  // digitalWrite(TOUCH_GT911_RST, HIGH);
  // delay(10);
  // touch_init();

  // lv_demo_widgets();
  // lv_demo_music();
  ui_init();

  Serial.println("Setup done");
}

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

void ui_init()
{
  ui_background();
  lv_disp_load_scr(mainScreen);
}

void lv_example_qrcode_1(void)
{
  lv_color_t bg_color = lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 5);
  lv_color_t fg_color = lv_palette_darken(LV_PALETTE_BLUE, 4);

  lv_obj_t *qr = lv_qrcode_create(lv_scr_act(), 10, bg_color, fg_color);
  // lv_qrcode_set_size(qr, 150);
  // lv_qrcode_set_dark_color(qr, fg_color);
  // lv_qrcode_set_light_color(qr, bg_color);

  /*Set data*/
  const char *data = "https://lvgl.io";
  lv_qrcode_update(qr, data, strlen(data));
  lv_obj_center(qr);

  /*Add a border with bg_color*/
  lv_obj_set_style_border_color(qr, bg_color, 0);
  lv_obj_set_style_border_width(qr, 5, 0);
}

void ui_background()
{
  mainScreen = lv_obj_create(NULL);
  lv_obj_clear_flag(mainScreen, LV_OBJ_FLAG_SCROLLABLE);

  title = lv_img_create(mainScreen);
  lv_img_set_src(title, &ui_logo_img_obj);
  lv_obj_set_size(title, 320, 117);
  lv_obj_set_pos(title, 0, 0);
  lv_obj_set_align(title, LV_ALIGN_TOP_MID);
  lv_obj_add_flag(title, LV_OBJ_FLAG_ADV_HITTEST);
  lv_obj_clear_flag(title, LV_OBJ_FLAG_SCROLLABLE);

  lv_obj_t *titleLabel = lv_label_create(mainScreen);
  lv_obj_set_pos(titleLabel, 0, 120);
  lv_obj_set_align(titleLabel, LV_ALIGN_TOP_MID);
  lv_label_set_text(titleLabel, "QRCODE");
  lv_obj_clear_flag(titleLabel, LV_OBJ_FLAG_CLICKABLE);
  lv_obj_set_style_text_font(titleLabel, &lv_font_montserrat_34, LV_PART_MAIN | LV_STATE_DEFAULT);

  lv_example_qrcode_1();
}

don't you need to actually allocate memory for this, not just allocate memory for a pointer?

also read https://pcbartists.com/firmware/notes-using-lvgl-with-esp32/

Hi Jackson

I use this pointer here:

lv_init();
  disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 4, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight / 4);

To inicialize the display, conforming the hardware docs

ah right - I missed the malloc / init

from the link I shared, it does not seem obvious with all ESP32

Yeah, tks for the link, is very useful, i think is something about the way of this board use a ttf drive, in real its very strange behavior, because on crash when i user a lvgl function below:

lv_qrcode_update(qr, data, strlen(data));

All of the code works whell, i will investigate this better when i have some time.

Hy, to register here, i resolved the problem switching from Arduino_GFX to LovyanGFX.

1 Like

Thx for coming back with the solution !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.