Arduino Analogue 'ring' Meter on Colour TFT Display

41,011

92

44

Published

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.

    5 People Made This Project!

    Recommendations

    • Water Contest

      Water Contest
    • Clocks Contest

      Clocks Contest
    • Creative Misuse Contest

      Creative Misuse Contest

    44 Discussions

    Following on from FabioB3's comment, I have run the Adafruit "graphicstest" sketch under the original Adafruit_GFX library and my enhanced version. The results are quite interesting:

    The speed has been increased to an average of 2.3 times faster. This is an equivalent boost to running a 16MHz UNO at 36MHz!

    Of particular note is the "line", triangle outline and circle outline drawing speed boost. This is because the Bresenham algorithm has been enhanced to take advantage of the way the display hardware has to be driven. The line drawing speed increase is the equivalent of running an UNO at 88MHz.

    See attached table of results.

    Test results.png
    4 replies

    Hi, Bodmer

    Congratulations again for your projects. The truth is that they are something that I always had in my mind. I wanted to ask for your help again, I'm interested in displaying data in the wattmeter display through input "A0", because in your sketch, the indication is simulated by a sinusoidal signal. It's posible?

    BODMER thank you very much, I hope your response as you have always done, congratulations !!!!

    Try code like this:

    reading = analogRead(A0);

    Then change the calling function to, for example:

    ringMeter(reading, 0, 1023, xpos, ypos, radius, "W", GREEN2RED);

    Hi, Bodmer, All Good?

    Can you help me again? I am trying one of the examples to make a voltmeter with of your ring put and it would need to visualize a precision value in the center of the display (the information her provides a converter ADC 24Bits "LTC2400") I have the code to monitor the readings of the LTC2400 but only it does it across ARDUINO's serial monitor, but it wanted to visualize it in the own display. Can you help me?

    THANKS A LOT BODMER!!!

    Hi Bodmer,

    Thank you very much for this work, its awesome,

    i managed to make this code and library to work on 1.8" TFT ST7735,(160X128) and i want to use it to read from sensor A0, i have a problem with the meter (gauge) position, the value is like you write from right to left, not upside down no, its like the left is right and the right is left, is there any way to fix this from library or the code itself.

    please check the attached picture

    Thank you very much and looking forward to hear form you.

    pic_8.JPG
    2 replies

    Could you post some code as I'm trying to work it on my 1.8 ST7735 as well and any ideas would be awesome !!

    Answered above, sorry for the late reply!

    0
    user
    Edw6

    Question 4 months ago

    Hi Bodmer

    I am building a project that would look real good with 2 of your projects.

    This one and the digital analog meter.

    I am using a raspberry PI for my display . Your ring graphic would fit very nicely .

    Is there a change that you or one of your followers have put this on the PI?

    2 more answers

    The library is not compatible with the Pi and I do not have the knowledge to convert it. You could try the RPi forum.

    thank you

    I will check it out at RPI : )

    Great! Thanks for the feedback!

    0
    user
    Edw6

    Question 4 months ago

    Can this run on the Rasberry pi with a 5 inch scrteen ?

    1 more answer

    No, sorry!

    0
    user
    alenZGB

    Question 4 months ago

    I have UNO with https://www.velleman.eu/products/view/?id=435582
    2.8 tft velleman display and i get white display.
    i manage to use one library and on tft.begin(0x9341); if i dont use 0X9341 the

    picture wont come, maybe here is the same problem ? Drivers should be ILI9341 acording to web page for that screen that i bought.

    Any help would be nice .

    Thanks in advance.

    1 more answer

    Hello,

    I love this project. I'm starting in this interesting world of Arduino.

    As an ultralight pilot, it seems interesting to be able to use this to control engine temperatures. 2 of the exhaust gas temperature, 1 of the water, and another of the engine head.

    I have a mega arduino 2560 and a tft 480x320 from aliexpress.

    would it be possible with these elements to do something of what I have described?

    This is just what I needed! Looking forward to try it out as soon as you have fixed the problems!
    Do you know if it works with the 1.8 inch display to?

    1 reply

    Working now!

    The 1.8" drivers probably will not work with the Adafruit_GFX_AS library version attached to this instructable, but...

    The sketch uses standard library function calls so should work with the drivers and Adafruit_GFX_AS library from my instructable here:

    https://www.instructables.com/id/Arduino-TFT-displa...

    Let me know is it works. I will be updating this instructable with updated drivers, which display do you use?

    TTFN