Logarithmic Scale meter (VU sound meter) using LVGL on ESP32-S3

Description

I’m trying to implement a digital VU meter using LVGL and ESP32 S3 wroom 1. The audio data input samples are converted to a logarithmic scale and the goal is to display these values on LCD in the form of a meter. I tried using “meter” widget in LVGL v8.40 However, this only supports linear scale. Now, I’m planning to use LVGL v9.0 which doesn’t have meter widget anymore. Instead it uses “scale” widget. After researching a bit on how to make the scale logarithmic, I came across some information about using LVGL events callbacks. But the scale widget in LVGL v9.0 doesn’t support LVGL events. I need help with how this can be implemented using LVGL v9.0? Any help is appreciated. Thanks.

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

ESP32-S3 LCD EV dev board

What LVGL version are you using?

v9.0

What do you want to achieve?

Display a sound VU meter on LCD.

What have you tried so far?

Tried using meter widget from lvgl v8.40. But this only allows to use linear scale. And preferably want to develop with v9.0 going forward.

1 Like

This is exactly what I need for the project that I am working on right now. It is a device that does many different things with audio signals. E.g. measuring levels, but also plot the spectrum and so on. Really plotting data in a logarithmic way is the only thing I am missing in this wonderful library. Right now I am still designing the interfaces, but when it comes to Implementation I am happy to add this to the project. At least if I manage to do it :smile: have you had any progress on this?

You are either going to want to custom render it using the canvas widget or you will use the scale widget. Either way the data doesn’t need to be logarithmic. It can simply be a scalar level so the data is normalized to a 0.0 to 1.0 scale. This would make it easier to deal with. What you are going to have to do is write a freertos task that will run on the second core that has the sole purpose of handling the data and passing that data to LVGL running on the first core. The reason why you will want it done this way is so that the task running on the second core will handle ramping the changes from one value to the next so the meter doesn’t just jump from one value to the next. it will smoothly move. The value gets sent to the task running on the first core and that task picks up the value and sets it to the widget and then immediately calls lv_refr_now after the widget has been passed the new value. This will force LVGL to render and flush to the display without waiting for the refresh timer. That will make sure that the widget value changes are not jumpy.

Here is an example of what I am talking about…

This is custom rendered using the canvas widget in LVGL. Watch the tick marks and you can see how they disappear in a nice smooth animation type manner. That is how you want the meter to move, nice and smooth. to achieve that you need to have LVGL running on one core and only tasked with updating widget or custom drawing the widget and telling LVGL to refresh the display. The rest of the work needs to be done on the other core.