2668 views|7 replies

280

Posts

7

Resources
The OP
 

[RVB2601 Creative Application Development] Environmental Monitoring Terminal 03-Using LVGL to Design the Interface [Copy link]

 

This article introduces how to design an interface on the OLED display screen of the RVB2601 development board based on the LVGL library.

The RVB2601 development board has a built-in monochrome OLED display with a resolution of 128*64, and the open source LVGL GUI library has been ported based on this platform. I have never used the LVGL GUI library before, so I just wanted to give it a try, so I searched for tutorials online. I happened to find a user manual translated by someone else, which is attached to this article. Students who need it can download it.

First, design a draft of the interface. As shown in the figure below, I plan to display 5 lines of information on the screen. The first line, the title, can be displayed directly using labels. The second line, the temperature, the left field does not need to be updated, and the right field needs to be refreshed regularly, and all are displayed using labels. The third and fourth lines are humidity and noise levels, respectively, and the same method is used to display temperature. The fifth line plans to make an indicator bar to dynamically indicate the real-time amplitude of the noise, so that it is more intuitive to view.

Figure 1. Interface sketch

I encountered various problems during the actual design. The first was how to display Chinese characters. After searching, I learned that I had to make and add built-in fonts myself. I looked at several tutorials and found that they were very complicated. I was lazy and decided to skip the Chinese display and use English instead.

The next problem is that the default English font is "LV_FONT_MONTSERRAT_14", which is relatively large. If it is displayed in 5 lines, it looks too crowded. By changing the configuration item, the font "LV_FONT_MONTSERRAT_12" is relatively better. I also tried to change it to a smaller font, but it was a bit horrible and I couldn't even distinguish it. It looked a bit like the Martian text in the blockbuster movies. The specific modification method is as shown in the figure below.

Figure 2: Modify font

Next, we will actually program to display text. When we were doing the title display, we saw that LVGL supports scrolling display. In order to reflect our learning results, we changed the original two-word title into a sentence and let it scroll at the top, which is more fun. For the specific setting method, please refer to the code below.

When setting the temperature display, it is necessary to display floating point numbers. I wrote the code in the conventional way and found that it could not be displayed normally. Then I checked the information and found that it was set to not support floating point mode by default in order to improve efficiency. I originally wanted to check the manual to change it to support floating point mode, but later I saw someone used a better method to solve it. That is, format the floating point number into a string first, and then display it as a string. I followed this method and successfully solved the problem. For specific methods, refer to the following code.

The last thing to be implemented is the noise indicator bar. After repeatedly consulting the manual, I finally decided to use the progress bar "LV_BAR" control design. After directly following the simple routine in the manual, I found that both ends were rounded, which was not the type I liked. Then I searched a lot, and the Internet is a good thing. I found a solution again. Friends who are interested can refer to the following post.

https://www.csdn.net/tags/MtTaEg4sMjI1OTA0LWJsb2cO0O0O.html

After repeated modifications and debugging, I finally built the interface framework, and the display effect is as shown below.

Figure 3: Interface framework

The entire framework initialization code is as follows.

lv_obj_t *pGui_label_temp;
lv_obj_t *pGui_label_humi;
lv_obj_t *pGui_label_noise;
lv_obj_t *pGui_bar_noise;

