Draw "PID" curve with lv chart series


I would like to draw a simple curve (such as PID curve) with LVGL chart widget.
My project is about Control Systems and PID controll. I need create a simple GUI to control any process, but I also need show to user the curve of PV and other variables.

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


What LVGL version are you using?

v7.1.0 in C language

What do you want to achieve?

I want draw a simple curve graph

Example of what I want to do


1 Like

Hi, So then what’s the problem?
You can add a different series to the same chart.

@Ali_Rostami It is not about “add different series”, it is about how to draw a “curve graph”. curve, not just straights connecting dots. LVGL don’t support float numbers, so, I can’t create a “curve effect”, just a “straight effect”:

I would like to know how can I create a graph with this “curve effect”.
Did you understand my question @Ali_Rostami?
Sorry about my English.

1 Like

Yeah, no problem.
OK, in fact, you can get to this curve by having more points on the chart. In my project I have to display something like this:
And I have no problem.
For setting float numbers, you can multiply your data to e.g 100 -based on your precision- and then add them to the chart.
For example, let’s say your numbers varies from 0.00 to 1.20 so if you multiply them to 100 you have the range of 0 to 120:
lv_chart_set_range(chart, 0, 120);


I think it is a idea, but it isn’t a good idea. It consumed a great of sources and doesn’t looked good.

AFAIK it doesn’t consume more than working with floating-point. otherwise, your processor is equipped with FPU, which also consumes power.

Actually, it’s how LVGL works with angles internally. As far as I know, we don’t use a single floating-point routine.

The gauge, linemeter, etc. all use fixed-point math like this to display the needle and lines.

Hi @Ali_Rostami. Thanks for your reply.
I understand fixed-point math, makes sense, but I dont understand how create this “curve” effect. Just add more points looks not enough. Can you share your example with me?

1 Like

Hi yes, I will share ASAPIC.

1 Like

@Lucas.Liao Do you have another idea/method to create this “curve effect”?

It seems that curve graph is very difficult to achieve, which is considered floating-point is necessary.

1 Like

The only difference between fixed and floating point math is that the latter allows any number of decimals, while the former has a fixed number. Otherwise, they behave exactly the same. In many cases, you wouldn’t notice a difference.

The curve effect shouldn’t be related to the type of math in use, as it controls how the lines between points are rendered, not the values of the points themselves.

How can I generate the “curve effect”? I just need one single example guys, please.

Sorry, I almost forgot about it. Here it is:

        chart = lv_chart_create(lv_scr_act(), NULL);
		lv_obj_set_size(chart, 704, 190);

		lv_obj_set_style_local_bg_opa(chart, LV_CHART_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
		lv_obj_set_style_local_border_opa(chart, LV_CHART_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
		lv_obj_set_style_local_pad_all(chart, LV_CHART_PART_BG, LV_STATE_DEFAULT, 0);
		lv_obj_set_style_local_bg_opa(chart, LV_CHART_PART_SERIES_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
		lv_obj_set_style_local_line_width(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, 2);
		lv_obj_set_style_local_size(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, 0);/*radius of points*/

		lv_obj_align(chart, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 325);

		lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_CIRCULAR);

		lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
		lv_obj_set_style_local_bg_opa(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, LV_OPA_TRANSP);

		lv_chart_set_point_count(chart, 225);
		lv_chart_set_div_line_count(chart, 0, 0);
		lv_chart_set_range(chart, 0, 255);

		/*Add data series*/
		series = lv_chart_add_series(chart, LV_COLOR_CYAN);

		lv_chart_init_points(chart, series, 0);

Hope it can help.

1 Like

@Ali_Rostami Thank you for your help, but what about update chart? The “magic” happens when chart is refreshed.

Not sure what you mean.
But In my case, whenever I receive new data from the sensor I call a function that has this line to draw next Y, based on the new data.
lv_chart_set_next(chart, series, y);
I do nothing more man. The config of the chart is as I posted and this is the way I add new data every time. Hope this can helpđź‘Ť
If it didn’t help, put your code here -the config and the part you add new data to the chart- to see if we can do anything about it.

1 Like

Hi @embeddedt,
Thanks for answering. I think https://github.com/lvgl/lvgl/blob/master/src/lv_draw/lv_draw_mask.c#L612 is the mystrey about skew line. I researched it carefully, but i have no idea about the parameters, such as wcorr, m = (xsf + xef) >> 1… If we draw a curve, we would had to penetrate the mystrey and revise it.

1 Like

I think the draw functions in the canvas are a better option. You can probably modify the line drawing code from the chart using draw arc. Might even be best to make that the default drawing method for the chart widget or an additional option. If the default angle is 0 it would draw straight lines and if the “smoothing” option is activated it could calculate the right start and end angle to draw a curve.

  • lv_canvas_draw_arc(canvas, x, y, radius, start_angle, end_angle, &draw_dsc)

If you upload your code I can give it a try later. I am working right now so I don’t have time to recreate your whole setup from scratch.

1 Like

Guys @excitedbox, @Lucas.Liao, @Ali_Rostami sorry for the late reply. I can’t retry your suggestions right now but I’ll try as soon as possible and I’ll give you feedback. Maybe I can write a tutorial for other people who want do the same thing. Thank you very much guys.

1 Like

Just like the lvgl_chart_example https://github.com/lvgl/lv_examples/blob/master/src/lv_ex_widgets/lv_ex_chart/lv_ex_chart_1.c#L4 It is difficult to draw a curve with serveral points. Do you think canvas can do like this:

1 Like