ESP32 deep sleep with SLS UI

What do you want to achieve?

I want to be able to implement deep sleep while storing UI widgets features, such as color, in the sleep (RTC) memory. my code changes the colors of a set of widgets and I need the new colors to be remembered.

What have you tried so far?I tried to add the RTC_DATA_ATTR in front of the widget names in the ui.h file but it doesn’t seem to work. Then I’ve added the RTC_DATA_ATTRin front of the same widget names in the screen1.c file but I get the following error when compiling: “section attribute cannot be specified for a local variable”

  • Target hardware: lilygo t-watch 2021

Why you change generated code??? Create own variables and own code for this.
And if you dont have battery your changes is lost after power lost in RTC…

@Marian_M thanks a lot for your answer. I am not sure I understood what you mean and perhaps I wasn’t clear in the first place.
My understanding is that SLS creates a variable for every graphic object that is part of the UI. And I found variables with the names of my objects in the ui.h and screen_1.c files.
So how can I create my own variable for the same object if that variable already exists? Could you explain better, maybe I’m just missing something… Angelo

Try shoiw

and maybe i can show you how… Normal way is SLS generate your events file , here you need …

Not sure this is what you asked for, but trying:

This is the part of code that changes the color of a pointer:

if (myButton.isSingleClick())
lv_obj_set_style_arc_color(*ui_Arc_pointer, lv_color_hex(0x40FF4B), LV_PART_MAIN);

And this is where the pointer is associated with an actual lvgl object depending on time:

if (time_seconds < 15 * 60) ui_Arc_pointer = &ui_Arc2

And here is the file ui.h where the lvgl objects are defined… As variables?

extern lv_obj_t * ui_Arc2;

Ok seems you only change to one color ? Then for state store you require bool variable.
In SLS on screens where arc is colored add EVENT on screen load start call function name it as you prefer… Generate code and open ui_events.c

here add

RTC_DATA_ATTR bool color2;

void loadstar(e)
if color2  set
else set original color .

same other events you use here for change on click and store

else false

