Arduino Adafruit GFX: Bar Graph

Creating a Visual Aid

Arduino TFT Bar Graph TutorialThe neat thing about a bar graph is that it gives us a rough order of magnitude of the value that is being displayed.  When viewing a bar graph, we don’t need to perform mental calculations to determine the relative amount of the measured value.  Instead, we can instantly know that its ‘about a half’ or ‘nearly full’.

In this tutorial we will build a bar graph using the Adafruit GFX library.  This bar graph will display a measurement from an analog input.   The bar graph will also include a scale that aids in determining the magnitude of the analog signal being measured.

What You Should Know How to Do

This tutorial assumes that you understand how to use 16 bit color,  create lines and how to created rectangles using the Adafruit GFX library.   If you’e new to the library,  you may wish to read some of the articles found in the Adafruit GFX Library User Guide.

My Hardware Set Up

Any GFX compatible display will work in this tutorial.  That said,  I developed mine using a common low cost ILI9163C 128 x 128 device.   You can get that display at any of the vendors identified below.

eBay      Amazon

I have a getting started tutorial that will help you put this display to use HERE.

Bar Graph Screen Elements Created

As alluded to before,  we will be creating a bar graph and a scale that includes major divisions and minor divisions.

Adafruit GFX Bargraph Elements

The scale is that that visual aid that allows us to put some meaning to the value we are measuring.    For example,  if the green bar graph were near the center scale division, we would say that it is about half.   Our scale includes:

  • Scale Major Divisions – There are three of them.  The top is 100 percent,  the middle is 50 percent and the bottom is zero percent.
  • Scale Minor Divisions –  There are two of these.  One at 75 percent and the other at 25 percent.

Bar Graph Anti-Flicker Technique

Unlike the display that you’re using to read this tutorial,  the TFT display using the Adafruit GFX Library isn’t that fast.  As a result,  it will flicker if asked to do a lot in a short period of time.

The way to minimize this flicker is to reduce the number of times that we paint to the screen and to reduce the amount that is painted.  We will do this as follows:

  • We Paint When Necessary – If the value has not changed,  we won’t paint the bar graph.   A more sophisticated approach might also filter out spurious noise or minute changes.
  • We Paint What is Needed –  In normal continuous operation,  we may not expect our measurement to change that fast.  When the bar graph increases,  we will ‘add’ a small green square to the display.  When it decreases, we will add a small black square to the display.

Adafruit GFX Bargraph Anti Flicker<

Arduino Adafruit GFX Bar Graph Tutorial

Connect Your Hardware

As previously mentioned,  I use the 1.44 inch ILI9163C 128 x 128 display.   Your connections will vary depending on what you have.

Adafruit GFX Bargraph

Copy Paste and Modify the Tutorial Sketch

You will need to modify the code with the proper constructors to make it work with your display.

Note that my graph height is 100 pixels.  I did this for simplicity.   The bar graph can be any height that you want.  You will just need to apply the correct ratio for the height you choose.

// Henry's Bench
//  Basic Bargraph Tutorial

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>

#define CS 10
#define DC 9

// Declare an instance of the ILI9163
TFT_ILI9163C tft = TFT_ILI9163C(CS, 8, DC); 


// Color Pallette

#define BACKCOLOR 0x18E3
#define BARCOLOR 0x0620
#define SCALECOLOR 0xFFFF

//Analog Measurement Declarations
const int analogIn = A0;
int RawValue = 0;
int LastPercent = 0;
 

void setup() {
  tft.begin();
  tft.fillScreen(BACKCOLOR);
  drawScale(); 
}

void loop(){  
    int newPercent;
    RawValue = analogRead(analogIn);
    newPercent = int((RawValue/1024.0)* 100.0);
    
    if (newPercent != LastPercent){
      drawBar(newPercent);     
    }
     
}

void drawScale(){  
  tft.drawFastVLine(55, 20,100, SCALECOLOR ); // Vertical Scale Line  
  tft.drawFastHLine(47, 20, 8, SCALECOLOR); // Major Division
  tft.drawFastHLine(50, 44, 5, SCALECOLOR); // Minor Division
  tft.drawFastHLine(47, 69, 8, SCALECOLOR); // Major Division
  tft.drawFastHLine(50, 94, 5, SCALECOLOR); // Minor Division
  tft.drawFastHLine(47, 119, 8, SCALECOLOR);  // Major Division
}


void drawBar (int nPer){

  if(nPer < LastPercent){
    tft.fillRect(61, 20 + (100-LastPercent), 30, LastPercent - nPer,  BACKCOLOR);     
  }
  else{
    tft.fillRect(61, 20 + (100-nPer), 30, nPer - LastPercent,  BARCOLOR);
  }    
  LastPercent = nPer;  
  
}