A generic ESP32 firmware

Hi,
I was triggered by an offer of a Cheap Yellow Display (CYD) (with accompanying book which is … well … don’t ask).

After taking a few first steps, I thought that the device might be nice as a display/controller for our home automation stuff:

  • Show some kind of calendar informing about future events, eg which of our 4 different bins has to be placed out,
  • Control several electrical appliances, eg a pump to circulate the hot water from our solar heating,
  • Inform about various statusses, eg whether doors and windows are closed/locked.

I quickly decided that it would be quite cumbersome to continuously update the source code to add new buttons or indicators. Instead, I thought about writing a generic firmware for the ESP32 and configure it using a set of description files describing the various screens that the CYD should display. So far, the code only supports buttons and labels (and labels inside buttons).

PS I plan to publish the code on Github once it has reached a usable state. I still need some kind of scale with indicator (lv_meter) and I need to figure out how to get rid of an entire screen to load a new screen.

1 Like

Hello @jmoellers
That’s awesome

LVGL supports runtime UI using XML
https://docs.lvgl.io/master/xml/xml/overview.html#using-the-xml-files

Check the scale docs here Scale (lv_scale) - LVGL 9.5 documentation

About changing the screens, see
https://docs.lvgl.io/master/common-widget-features/screens.html#loading-screens

1 Like

@fbiego Thanks!
I’m only scratching the surface of LVGL at the moment.
As to XML: My understanding was that an XML parser took up more space than a json parser. I also had some contact with json when I set up kea on a RasPi, so I tried that first.
Again: Thanks!

Hm, when reading the documentation on XML, I come to the understanding that the XML files are fixed. One of my intentions is that I want to be able to

  • create the files on demand and
  • even if the files already exist, they can be parametrized.
    Re the latter: I have written a microhttp-based server program that will (of course!) serve the pages but will parse each line before serving and replace $directive$ by whatever the directive is: eg I’d like to have a similar layout no matter what the size of the screen is, so I use "width": $15.625%W$, "height": $15.625%W$ to get a square button proportional to the width of the screen.

As to the scale: it misses an indicator! I’d like to use it to display thermometers to show temperatures eg in our garage or on the patio and I can’t see how the lv_scale would indicate the current temperature. Thus said, I have been playing around with adding an lv_button (will probably become an lv_label with text “>”) and put it outside and next to the scale plus some means to connect the position of the indicator with some MQTT topic, eg garage/temperature and terrasse/temperature, so the location of the indicator depends upon the value of that topic.

I greatly appreciate this fruitful discussion. As I wrote: I’m still a beginner as far as LVGL is concerned. I have written quite a few Perl/Tk and also some QT-based programs but so far my LVGL knowledge is rudimentary.

Oh … BTW … here’s a simple page description:

{
“width”: “320”,
“height”: “240”,
“widgets”: [
{
“type”: “button”,
“x”: 40,
“y”: 95,
“width”: $15.625%W$,
“height”: $15.625%W$,
“color”: [ 255, 0, 0 ],
“align”: “tl”,
“inside”: { “type”: “label”, “align”: “c”, “text”: “\uf2ed” } // LV_SYMBOL_TRASH
},
{
“type”: “button”,
“x”: 100,
“y”: 95,
“width”: $15.625%W$,
“height”: $15.625%W$,
“color”: [ 0, 255, 0 ],
“align”: “tl”,
“inside”: { “type”: “label”, “align”: “c”, “text”: “\uF287” } // LV_SYMBOL_USB
},
{
“type”: “button”,
“x”: 160,
“y”: 95,
“width”: $15.625%W$,
“height”: $15.625%W$,
“color”: [ 0, 0, 255 ],
“align”: “tl”,
“inside”: { “type”: “label”, “align”: “c”, “text”: “\uF240” } // LV_STR_SYMBOL_BATTERY_FULL
},
{
“type”: “thermo”,
“x”: 220,
“y”: 10,
“align”: “tl”,
“source”: “mqtt,172.16.1.22,/garage/temperatur”,
“indicator”: { “type”: “button”, “x”: 0, “y”: 0, “align”: “olb”, “h”: 10, “w”: 10, “color”: [ 255, 0, 0 ] }
},
{
“type”: “label”,
“x”: $12.5%W$,
“y”: $4.1667%H$,
“align”: “tl”,
“text”: “Hello, world”
}
]
}

Hi!

Regarding creating files on demand. One thing you could try doing to update components with dynamic XML is using:

lv_xml_register_component_from_data("dynamic_ui_component", xml_data_buffer);

xml_data_buffer could be an xml file data generated on demand and retrieved from a web server for example.

An then do:

lv_obj_t * new_screen = lv_xml_create(lv_screen_active(), "dynamic_ui_component", NULL);

Here is the documentation with some more details about XML components: Components - LVGL 9.5 documentation