esp32 – Nice UI on a TFT display – pt 5

In the previous parts, I had been using an arduino mega and a TFT display. If you swap out the arduino mega for a 32 bit microcontroller like the esp32, then you can use TFT_eSPI. Which is in part 4b – currently unpublished because I’ve been distracted by a device that I need to make a 4c about, because it uses yet another library for a TFT display

If you are dead set on using a non-32-bit micro controller, then from here you basically have to do the UI all on your own. You use the tft driver to draw shapes, and then you check the touch points and decide how you handle touch down, touch up, whether the touch is close enough to the UI, etc, and you do all of that on your own. Though there may be some library someone has written for it that I didn’t find. Most people seem to be quite content with using an esp32 instead.

Another option is also to get a display with a built in esp32, and using uart, spi, or i2c to communicate with it, and having it handle your UI, and your arduino handle your sensors. This is what I have decided to do, using an ELECROW device for my project. They have surprisingly useful documentation and a playlist on youtube of tutorials. It is however extremely limited on IO, with only i2c, uart0, or a single gpio pin. So I decided to use it in conjunction with other microcontrollers instead of relying exclusively on it.

 

LVGL


Light and Versatile Graphics Library – LVGL is a rather powerful extremely C library. It does also support micropython if that’s your thing, and with how I have recently realized time has covered c++’s pain points, I wouldn’t blame you. But python’s use of whitespace is stupid.

With LVGL, if you are using a TFT_eSPI or LovyanGFX compatible microcontroller and display, then you have a pretty powerful UI framework at your fingertips. And honestly it probably works with other displays too, because part of using it is flushing some buffers to the display

 

The general steps for it

  • setup a config file for LVGL – I recommend using platformio instead of arduino ide, so you can more easily set build flags for where the config file is kept instead of modifying a global file
  • in your setup, you initialize your TFT display
  • call lv_init()
  • implement loop like this

    • though keep in mind that you can do other stuff in loop. you need lvgl to run its even loop.
  • implement a method to handle flushing buffers to your display
  • implement a method to handle mapping touch events from your touch driver to lvgl

That last one is where a lot of power comes from. You are implementing a function to check your display for touches and tell lvgl if it is currently being touched, and where. This allows lvgl to easily handle button presses, scrolling, swiping, etc.

 

I honestly recommend watching the ELECROW tutorials to know how to do this stuff, because it is much easier to process.

But what remains is my thoughts on additional things before diving head first into a project

 

Squareline Studio


Squareline Studio is another interesting piece to the puzzle. LVGL, while powerful, kind of sucks to work with. Its very pointer heavy, and because its C, it ends up being somewhat reliant on global variables and global functions all over the place.

It is technically possible to write c++ wrappers around things so that your not so reliant on global variables and global functions. But you have two sets of resources to maintain now because your c++ and the original c objects are both being created. And you need to make sure you’re not destroying the UI when your c++ stuff goes in and out of scope from being on the stack.

I did that myself in my project. And I would not do it the same way if I were to start over.

So where Squareline Studio comes in, is that it is similar to Xcode’s UI builder. Not the swiftUI stuff, the old one.

With Squareline Studio, you have a drag and drop UI builder. You make the UI, where you can add some event callbacks into your code, or some basic UI events such as screen transitions, or updating labels to match slider values, etc.

Then you export from Squareline Studio, and it will write out a bunch of C files for all of the UI you created in the visual editor

Because LVGL is C and uses so many global variables, Squareline Studio handles making sure your variables are uniquely named, it can also handle naming your variables with prefixes for where they are in your UI to help keep you from making mistakes in your code.

Because Squareline Studio is a visual editor, you don’t have to deal with writing code, deploying it to a microcontroller, and then finally seeing if it looks right. And they have UI for all sorts of things so that you don’t have to go read the documentation about every single thing to know which of the hoard of c functions you can use.

 

Squareline Studio’s cons


Now that we’ve talked about how great Squareline Studio is, we really have to talk about its downsides, which ultimately led me to stop using it within my project

Squareline Studio has a free/personal license. But this license comes with a limitation. And the next license is absolutely insane. There is no middle ground. There is no “I am just making a personal project for myself and want to pay something reasonable for my personal project”

You will either have limitations, or you have to provide them with evidence that you’re a small enough business for the $66 per month small business plan (which I think has to be paid annually, so you can’t just pay for one month, make your project and be done unless you need to add some features in a year)

There is a free trial of the full featured stuff, for 30 days. But from what I can tell, they are somehow tracking your computer, so if you finish your project in 30 days and then find a bug a bit later, you’re screwed unless you have more computers. I would never recommend trying a VM to see if you can circumvent the license, because that would most certainly be a violation of their license policy.

So what are the limitations that make a personal project so limiting

 

You can have up to 10 screens

This is not that limiting for me. But I could see potential projects where this could be a limiting factor. Let’s say you were making a local security camera viewer, and you wanted to have one page per camera, that’s fine as long as you don’t have too many.

 

You can have up to 150 widgets (think ui elements)

This is one limitation that I ran into. I am working on an controller for multiple hdmi switches that are chained together. In total, I have 15 ports that I can plug in. I originally envisioned a UI I could scroll through to pick the port.

  • So you have a button, that’s 1
  • I wanted an icon in the button, so that’s another
  • I want a label in the button so that i can have a name for what device is plugged into the switch, so that’s another
  • I wanted a status indicator to know if something is currently plugged into the port on the switch, so that’s another
  • I wanted another label for which physical port it is (think hdmi 1, whereas the former label would be “Gamecube”)

This gives us 5 widgets * 15 ports = 75 widgets

so half of our UI budget is used up, and that’s before we’ve added a title bar, a settings page, and some UI to edit the names, icons, etc

 

I blew past the 150 widget limit without even trying. And had no choice but to either do things manually in my code, or redesign my UI for fewer UI elements.

 

Unrelated to the pricing – Squareline Studio does not support dynamic list views

You’ll notice that math had 5 widgets * 15 ports, and that’s because you can’t just say I want a list of stuff that looks like this.

If you want to do something like that, you can, but you’ll have to do it in your code.

If you want it in Squareline Studio, it has to all be determined ahead of time. You can show and hide things still, but you can’t just add them from code.

This also means that if you want to reorder things, you’ll have to do that yourself in code.

 

This can be worked around, but it is an extremely limiting factor to Squareline Studio that I think is worth knowing.

 

Back to pricing – You can have up to 1 component

so I’ve got 15 things I want to look identical, and I want to be able to update in one place instead of 15 times.

You can create a component for this.

But you can only have one in your project

 

So I could make a component for my buttons to pick with hdmi port is active, but on the settings page, where now I have 15 “table view rows” I’ve already used up my one and only component.

 

Normally you would be able to make components for things like “list view rows” or “collection view nodes” or whatever other mobile development metaphor you want to use. But on the personal/free license you can’t

 

All in all, I personally found it so limiting that I ended up using it to prototype things, then export the UI, and then look through the code to understand how things were done, but then I ended up writing my own wrapper around LVGL.

Leave a Comment

Your email address will not be published. Required fields are marked *