patterncMinor
Optimizing a loop in C for a microcontroller
Viewed 0 times
microcontrollerloopoptimizingfor
Problem
I am trying to draw a Checkerboard pattern on a LCD using a GUI library called emWin. I have actually managed to draw it using the following code. But having this many loops in the program body for a single task, that too in the internal flash of the microcontroller is not a good idea.
For those who have not worked with emWin, I will try and explain a few things before we go for the actual logic.
The code below works fine but I want to make it smarter.
```
GUI_RECT Rect = {0, 0, 79, 79};
GUI_RECT Rect2 = {80, 0, 159, 79};
GUI_RECT Rect3 = {160, 0, 239, 79};
GUI_RECT Rect4 = {240, 0, 319, 79};
GUI_RECT Rect5 = {320, 0, 399, 79};
GUI_RECT Rect6 = {400, 0, 479, 79};
GUI_RECT Rect7 = {480, 0, 559, 79};
GUI_RECT Rect8 = {560, 0, 639, 79};
GUI_RECT Rect9 = {640, 0, 719, 79};
GUI_RECT Rect10 = {720, 0, 799, 79};
WM_SelectWindow(Win_DM_Main);
GUI_SetBkColor(GUI_BLACK);
GUI_Clear();
for(i = 0; i < 6; i++)
{
if(i%2 == 0)
GUI_SetColor(GUI_WHITE);
else
GUI_SetColor(DM_CHECKERBOARD_COLOR);
GUI_FillRectEx(&Rect);
Rect.y0 += 80;
Rect.y1 += 80;
}
for(i = 0; i < 6; i++)
{
if(i%2 == 0)
GUI_Set
For those who have not worked with emWin, I will try and explain a few things before we go for the actual logic.
GUI_RECTis a structure which id define source files of emWin and I am blind to it.
Rect,Rect2,Rect3.. and so on untilRect10are objects.
- Elements of the
Rectarray are{x0,y0,x1,y1}, wherex0,y0are starting locations of the rectangle in the X-Y plane and x1, y1 are end locations of the Rectangle in the X-Y plane.
Rect={0,0,79,79} is a rectangle that starts at the top left of the LCD and is up to (79,79), so it's basically a square.- The function
GUI_setBkColor(int color);sets the color of the background.
- The function
GUI_setColor(int color);sets the color of the foreground.
GUI_WHITEandDM_CHECKERBOARD_COLORare two color values,#defineed
GUI_FillRectEx(&Rect);will draw the rectangle.
The code below works fine but I want to make it smarter.
```
GUI_RECT Rect = {0, 0, 79, 79};
GUI_RECT Rect2 = {80, 0, 159, 79};
GUI_RECT Rect3 = {160, 0, 239, 79};
GUI_RECT Rect4 = {240, 0, 319, 79};
GUI_RECT Rect5 = {320, 0, 399, 79};
GUI_RECT Rect6 = {400, 0, 479, 79};
GUI_RECT Rect7 = {480, 0, 559, 79};
GUI_RECT Rect8 = {560, 0, 639, 79};
GUI_RECT Rect9 = {640, 0, 719, 79};
GUI_RECT Rect10 = {720, 0, 799, 79};
WM_SelectWindow(Win_DM_Main);
GUI_SetBkColor(GUI_BLACK);
GUI_Clear();
for(i = 0; i < 6; i++)
{
if(i%2 == 0)
GUI_SetColor(GUI_WHITE);
else
GUI_SetColor(DM_CHECKERBOARD_COLOR);
GUI_FillRectEx(&Rect);
Rect.y0 += 80;
Rect.y1 += 80;
}
for(i = 0; i < 6; i++)
{
if(i%2 == 0)
GUI_Set
Solution
It's unlikely that your app's performance concerns are due to the excessive looping. They are all small loops and should rip through pretty quickly, even on an embedded controller. I suspect your expensive call is the GUI_FillRectEx() calls.
That said, there are techniques to clean up your code and make it more maintainable.
Notice how you have the same loop structure + code for each of those blocks?
While the cost isn't necessarily great in this case, you are repeating it for each of your rectangles.
-
Look for the actions that don't need to occur.
-
In this case, do you really need to paint both the white and black squares? Could you "cheat" by using a black canvas and only paint the white squares? That would cut your FillRectEx() calls in half.
-
Do you really need to declare 10 Rect's and increment coordinates on each loop? How about declaring a fixed array ahead of time and pre-populate / hard code all the coordinates?
That said, there are techniques to clean up your code and make it more maintainable.
- Look for the duplicated logic.
Notice how you have the same loop structure + code for each of those blocks?
for(i = 0; i < 6; i++)
{
if(i%2 == 0)
GUI_SetColor(DM_CHECKERBOARD_COLOR);
else
GUI_SetColor(GUI_WHITE);While the cost isn't necessarily great in this case, you are repeating it for each of your rectangles.
-
Look for the actions that don't need to occur.
-
In this case, do you really need to paint both the white and black squares? Could you "cheat" by using a black canvas and only paint the white squares? That would cut your FillRectEx() calls in half.
-
Do you really need to declare 10 Rect's and increment coordinates on each loop? How about declaring a fixed array ahead of time and pre-populate / hard code all the coordinates?
Code Snippets
for(i = 0; i < 6; i++)
{
if(i%2 == 0)
GUI_SetColor(DM_CHECKERBOARD_COLOR);
else
GUI_SetColor(GUI_WHITE);Context
StackExchange Code Review Q#27889, answer score: 4
Revisions (0)
No revisions yet.