I think I’m beginning to understand now… :slight_smile:
Thank you so much. I just need to ask you some clarifications:

  1. I actually have 3 possible colors, so I guess I can’t use a bool variable.

  2. In my SLS project I have only one screen and many arc objects. The color change affects all the arcs (3 possible colors for each arc).
    So do I have to add the call function EVENT only to the screen or I need to add an EVENT to each arc?

  3. If I have to add the EVENT to each arc, do I use the same function name for all of them or I need to create functions with different names for each arc?

  4. in the function definition, where you just wrote “set” and “set original color”, I guess I need a more complex syntax. I found this in the ui_Screen1.c file:

    lv_obj_set_style_arc_color(ui_Arc2, lv_color_hex(0x979B97), LV_PART_MAIN

    Is this the correct syntax to use?

  5. Your function appears as loadstar(e), but mine in the ui_events.c appears as ColorSave(lv_event_t * e). Any idea why the argument is different?

  1. all is based on your idea, maybe you need variable for every arcs used or better array or struct of 2bit variables , primary into RTC you can store only little amount vars and need understand that deep sleep wake is MCU reset.
  2. for many arcs you can in func create helping array and use for…
    or if all arcs change to same color you can assign one style to all arcs etc.
  3. one event on screen load is required for init first show after wake up …
  4. yes i write shortest semantics no real code but for change is better create array of possible colors and use it as second argument in lv_obj_set_style_arc_color
  5. as 4 i short and lv_event e is struct with members for example e->target is object sourced event , then you can use one func on many objects… if this is effective

ok… I am trying to implement this. I guess the biggest issue is that my code identifies the arc whose color has to change based on the time of the day (total of 48 arcs, each associated to a 15 minutes window) and I have done this by using a “ui_Arc_pointer” which first is associated to an actual arc based on the time and then has its color changed based on button press (short press = green, long press = red, no press = grey)

if (time_seconds < 15 * 60) ui_Arc_pointer = &ui_Arc2; // store ui_Arc2 address into pointer

And then:

if (myButton.isSingleClick())
lv_obj_set_style_arc_color(*ui_Arc_pointer, lv_color_hex(0x40FF4B), LV_PART_MAIN);
already_changed_arc_color = true;
else if (myButton.isLongClick())
lv_obj_set_style_arc_color(*ui_Arc_pointer, lv_color_hex(0xFF4048), LV_PART_MAIN);
already_changed_arc_color = true;

So to implement this new function in my code I think (not totally sure at this point…) that I would have to create a pointer to my “color_memory” variable, with the variable having 3 possible values (1, 2, 3)

So the code snippets above shoud change into something like this:

if (time_seconds < 15 * 60) {
ui_Arc_pointer = &ui_Arc2; // store ui_Arc2 address into pointer
color_memory_pntr = Color_memory_arc1;


if (myButton.isSingleClick())
lv_obj_set_style_arc_color(*ui_Arc_pointer, lv_color_hex(0x40FF4B), LV_PART_MAIN);
already_changed_arc_color = true;
*color_memory_pntr = 1;
else if (myButton.isLongClick())
lv_obj_set_style_arc_color(*ui_Arc_pointer, lv_color_hex(0xFF4048), LV_PART_MAIN);
already_changed_arc_color = true;
*color_memory_pntr = 2;

But this looks like I would have to write A LOT of lines to cover all cases for all 48 arcs…
Unfortunately I am not familiar with arrays or struct, which maybe could help me streamline the whole thing…

Im lost in your deep sleep idea… When your 48 arcs is every in different state based on time and clicks how you plan recover this state after wake???
If yu have free component in license, create arc as component an in code create array of components in for example flex area …

And no you pointer code example isnt good. I mean

lv_color_t colorsinarc[] = {lv_color_hex(0x40FF4B),lv_color_hex(0xFF4048),...}

lv_obj_set_style_arc_color(*ui_Arc_pointer, colorsinarc[arcstate[0..47]], LV_PART_MAIN);

too what is myButton.isLongClick() , normal SQS have own event system for short and long clicks…

This looks like a great tip, but it’s taking me a while to understand your code.

“colorsinarc[ ]” seems to be an array of 48 colors. Is this correct?
Then the command “lv_obj_set_style_arc_color” is the same I had and has the purpose of changing the color of the arc pointed by “ui_Arc_pointer”.
Is this correct as well?

But I don’t understand “colorsinarc[arcstate[0…47]]”… What is “arcstate”?
And why two sets of square brackets? Is this an array inside another array?
And when you write 0…47, does it mean I have to type there all the numbers? How does it know which one is associated to the pointer?

no colorsinarc is your 3 color array index 0 to 2
and arcstate is actual color on arcs indexed 0 to 47 with values 0 to 2 placed in RTCRAM

So still looking at the code you wrote:


I have to write only one number between 0 and 47, so this syntax produces one color that is then “written” in the arc pointed by the pointer? That’s what I understand but I still miss why I would do that instead of just writing the hex color code…

Maybe I should change this part of my code

if (time_seconds < 15 * 60) ui_Arc_pointer = &ui_Arc2; // store ui_Arc2 address into pointer

Into something like this:

if (time_seconds < 15 * 60) ui_Arc_pointer = &.arcstate[1]; // store ui_Arc1 address into pointer

if (time_seconds < 30* 6ui_Arc_pointer = &arcstate[2]; // store ui_Arc2 address into pointer

Also I would have to change the type of arc_pointer, from an LVGL object to an int

Sorry i cant help you. You ask deep sleep , but showing code without knowledge is waste time. Create for example two arc design and do what you plan with deep sleep.

@Marian_M I understand. You gave me a great help anyways. Hopefully I can work on that and get to the final result by myself. Thank you!