Introduction: Arduino Analogue 'ring' Meter on Colour TFT Display

Yet another Arduino project for the display of sensor readings etc.

The example sketch included in the instructable includes the meter drawing function to use in your own projects, the function is not in a library so could be adapted for use with other graphics libraries. The meter drawing function has been "parameterised" so the meter size, position, range, units and colour scheme can be easily configured to suit your own needs.

Part of the inspiration for the development of the graphic was to have a similar style to the forthcoming Adafruit IO "Internet of Things" website.

The display is a 2.2" 320 x 240 pixel TFT colour display with the ILI9341 driver chip, this is driven by an Arduino UNO.

Step 1: The Meter Graphics

The value displayed is shown as a bar graph that can be segmented or continuous. Larger values are shown as more segments being coloured in, thus the display gives an instant visual indication of a reading at a glance without having to read the numbers. The numerical value is shown in the center of the ring, a bit like the Google Nest display.

The colour of the ring segments can be set to change as the value increases, so this means a display showing temperatures can be set change from blue to red as the temperature increases. Another display for say a battery level could change from red for a low value, through yellow to green for a high value.

The meter position and size can be set as desired to make a meter arrangement that suits your taste. The sizes are set independently so more important information can be shown with a bigger graphic, or the display could cycle though several meters.

The unlit segments are dark grey (these segments look brighter in the images as I had to adjust the web cam settings to try to capture the display colours.)

The displays are best for values that change slowly with time such as temperature and humidity etc.

Step 2: Hardware Configuration

The hardware setup is common to some of my other Instructables, it consists of the UNO, the 2.2" TFT display based on the ILI9341 driver chip and a set of libraries that are enhanced versions of the Adafruit GFX and ILI9341 libraries.

The libraries attached have been enhanced to give a much faster performance on an UNO using direct port access, other boards could be used by commenting out a #define and changing the the SPI pins.

The UNO is connected to the ILI9241 2.2" TFT display like this:

    • UNO +5V to display pin 1 (VCC)
    • UNO +5V through a 56 Ohm resistor to display pin 8 (LED)
    • UNO 0V (GND) to display pin 2 (GND)
    • UNO digital pin 7 through a 1K2 resistor to display pin 4 (RESET), add a 1K8 resistor from display pin 4 to GND
    • UNO digital pin 9 through a 1K2 resistor to display pin 5 (DC/RS), add a 1K8 resistor from display pin 5 to GND
    • UNO digital pin 10 through a 1K2 resistor to display pin 3 (CS), add a 1K8 resistor from display pin 3 to GND
    • UNO digital pin 11 through a 1K2 resistor to display pin 6 (SDI/MOSI), add a 1K8 resistor from display pin 6 to GND
    • UNO digital pin 13 through a 1K2 resistor to display pin 7 (SCK), add a 1K8 resistor from display pin 7 to GND

    It is important to include the 1K8 resistors to GND with this 2.2" display as otherwise it will not work! The 1K2 and 1K8 resistors are a "potential divider", acting as a logic level shifter so that the logic level at the display is reduced from 5V to around 3V. Pin 9 of the display does not need to be connected up.

    I have included a couple of short (!) videos (rather poor quality...) showing the graphics speed using an UNO and hardware SPI. (These have had the long delay() intervals between each test screen removed from the sketch!)

    One video is the UTFT Demo running on a Mega board with a 16 bit parallel interface to the display. It is faster mostly because the 10,000 pixel plot test at the end has been changed so 30,000 16 bit random numbers do not need to be produced at the same time as plotting 10,000 pixels (generating 30,000 16 bit random values takes nearly 3 seconds so the UNO can really drive the display faster than it appears during that part of the test!)

    The "Sine wave" animation is limited mainly by the floating point maths involved and could be speeded up dramatically by using a simple Sine lookup table, that test would then be over in the blink of an eye!

    Step 3: The Meter Drawing Function

    Here is the function prototype:

    int ringMeter(value, vmin, vmax, x, y, r, "Units", scheme)

    The ringMeter function returns the x coordinate of the right hand side of the meter to aid placement of the next meter.

    value is the value to be displayed and plotted, integer values up to 4 digits are accommodated

    vmin is the minimum value to be plotted

    vmax is the maximum value to be plotted, thus vmin and vmax set the full meter range

    x and y are the coordinates of the top left corner of an imaginary box that contains the meter

    r in the outer radius of the ring in pixels, the minimum is about 52 before the text intrudes on the ring

    "Units" is the text string such as "Volts", "C" etc.

    scheme sets the colour scheme, there are some # define statements in the example that enumerate the settings available, others could be added:

    • #define RED2RED 0
    • #define GREEN2GREEN 1
    • #define BLUE2BLUE 2
    • #define BLUE2RED 3
    • #define GREEN2RED 4
    • #define RED2GREEN 5

    These different schemes set the colour change as the value grows from vmin to vmax, so for example in the following the colour scheme is change from Blue to Red as the value increases:

    ringMeter(reading,-10,50, xpos,ypos,radius,"degC",BLUE2RED);

    In this case a temperature reading is being plotted in the range -10 to +50 degrees C, as the value increases the segments turn from blue (cold!) to red (hot!) as shown in the picture.

    Step 4: Libraries and Sketch

    The ring meter sketch and the two libraries needed are in the attached zip file.

    Some fonts have been disabled in the "Load_fonts.h" file to save space in the compiled sketch. Fonts 2,4 and 6 are enabled.

    The "Adafruit_ILI9341_AS" library as provided here is optimised for the UNO and ATmega 328p microcontroller, so it is best to start with that device.

    To use with others such as the Mega the SPI pins in the sketch will need to be changed and also the #define F_AS_T line will need to be commented out in the "Adafruit_ILI9341_FAST.h" file found inside the "Adafruit_ILI9341_AS" library. When the line is commented out the ATmega328 specific code will not be used so the display updates will be 50% slower.

    Eventually I will add speed enhancing code for the Mega as that is likely to be the upgrade path for projects that use large font files!

    The libraries and sketch were really developed for my own use and hence may have a few rough edges... but it works for me! If you have problems then report them below and I will try to help... given time!

    Warning: This version of the "Adafruit_GFX_AS" has NOT been tested with the other display libraries (S6D02A1 and ST7735) in my other instructables. So please keep a copy of your old library in case this one has an incompatibility! I will be adding compatible hardware drivers to this instructable at some point...

    Lastly, there is a comment at line 121 in the sketch describing how to turn a continuous ring into a segmented one.