How to refresh screen elements

Description

I have a system that communicates with another hardware, and I want that the screen parameters shown change when differents states of the communications are given.

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

STM32F , but now using the simulator in CodeBlocks

What do you want to achieve?

I want to be able to refresh the state of the buttons/lists, etc… of my screen when an internal event occur in my software. The internal states has many variables that affects different screens, so I should have any way to tell the system that the state of the buttons/leds/labels, etc… has to be recaculated, in order to show the actual state

What have you tried so far?

I hae tried to do it with a task, but then I have to keep a variable for each state of every object, if I don’t want to update all the objects every time. Ideally, an internal “refresh_screen” callback where all the states of all the objects would be calculated again would be the best, and I don’t know if there is some functionality similar to this, or I have to do it all by myself.

Code to reproduce

NOT AVAILABLE

Screenshot and/or video

NOT AVAILABLE

How do your “internal events” work? Are they interrupts or something else? One way of approaching this would be to set things up so that you can simply adjust the object’s state from inside the event itself.

Hello,

My internal events can be caused by interrupts, or by processes: for example, if I lose the communication with a remote device, some options are not available, and then the screen should reflect this, if the current screen has some setting that is affected by this situation.

The problem I see is that I would like to keep the graphical code separated from the “core” code, so changing screen objects from the core code is not ideal for me.

For me the ideal situation would be a function that would set all the objects in a screen in the actual “core” state, that I would call once all the objects have been created, and again when the code knows there is a situation where the change of the internal variables can affect the screen output. Ideally, this function should be a callback associated with the actual screen shown, then the core code would not have to know in which screen you are, only call the refresh_screen callback.

I don’t know if I have explianed well my situation, and if what I say makes sense. I have been working with a modified microchip UI very long time, and I made something similar to what I am explaining, but I don’t know if there is a “correct” way to do this with littlevGL

Thanks

Alex

I’d do this:

  • Create struct will all the objects (lv_obj_t *) you wan’t to refresh.
  • When you create a screen or object save the created object(s) in the struct.
  • Assign an event callback to the objects. It can be the same for every object and you can use a switch case to see which object triggered the event.
  • In LV_EVENT_DELETE set the related object’s pointer to NULL.
  • If something happened with the communication send LV_EVENT_REFRESH event to all objects (use lv_event_send(obj, LV_EVENT_REFRESH, NULL)).
  • In the event callback refresh the object as you need in if LV_EVENT_REFRESH is received.

Thank you.

I have com across a similar solution, with a UI_screen struct that defines callbacks for refresh, previous_screen, task and other stuff that I want to do when changing screens.

I just didn’t know if there was a way to do it from the littlVGL code itself, but as I have seen other people do their own ways, I understand that is an upper level of UI organisation and done my own, though not as elaborated as others I’ve seen, but it will do for now.

Alex

I’ve started to think about a data_bind modul where variable pointers are assigned to lv_obj_t *s. It periodically checks if a variable changes and send LV_EVENT_REFRESH. When the object is deleted it is can be automatically deleted from the bind list too.

What do you think about it?
@embeddedt

It sounds like a useful idea. It would be even better, IMO, if it could be event-driven instead of having to poll for changes.

It sounds good, but I have a pair of questions/suggestions I’m thinking:

  • The update should be configurable, and if you set it to 0, it would be called by the user whenever it is needed.

  • What if the condition to change is not a variable, but a function? Imagine that the condition depends on different states of the system (for example: communication state, and number of channels available). I f you have to do it with variables, you have to create a variable for every combination of states or conditions you may have.

I’ve come with an idea to refresh my screen, but I don’t know if it could have any problems: when I want to load my screen, I have a function that creates all the buttons

  • my_scr_create

and another that sets all the buttons, leds, switches, labels, etc… to the correct value:

  • my_scr_refresh:

I created a callback function which I have initialised to my_scr_refresh, and I call it after creating the screen, and whenever I want to refresh the screen (because any internal states have changed).

What I was thinking is that I can copy all the things that I am doing in my_scr_refresh and put in the LV_EVENT_REFRESH of the callback function of the screen, and then I would only have to call the LV_EVENT_REFRESH of my current screen. Is there any problem with this? I don’t know if this event is used for any other things that could cause problems.

Alex

Do you mean the change should be announced like lv_bind_update(&my_var)?

Why would it be important to set the period individually?

Great question. There can be two functions like:

  • lv_bind_add_var(&my_var, obj)
  • lv_bind_add_func(my_func, obj), int32_t my_func(void)

LV_EVENT_REFRESH is for the user, so your approach should be fine.

Yes. I suppose this is basically the equivalent of setting the period to 0 the way @abueno described it.

It would highly simplify things because with periodical checks we needed to remember the last value to decide it has changed or not. And we should know at least the size of the value to save and compare it.
So a manual announcement seems a reasonable effort from the user for the less complexity in the background.

1 Like

hi @kisvegabor is the data-bind model done in lvgl now?

Finally, we added a very simple interface to build-up widget refreshing.
https://docs.lvgl.io/latest/en/html/overview/event.html#refresh-event

I’m interested in reconsidering it and implement a proper pub-sub model or so.

1 Like

Hey, Im doing something like you, but LV_EVENT_REFRESH, NOT changed!!! (scroll on the screen)

I’m call in my task --> lv_event_send_refresh(page); after --> lv_page_scroll_ver(my_page, -5);

there’s some ““screen update”” or relaod?

Sorry, I don’t really understand. What do you expect to happen and what happens instead?