How to change existing transformation style?

I’m trying to rotate a widget depending on some sensor data. For that I added a:

lv_obj_set_style_transform_rotation(ui_obj, 0, LV_STATE_DEFAULT);

Which works once, but if I try to change it with another call inside the loop() the program hangs. I also tried it to create a new style and attach that to the object, and change the style (and inform the object that a style property has changed) - the program hangs.

How can I do that?

I use that a lot in some projects:

lv_obj_set_style_transform_rotation(objects.img_radar_arrow, temp_arc, LV_PART_MAIN | LV_STATE_DEFAULT);

And don’t have any issue, can you share that code section?

Thank You

Sure!

void setup() {
...
    int outerDiam = (int)(screenWidth * 0.8);

    ui_outerBall = lv_obj_create(lv_scr_act());
    lv_obj_remove_style_all(ui_outerBall);
    lv_obj_set_width(ui_outerBall, outerDiam);
    lv_obj_set_height(ui_outerBall, outerDiam);
    lv_obj_set_align(ui_outerBall, LV_ALIGN_CENTER);
    lv_obj_set_style_radius(ui_outerBall, outerDiam / 2, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(ui_outerBall, lv_color_hex(0x3D65BC), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_outerBall, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_grad_color(ui_outerBall, lv_color_hex(0x916040), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_main_stop(ui_outerBall, 128, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_grad_stop(ui_outerBall, 128, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_grad_dir(ui_outerBall, LV_GRAD_DIR_VER, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_color(ui_outerBall, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_opa(ui_outerBall, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(ui_outerBall, 1, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_transform_rotation(ui_outerBall, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_transform_pivot_x(ui_outerBall, outerDiam/2, LV_PART_MAIN| LV_STATE_DEFAULT);
    lv_obj_set_style_transform_pivot_y(ui_outerBall, outerDiam/2, LV_PART_MAIN| LV_STATE_DEFAULT);
}

void loop() {
  lv_task_handler();

  ahrs.step();

...

  lv_obj_set_style_transform_rotation(ui_outerBall, (int)ahrs.getRoll(), LV_PART_MAIN | LV_STATE_DEFAULT);
}

After playing around a bit I found out that not the update is the problem, but the call itself.

If I’m calling lv_obj_set_style_transform_rotation(ui_outerBall, 0, LV_PART_MAIN | LV_STATE_DEFAULT); with any different value than 0 for the second parameter, the program hangs.

The rotation seems to need a lot of memory.

[Trace]	(5.091, +1)	 lv_malloc_zeroed: allocating 28 bytes lv_mem.c:94
[Trace]	(5.092, +1)	 lv_malloc_zeroed: allocated at 0x3fc9ab90 lv_mem.c:115
[Trace]	(5.093, +1)	 lv_malloc: allocating 58567 bytes lv_mem.c:64
[Info]	(5.094, +1)	 lv_malloc: couldn't allocate memory (58567 bytes) lv_mem.c:73
[Trace]	(5.095, +1)	 lv_mem_monitor_core: begin lv_mem_core_builtin.c:201
[Trace]	(5.096, +1)	 lv_mem_monitor_core: finished lv_mem_core_builtin.c:219
[Info]	(5.097, +1)	 lv_malloc: used: 7584 ( 12 %), frag:   1 %, biggest free: 55912 lv_mem.c:77
[Warn]	(5.098, +1)	 lv_draw_buf_create_ex: No memory: 121x121, cf: 16, stride: 484, 58564Byte,  lv_draw_buf.c:272
[Trace]	(5.099, +1)	 lv_free: freeing 0x3fc9ab90 lv_mem.c:132
[Warn]	(5.100, +1)	 lv_draw_layer_alloc_buf: Allocating layer buffer failed. Try later lv_draw.c:506

even doubling LV_MEM_SIZE doesn’t help:

[Trace]	(5.267, +1)	 lv_malloc_zeroed: allocating 28 bytes lv_mem.c:94
[Trace]	(5.268, +1)	 lv_malloc_zeroed: allocated at 0x3fc9ad88 lv_mem.c:115
[Trace]	(5.269, +1)	 lv_malloc: allocating 88807 bytes lv_mem.c:64
[Info]	(5.270, +1)	 lv_malloc: couldn't allocate memory (88807 bytes) lv_mem.c:73
[Trace]	(5.271, +1)	 lv_mem_monitor_core: begin lv_mem_core_builtin.c:201
[Trace]	(5.272, +1)	 lv_mem_monitor_core: finished lv_mem_core_builtin.c:219
[Info]	(5.273, +1)	 lv_malloc: used: 8752 (  7 %), frag:  49 %, biggest free: 61800 lv_mem.c:77
[Warn]	(5.274, +1)	 lv_draw_buf_create_ex: No memory: 149x149, cf: 16, stride: 596, 88804Byte,  lv_draw_buf.c:272
[Trace]	(5.275, +1)	 lv_free: freeing 0x3fc9ad88 lv_mem.c:132
[Warn]	(5.276, +1)	 lv_draw_layer_alloc_buf: Allocating layer buffer failed. Try later lv_draw.c:506

Seems that I need to implement a different way.

Hi

Yes, most likely. Tried on the simulator and it worked “normally”, but in Simulator there is no issues with “memory”.

In my test case I set the screenWidth at 480, the buffer required is 620944 bytes (3943944), (4 since color format is ARGB888).

If your processor (Assuming is an ESP32) has PSRAM, you could try to move the LVGL memory to the PSRAM and increase the size of it substantially for it to work.

I did something similar to a recent product, and went to directly paint on the screen, using lv_draw_triangle_dsc_t and lv_draw_triangle in the event LV_EVENT_DRAW_MAIN, the points and so on needed to be manually calculated.

It also seems to have quite some performance issues, so I decided to implement my own draw method. Thanks for the help.