HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Optimizing a loop in C for a microcontroller

Submitted by: @import:stackexchange-codereview··
0
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.

  • GUI_RECT is a structure which id define source files of emWin and I am blind to it.



  • Rect, Rect2, Rect3.. and so on until Rect10 are objects.



  • Elements of the Rect array are {x0,y0,x1,y1}, where x0, y0 are 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_WHITE and DM_CHECKERBOARD_COLOR are 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.

  • 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.