How to Create a Circular Gauge

Last modified by Microchip on 2025/06/04 05:32

Introduction

A circular gauge is a visual representation used to display data in a circular format, often resembling a traditional analog gauge or dial. This interface type is commonly used to represent values such as speed, temperature, pressure, or other metrics that can be intuitively understood in a circular layout.

Key features of a circular gauge Graphical User Interface (GUI) might include:

  • A needle or pointer that moves around the circular path to indicate the current value.
  • Animation effects to smoothly transition between values.

This user guide demonstrates how to use the Microchip Graphics Suite (MGS) vector rendering library to implement different types of needles or pointers and how to move them in a circular path.

MGS Example Project

Refer to the project in GitHub for the example.

MGS Simulator Output

  1. The application launches with a line-based needle gauge that moves in a circular path to indicate the gauge value from 0 to 140, and vice versa. Press the Change needle type button in Figure 1 to cycle through different needle types, like a triangle or an arc.
Figure 1: Circular Gauge Example

Back to Top

MGS Harmony Composer Design

Figure 2 shows the screen design in MGS Harmony Composer. The On Show, On Hide, and On Update event callbacks are enabled for this screen. These callbacks will be used to initialize and update the screen at runtime.

Composer Design

Figure 2: Composer Design

The design uses an image for the static sections of the screen, such as the gauge tick and background. Then, it uses the graphics library to draw the moving needles on top of the static section.

The Screen Tree on the left lists the widgets on the screen. For the circular gauge, the design uses the following widgets:

NameTypeFunction
imgGaugeImage WidgetA static image for the gauge with the ticks and values around it.
surfNeedleDraw Surface Widget

Used to draw the needle or pointer on top of the static gauge image.

The draw surface widget allows the application to draw at run-time any shape or graphic on the widget area using the library's vector drawing functions, like lines, arcs, circles, rectangles and polygons.

The Draw Notification event for this widget is set. This enables the library to call the application callback function for drawing on the widget area.

imgCenterImage WidgetAn image for the needle cap that's on top of the gauge.

Design Optimizations for Best Performance

The MGS Composer project and assets are configured for the best drawing performance. As such, the renderer settings have the default color to RGB565 and the scratch buffer sized is set so that it is large enough to fit a full frame buffer.

Renderer Properties

Figure 3: Project Settings

Since the design is single-layered and the needle is constantly being redrawn on top of the base gauge image, the library will also have to redraw the section of the base gauge image that overlaps with the needle.

To optimize the drawing of the base gauge image, it is set to match the project color mode (RGB565, uncompressed) and the render mode is set to direct in the Image Manager. This tells the library to copy the image to the frame buffer directly, without any color conversion or alpha blending.

Image Properties

Figure 4: Image Manager

This allows for very fast image drawing; however, the tradeoff is that the image size is larger, and transparent backgrounds will be ignored.

Back to Top

Application Code

The application code that manages the screen behavior and the callback functions for handling the screen and widget events are defined in the app_screen0.c file. 

Additional application library files provide the Application Programming Interfaces (APIs) for drawing different types of needles on the draw surface widget.

FileDescription
app_needle_line.c/hThese files contain helper functions for drawing lines using the MGS vector rendering routines, specifically as for circular gauges.
app_needle_poly3.c/hThese files contain helper functions for drawing three-sided polygons (triangles) using the MGS vector rendering routines, specifically as for circular gauges.
app_needle_arc.c/hThese files contain helper functions for drawing arcs using the MGS vector rendering routines, specifically as for circular gauges.

The structures for the different needles are declared in app_screen0.c.

/* For line needle */
static NEEDLE_LINE_t needleLine; //Outer line (blue glow)
static NEEDLE_LINE_t needleLine2; //inner line (gold)

/* For the polygon/triangle needle */
static NEEDLE_POLY3_t needlePoly3;

/* For arc needle */
static NEEDLE_ARC_t needleArc; //the arc object
static NEEDLE_LINE_t needleLineArc; //the line on the arc edge