static void gui_label_create(void)
{
	char cdata[10] = { 0 };
	
	lv_obj_t *p_label_title  = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(p_label_title, LV_LABEL_LONG_SROLL_CIRC);     /*滚动显示*/
    lv_obj_set_width(p_label_title, 160);
    lv_label_set_text(p_label_title, "Hello EEWOLRD,This is a Environment Monitor based on RVB2601.");
    lv_obj_align(p_label_title, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);   
	
	lv_obj_t *p_label_temp = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_align(p_label_temp, LV_LABEL_ALIGN_LEFT);
    lv_obj_set_pos(p_label_temp, 0, 12);
    lv_obj_set_size(p_label_temp, 128, 64);
    lv_label_set_text(p_label_temp, "Temperature:");
		
	lv_obj_t *p_label_humi = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_align(p_label_humi, LV_LABEL_ALIGN_LEFT);
    lv_obj_set_pos(p_label_humi, 0, 24);
    lv_obj_set_size(p_label_humi, 128, 64);
    lv_label_set_text(p_label_humi, "Humidity:");
		
	lv_obj_t *p_label_noise = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_align(p_label_noise, LV_LABEL_ALIGN_LEFT);
    lv_obj_set_pos(p_label_noise, 0, 36);
    lv_obj_set_size(p_label_noise, 128, 64);
    lv_label_set_text(p_label_noise, "Noise level:");

	pGui_bar_noise = lv_bar_create(lv_scr_act(), NULL);
	lv_obj_set_size(pGui_bar_noise, 120, 10);
	lv_obj_align(pGui_bar_noise, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -1);
	lv_bar_set_anim_time(pGui_bar_noise, 200);
	lv_bar_set_range(pGui_bar_noise, 1, 100);
	lv_bar_set_type(pGui_bar_noise, LV_BAR_TYPE_NORMAL);
	lv_bar_set_value(pGui_bar_noise, 50, LV_ANIM_OFF);
	lv_obj_set_style_local_radius(pGui_bar_noise, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, 0); /*Add a local style*/
	lv_obj_set_style_local_bg_color(pGui_bar_noise, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLACK);
	
	static lv_style_t style;
	lv_style_init(&style);
	lv_style_set_radius(&style, LV_STATE_DEFAULT, 0);//这里的参数0意思是进度条的指示器样式弧度为零,也就是直角。
	lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_WHITE);//进度条背景颜色
	lv_style_set_border_width(&style, LV_STATE_DEFAULT, 1); //进度条背景线条宽度
	lv_style_set_border_color(&style, LV_STATE_DEFAULT, LV_COLOR_BLACK);//颜色

	lv_style_set_pad_top(&style, LV_STATE_DEFAULT, 2);//指示器到背景四周的距离
	lv_style_set_pad_bottom(&style, LV_STATE_DEFAULT, 2);
	lv_style_set_pad_left(&style, LV_STATE_DEFAULT, 2);
	lv_style_set_pad_right(&style, LV_STATE_DEFAULT, 2);

	lv_obj_add_style(pGui_bar_noise, LV_BAR_TYPE_NORMAL, &style);//样式加到进度条中
	//https://www.csdn.net/tags/MtTaEg4sMjI1OTA0LWJsb2cO0O0O.html

	pGui_label_temp = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_align(pGui_label_temp, LV_LABEL_ALIGN_RIGHT);
    lv_obj_set_pos(pGui_label_temp, 90, 12);
    lv_obj_set_size(pGui_label_temp, 128, 64);
	sprintf((char*)cdata, "%.1fC", 25.68);//格式化输出 浮点数转成字符串输出
    lv_label_set_text_fmt(pGui_label_temp,"%s", (const char*)cdata);
	
	pGui_label_humi = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_align(pGui_label_humi, LV_LABEL_ALIGN_RIGHT);
    lv_obj_set_pos(pGui_label_humi, 90, 24);
    lv_obj_set_size(pGui_label_humi, 128, 64);
	sprintf((char*)cdata, "%.1f%%", 55.8);//格式化输出 浮点数转成字符串输出
    lv_label_set_text_fmt(pGui_label_humi,"%s", (const char*)cdata);
	
	pGui_label_noise = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_align(pGui_label_noise, LV_LABEL_ALIGN_RIGHT);
    lv_obj_set_pos(pGui_label_noise, 90, 36);
    lv_obj_set_size(pGui_label_noise, 128, 64);
    lv_label_set_text_fmt(pGui_label_noise, "%ddB", 55);
	
}

static void gui_lvgl_task(void *arg)
{
    lv_init();
    /*Initialize for LittlevGL*/
    oled_init();

    /*Select display 1*/
    // demo_create();
    gui_label_create();

    while (1) {
        /* Periodically call the lv_task handler.
         * It could be done in a timer interrupt or an OS task too.*/
        lv_task_handler();

        aos_msleep(5);
        lv_tick_inc(1);
    }
}

Since I haven't adjusted the detection procedures for each parameter yet, I have to create a task first, create simulated data, and make the interface move first to show the effect. The code is as follows.

struct Result_S
{                     
    float temp; 
	float humi; 
	int noise;
}res_data;                  

