Today I'd like to talk about
MCU application design. Creating something graphical in an
embedded environment was not an easy task. Let's say we make a button.
To create a single button with code, we need more than we think. We need to
specify the size and position of the button, and we also have to implement a pressed
event if that button is touched by the user. Of course, you may not need these
graphical elements in an embedded system. It may be sufficient to connect
the MCU and the sensors, convert the analog data to digital,
and send it to another device. However, as the utilization
of MCUs has been maximized, things that were difficult to do
in the past have become possible. This makes it possible to depict vivid
graphics through a high-quality display. As far as I know, there are
several tools that allow you to create GUIs in an embedded environment. I've been using LVGL for a long time
and I love working with it. It works very well on my ESP32 and was able to
easily configure the screen I needed. LVGL's official UI Editor, SquareLine, makes it faster and easier to create
parts that are difficult to write in code. This enables screen composition of much
higher quality than writing UI in code. Today, we will try to configure GUI through
SquareLine and apply it to code together. The currently built system displays
GPS information as text on the screen. It's not fun because it's only shown as
text. We believe we can do better than this. But the reason we need this is because
we know what type of data we have, so we need to do this first. UI/UX designers are the ones who know
best how to effectively represent data that we can access on the screen.
You can create a much nicer layout with help from a designer, but I don't currently
have a designer, so I'll show you how I did it. The application I will create is Speedometer. If you google the speedometer app, you
will see some very nice and cool designs. Here, I can pick out some reference things and
sketch what I want to express based on them. Rather than displaying all
information on one screen, I decided to display all
information on two screens. The GPS Information page will display
the data obtained from GPS on the screen. The focus here is to display all
information from GPS and Compass. In the next screen, Speedometer, I have
configured a simple screen that shows speed and compass together.
It would be nice to have the gauge change according to the speed.
And it would be nice to have a heading degree and make a compass that always points north.
This referenced the iPhone's compass. This is the basic sketch I
will be working on today. Let's start working on SquareLine. You can download squareLine from
their official site. I'm currently using it on Mac. Thank you for supporting Mac.
I believe you're running SquareLine on your end. In the create menu, on the bottom right,
there is a menu of project settings where you can create a new project.
Choose a project folder and project name to work with.
The resolution I will be working with is 320x480. Color Depth is 16 bit.
LVGL version is 8.3.3 and I set the Theme to Dark. An empty project is created. The screen interface is very simple.
The canvas you are working on is in the center. You can zoom the canvas here. Let
me set it to bigger than this. On the left, you can see the hierarchical view. As widgets are added, you
will see them updated here. Below shows the available widgets. You can simply add it to your
canvas with mouse clicking. In Asset, you can add images and
fonts to be used in this project. In the inspector on the right, you
can modify and design everything on the currently selected widget.
We have to get used to being here. I'll show you how to add assets.
You can download it from the link below. I'm adding font and image files
to be used in this project. Three images and one font file are here. Images are used to indicate
the compass and speed gauge. Also, this project uses a
font called Open 24 Display. Unfortunately, it doesn't
support multiple selection, so I need to add them one by
one. I hope they fix it soon. Also, Font can be selected only after
changing the file type. That's not good too. You can see that all the images and the font
I will use have been added to the assets. For now, Let's make widgets. I'll put the speedometer on
the first page because it has a more simple design. It's not a
big deal. You can do your style. First thing I'll add a panel widget. Actually, this is not a mandatory thing. You can make
it without panels. Just I'd like to make a section using a panel. You will then have a more
organized hierarchy. This is my style to make UI. This name is Root panel and
resize it to fit the screen size. If you look at the corners of the
panel, you can see that they have
rounded corners. I remove them. I also change the background color to black. The base panel is complete.
Let's create the next panel. It'll have a title text. Move the newly created panel under the root panel. All widgets on this screen become
child widgets of the root panel. Let me name this panel Top Panel. Since we need to put a title,
I will add a Label widget. It also makes this label widget
a child widget of the top panel. After naming this label widget, set the text for this label.
Let's call it a speedometer. Go to the top panel.
Let's resize it. It's gonna be 80% of the width. Also, the alignment of this
panel should be Top middle. and the Y axis has negative
numbers to move up slightly. Looks good but not enough. It
should have a new style font. Let me show you how to apply the font you want. Go to Font Manager. Select font asset.
I added the Open 24 display font at the beginning of this project.
So it's selected automatically. And Let's set the font name.
We need to create a font for each size. So, it's easier to use if
you write the size after the font name. I set it to Display 16
because the font size is 16. Click the Create button. All done. you can see the font
files are added as your assets. Let's apply the font we just created. You can find Text Font under Style.
If you click the checkbox, it will be activated and you
can set the font you want. There is my font. Select it. You can see the font is applied to the label. But the font seems too small. Let's go back to the Font Manager
and create a new font size. Set name Display24. Set font size 24. Create. Go to the text label again. Inspector. set Text font Display24. Cool. This is what I wanted. This time, let's create a
panel that displays the speed. This panel name is SpeedPanel. Set the width to 100% and
the height to 140 pixels. Position it 100 pixels above the center.
It's negative because to go above. Remove the rounded corners as before and
change the background color to black. Let's add an image widget. In the Hierarchy View, make the Image
widget a child widget of the SpeedPanel. And name it SpeedBG. Go to the asset below, You can see the all available images.
Set the speedBG png file. This time I will add a Slider widget. This widget's parent will be SpeedBG.
So, make it a child widget of SpeedBG. Let's set the name, Speed Slider. It has also the same 100% width. The slider has a range for a value. I set the 0 to 200. I think
that's enough for the speed gauge. Also, set the initial value to 120. Now we need to set the styles. The slider has three styles,
Main, Indicator, and Knob. Let's start with the main style.
the background should have no color. so the opacity is 0 which
means completely transparent. The indicator style is also the same
as the main style. And you can set the background image of the indicator
here. Set the SpeedFG png file. Oops, nothing changes. Ok. Go back to the slider size. Let's set the 320 px instead of
100 percent for its width. Also, for the height, let's
set it to 140 pixels like the BG Image Widget. Now I can see the indicator image
but the knob should be removed. The background image should be transparent. Cool. It looks slick.
SquareLine supports a mode where you can try triggering
an event. Let's play this page. You can adjust the value of the
slider by dragging the mouse. Depending on the value, the part where
the image is displayed changes like this. Very nice. Let's create a label that displays the
minimum and maximum values of speed. Create a label and set a name. And it should be 0. The alignment should be at the bottom left.
oh. Do you know what the problem is here? The label widget's parent is not the
SpeedPanel, so it's aligned in a weird position. Let's move it under speedPanel.
Now the its position is good. The speedBG must be in the
back most. Drag it to up. Good. Let me move it y-axis a little bit. Also, need to set it to the font.
Oops. It should be Display 24. We have to make the maximum label too. In this
case, we can duplicate widgets very simply. Click this duplicate icon to easily
create one more identical widget. After that, you need to name it again. Note that all widgets must have unique
names. The same names are not allowed. After changing the text to 200,
change it to the Top Right alignment. I will change the y value
to move it further upwards. This is enough. This time we will create a panel for the compass.
I know you can make the panel. It's the same.
Change the name, width, and height. let's make the height 60%. The alignment of this panel
should be the bottom middle. I'm gonna down this panel some
because the top overlaps a bit. It has a rounded corner so set it to 0.
Also, the background should be black. Also, let's remove the border.
Set the border width 0. Now it's an empty black panel. Add an image widget here. I will rotate this image
to make a rotating compass. Set this widget name Compass Img. We need to set the asset of this widget.
Set the compass png file. Finally, we can see the compass image
on this project. Happy with this. Above this compass, I will add a
label indicating the heading degree. It should be under the Compass Panel. Alright. Set the name to compass label. For dummy text, Let's say 360. Also, it should have the font. Okay. All looks good. Do you know how to rotate the image?
I'll show you how to do it. Go to the compass image.
there is a rotation. You can rotate the image with this value.
One interesting is that the range of the rotation is 0 to 3600. It means It
can finer rotations than 360 degrees. Next is the speed text panel. We gonna show this panel the
current speed in large text. The width is 100%, the Height is 80 pixels,
and the y-axis is -40 from the center. Make the background transparent, not black. Also, we don't need a border, so
set the border width to 0. Let's add a speed unit text label.
The unit of speed will be Mile per hour. The name of this widget is Speed Unit Label.
The text should be mph. The alignment of this widget
is set to the bottom right. Also, don't forget to apply the font. We need to make two more label widgets.
One is for the background text, the other one is for the foreground text. I'm gonna copy this widget and use it. This will be the background text. it won't change the value but just shows three
digits of 0 with gray color. We need to move it to the
left because it's overlapped. This requires a large font, so I will make
a large font through the font manager again. It's 90. It's a really big one. Cool. It's created. Let's apply
this new one to the label. Wow it's really big. The top is cut a little, so
I'm going to move it down. Now it's perfect. Let me set the color like a placeholder. That looks good.
Make a new widget by duplicating this widget. Set this name to Speed Label.
And set the color to cyan color. Cool. Let me change the dummy text to 120. How about this? I like this design.
It's very intuitive for the speed and it looks really speedometer application. The font for the heading degree in the compass seems to be too small. Let me
make another font for this. I think a size 40 would be fine. Go back to the inspector. and
set the font to Display 40. Much better than before. Also, I will change the text color
to cyan color to make it stand out. That's it. This is what I wanted for the compass. This time, let's emphasize the title part. Go to the title of the top panel. Let's also change the text color to cyan. Go to the top panel.
Let's add a border color in the Top Panel. Set it to gray, and then
set the border width to 4. Finally, add a cyan shadow
effect to fit the overall theme. You can specify the size of the shadow with the
shadow width and shadow spread, and the angle of the shadow with the value of OX OY.
I made it oblique. Finally, the first page is complete. How is it? I think it would take a very
long time if I wrote it in code. Also, the styling part is a tricky part to write
in code. You have to browse the document to create the style you want. It takes a lot of time
and is not guaranteed to make a good style. This time I will copy the entire
screen. Same as the Widget duplication, press the duplicate icon. Here you are. You can see that all copied widgets are automatically numbered to
avoid duplicate widget names. The second page is the GPS Information page,
which focuses on showing everything at a glance. I'll remove all other widgets except for
the top panel part among the copied widgets. This title should be GPS Information. I changed my mind. Sorry.
The white color of the title text on the page looks better. On both pages, I'll
change the color of the title text to white. On the first page, there is a part that I missed.
That's the loading icon. It may take some time before the GPS module
receives signals from some satellites. It looks like a loading icon is needed to confirm that
a signal has been received from the satellite. I'll turn this on and off in the code later. For now, let's place the Spinner widget. Set the name of the spinner as usual.
This widget needs to be aligned to the Top right. Set the size to 20 px x 20 px. As you can see here, it's too stuck on the top right corner.
Let's move it to 12 pixels each. Spinner has two styles. The main style is for the background side and
the indicator style is for the foreground. First, change the color of
the background to dark gray. Also, change the arc width
to 4 to make it thinner. Now it's the indicator's turn. I will set the color of the
rotating Arc to cyan color. This also sets the width 4 which
is the same as the main style. Even a spinner to show the loading was completed. From now on, we will complete
the GPS Information page. What I'm going to do now is very
similar to what I've already shown. So, I will only show the screen
I'm working on without my words. I'll make sure you don't have any
trouble following them one by one. If you don't need this part, please
skip to the code export part. or, set the double speed to
watch it. Save your time. The two screens are now done.
I hope it was an exercise in creating a UI. After making a few UIs, I think you can quickly
adapt to the square line studio. I believe so. The last thing I will do is add a button. This allows you to move the screen with a button. The button should be on the title
text and it will have a only frame. This button name is Top Button 1. and set the width 100%.
and then remove the background color. Let's add a button event. When a button event occurs,
it moves to the next screen. Select Change Screen from the Action menu.
And then, click the add button. Here you can set the action for the Change Screen. In Fade mode, you can choose animation
effects. I selected MOVE LEFT so that the current screen is shifted to the
left and the next screen appears. The target screen is the second
screen, so select Screen 2. I set the animation speed to 100ms and no delay. Ok. Let's try this works. When a button event occurs, it
moves to the next page. Cool. Now let's add a button to the
second page so we can come back. Duplicate the button widget. And drag and drop to the top
panel of the second page. The target screen is Screen
1 and the fade mode should set the move right. That's all. What an easy task. If you press the button at the
top, it goes to the next page. Also, it returns to the first
page through the event again. Congratulations! We made it. So far, we have created an embedded
UI using Square Line Studio. It doesn't end here, but from now on, we
have to use this design in our source code. Let's export UI files. You can easily export to C-style
files through the top menu. Let's create a folder and select it. That's it. They're exported and we can use it.
Here are the UI files exported from
Square Line Studio. As you can see, all font and image files are in c file format. I'm going to copy all of these files
into my previous project folder. And then open Arduino IDE. All files in the project folder
are automatically loaded. You can check all the files in the
project folder with explorer. The shortcut key is Command + Shift + E.
For Windows, I guess it's Ctrl + Shift + E. Let's download the LVGL library. You can
get it quickly through Library Manager. To use LVGL library for Arduino environment,
you should have this task first. Go to the LVGL folder. There you'll find the lv_conf_template header file. Copy this to
the source folder and rename it to lv_conf. And then open it with any text editor you have. You only need to enable two things.
This is for using LVGL. Please change it to 1. The following is the time tick to update
the screen in the Arduino environment. After saving, return to the source code again. Let's add them one by one.
We use LVGL, so we need to include its header. The ui header file is a file obtained
from Square Line Studio. Add it together. This part is necessary for LVGL
screen composition. Depending on your hardware set, you may need to
change this part. Please note only. This is the part that initializes LVGL.
Set up the buffer and set the input device driver. It calls a function called ui_init.
Through this, the UI we worked on in Square Line Studio is drawn
on the screen. How easy is it? For testing purposes, all GPS-related
codes will be commented out. Need to call the timer
handler so that LVGL can run. With this, we'll see if the
UI we've been working with is displayed on the screen. I can update the slider by touch. Ok, but
it should be updated according to the speed, not by user touch. I will block
this part in the code. Touch the upper part to move to the next page. It works the same as what we did. It looks like the UI reset part is needed.
Since the dummy texts we used in our work are still there, it would be good to clean up the UI
as soon as this device starts up. Also, I will prevent the slider
widget from being touched. This time the touch event
on the slider doesn't work. Also, all texts on the GPS Information
page are displayed as zero. Now all that's left is to get
the GPS and compass information and display it through the UI Widget we worked on. The widgets we work with through Square
Line Studio can be accessed via the widget name we set. When exported, a prefix of
ui underscore is automatically added. You can update the screen
using this LVGL object name. It's to output data to the
screen according to each widget. If the number of satellites found is
non-zero, the Spinner should be invisible. I made a simple function to show the
Spinner again when it becomes 0 again. The heading degree obtained from
the compass is expressed as text, and that amount is also applied to the
compass image rotation. As mentioned earlier, the rotation range is from 0 to
3600, so I multiply it by 10. One last thing is, setting the
animation speed again. Do you remember I set it to 100 ms?
I'd like to set it to 50 ms instead. I think this is all. Let me
build and upload it to my device. Do you like it? Because GPS information
cannot be received indoors, the screen is not updated. Only data obtained
from the compass is displayed. In this project, UI was created using
SquareLine Studio, and the data obtained from the sensor connected to the MCU is
updated through the widgets on the screen. Along with the MCU, the display
is also developing a lot. What was impossible just a few years ago
is now possible. That's amazing. In my opinion, in the near future,
the MCU application does not have a display at all, so it will be used
in connection with a smartphone, or it has a very colorful application
design to catch people's attention. If you are preparing for the future, you may need
this kind of work. Anyway, that's it for today. Thank you for watching. See
you on the next project.