At boot, these structures are initialized when the screen is first shown using the screen's OnShow() callback function. This callback function also sets the default needle type and starts the timer that's used to animate the needles.

/* Screen on show callback function. This gets called before the screen is rendered.
 * Initialize globals and widget states here. */

void Screen0_OnShow(void)

At run-time, these structures are updated to move and animate the needles on the gauge. Depending on the current type of needle being shown, the screen's OnUpdate() function calls the needle type-specific APIs to update the needles' angle and dimensions. The OnUpdate() function gets periodically called by the library and uses the timer's animation tick counter to set the frequency of the needle update.

void Screen0_OnUpdate(void)
{
...
/* Check if tick counter has changed */
   if (lastAnimTick != animTickCount)
    {
    ....
           /* Based on needle type, update the needle angle and size */
           switch(needleType)
            {
               /* Line needle */
               case NEEDLE_LINE:
                {
                   APP_UpdateNeedleLine(&needleLine, angleDeg, NEEDLE_OUT_RADIUS,
                                        NEEDLE_IN_RADIUS - (NEEDLE_IN_RADIUS * angleDegDelta)/MAX_ANGLE_DELTA_DEG);
                   APP_UpdateNeedleLine(&needleLine2, angleDeg, NEEDLE_OUT_RADIUS,
                                        NEEDLE_IN_RADIUS - (NEEDLE_IN_RADIUS * angleDegDelta)/MAX_ANGLE_DELTA_DEG);
                   break;
                }
               /* Triangle/Polygon needle */
               case NEEDLE_POLY:
                {
                   APP_UpdateNeedlePoly3(&needlePoly3, angleDeg, NEEDLE_OUT_RADIUS,
                                        NEEDLEPOLY_IN_RADIUS - (NEEDLEPOLY_IN_RADIUS * angleDegDelta)/MAX_ANGLE_DELTA_DEG);
                   break;
                }
               /* Arc needle */
               case NEEDLE_ARC:
                {
                   APP_UpdateNeedleArc(&needleArc,
                         START_ANGLE,
                         -angleDegDelta);
                   
                   APP_UpdateNeedleLine(&needleLineArc,
                           angleDeg,
                           NEEDLE_ARC_RADIUS + NEEDLE_ARC_THICKNESS/2,
                           NEEDLE_ARC_RADIUS - NEEDLE_ARC_THICKNESS/2);                     
                   break;
                }
               default:
                   break;
            }

        ....
       lastAnimTick = animTickCount;
    }
...
}

Drawing the Needles

The app_needle_*.c/h application libraries provide reusable functions for drawing different types of needles on the draw surface widget. These functions use the GFX library's vector rendering functions to draw the needles based on the specified length, color, thickness, and angle parameters. 

These libraries provide the following APIs:

APIDescription
APP_InitializeNeedle<type>

Initializes the needle object.

Call this in the screen on show function so that the needle structure is initialized before the needle is configured and drawn.

APP_UpdateNeedle<type>

Updates the needle's properties, such as length and angle.

Call this in the screen update callback function to configure the needle to be drawn at a specific angle, based on the value of the gauge.

APP_DrawNeedle<type>

Draws the needle based on its properties. 

Call this in the draw surface widget's OnDraw() callback function to draw the needle. 

Vector Stylization

The app_needle_* application libraries use the GFX library's vector rendering functions to draw the needles. The vector rendering functions provide stylization settings for drawing the vectors, such as the hardness, anti-aliasing and alpha. The values for these stylization settings are hardcoded in the application library and can be changed by modifying the application library header file.

For example, update the following values in app_needle_line.h.h to change the style of the line needles.

/* Hardcoded stylization of the lines */     
#define NEEDELINE_HARDNESS      0.30f
#define NEEDELINE_AA            LE_ANTIALIASING_NONE
#define NEEDELINE_CAPSTYLE      LE_CAPSTYLE_ROUND
#define NEEDLELINE_ALPHA        0xff

Back to Top