static void res_update_task(void *arg)
{
	int num_temp = 200;
	char cdata[10] = { 0 };
	
	while(1)
	{
		num_temp++;
		if(num_temp>1000)
		{
			num_temp = 200;
		}
		
		res_data.temp = num_temp / 20.0;
		res_data.humi = num_temp / 10.0;
		res_data.noise = num_temp % 99;
			
		sprintf((char*)cdata, "%.1fC", res_data.temp);//格式化输出 浮点数转成字符串输出
		lv_label_set_text_fmt(pGui_label_temp,"%s", (const char*)cdata);
		
		sprintf((char*)cdata, "%.1f%%", res_data.humi);//格式化输出 浮点数转成字符串输出
		lv_label_set_text_fmt(pGui_label_humi,"%s", (const char*)cdata);
		
		lv_label_set_text_fmt(pGui_label_noise, "%ddB", res_data.noise);
		
		lv_bar_set_value(pGui_bar_noise, res_data.noise+1, LV_ANIM_OFF);
		
		aos_msleep(500);
	}
}

The dynamic effect of the interface is as follows. When the detection parameters are adjusted in the future, the results will be assigned to the corresponding variables to complete the formal interface display.

Figure 4: Dynamic display effect

At this point, the interface display design of the environmental monitoring terminal is completed. Through this practice, we have a basic understanding of the process of using LVGL to design UI, which adds a new idea for the subsequent UI design.

LVGL Documentation.zip (5.34 MB, downloads: 12)

Latest reply

I ported U8g2 and felt that it still took up a lot of resources, especially the font library, so I am considering switching back to my own font library later.   Details Published on 2022-4-13 20:19
 
 

5220

Posts

239

Resources
2
 

When I see the refreshed diagonal pattern, I always feel it is a bug.

Add and join groups EEWorld service account EEWorld subscription account Automotive development circle

Comments

Most monochrome OLED screens have this problem. I can't find any information about this screen. Otherwise, you can study the refresh rate.  Details Published on 2022-4-11 13:56
 
 
 

280

Posts

7

Resources
3
 
nmg posted on 2022-4-11 10:33 When I see the refreshed diagonal line, I always feel it is a bug

Most monochrome OLED screens have this problem. I can't find any information about this screen. Otherwise, you can study the refresh rate.

Comments

The screen data board factory should be able to get it  Details Published on 2022-4-12 16:24
 
 
 

7452

Posts

2

Resources
4
 
sipower posted on 2022-4-11 13:56 Most monochrome OLED screens have this problem. I didn’t find any information about this screen, otherwise I could study the refresh rate

The screen data board factory should be able to get it

Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 
 

6841

Posts

11

Resources
5
 
I originally wanted to use LVGL for display, but once I added wifi, the compilation would show insufficient memory and failed to compile. I wonder if you have tried this?

Comments

I haven't tried this yet. If it doesn't work, I'll consider making my own UI program.  Details Published on 2022-4-13 19:55
 
 
 

280

Posts

7

Resources
6
 
lugl4313820 posted on 2022-4-13 19:45 I originally wanted to use LVGL for display, but once wifi was added, the compilation would show insufficient memory and the compilation would fail. I wonder if you have tried this...

I haven't tried this yet. If it doesn't work, I'll consider making my own UI program.

Comments

I ported U8g2 and felt that it still took up a lot of resources, especially the font library, so I am considering switching back to my own font library later.  Details Published on 2022-4-13 20:19
 
 
 

6841

Posts

11

Resources
7
 
sipower posted on 2022-4-13 19:55 I haven't tried this yet. If it doesn't work, consider making your own UI program

I ported U8g2 and felt that it still took up a lot of resources, especially the font library, so I am considering switching back to my own font library later.

Comments

In order to save resources, you can just make a picture, put the entry, title, unit, etc. on it, and then make a font library of 10 Arabic numerals.  Details Published on 2022-4-13 20:22
 
 
 

280

Posts

7

Resources
8
 
lugl4313820 posted on 2022-4-13 20:19 I ported U8g2 and it still takes up a lot of resources, especially the font library, so I'm considering switching back to my own font library later.

In order to save resources, you can just make a picture, put the entry, title, unit, etc. on it, and then make a font library of 10 Arabic numerals.

 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list