Arduino Adafruit GFX Drawing Circles

Two Concepts You Should Understand

Within a few minutes, you will be drawing circles on your TFT display.

In order to make the most this tutorial  you will want to:

How to Specify points on a TFT Display  – Here you will be introduced to the coordinate system used by the Adafruit GFX graphics library.  Its like most other coordinate systems used in graphic’s software.

Know How to Use 16 Bit Color –  Many of the TFT displays available use 16 bit color.  This will show you how to specify color using that format.

Hardware Used in Developing this Guide

I used a 128 x 128 1.4 inch TFT display.   Mine uses an IL9163.    This is a low cost display that I feel is great for getting introduced to using these types of displays with your Arduino.  You can get this display at any of the following locations:

eBay      Amazon

Circles on a TFT

Imagine having a piece of graph paper and creating a circle by shading dots using a colored pencil.   As you can imagine,  what you will end up with a is a jagged approximation of a circle.   In other words, it won’t be the same circle you get when you draw with a drafter’s compass.

That’s what happens when you draw a circle on a TFT display.   That said,  with great resolution,  you can get an approximation of a circle that actually looks like a circle.  Especially if you put the circle against the right background color.

Adafruit GFX Circles Desired vs Actual

Drawing Circles on a TFT

Drawing a Circle on a TFT,  requires that you supply a few things:

  • The x and y coordinates of the circle center
  • The radius of the circle ( or distance from the center to the outer edge)
  • The color of the circle

 

Adafruit GFX Circle Values

Notice how the diameter of the circle (twice the radius) will ALWAYS be an odd number!

Adafruit GFX drawCircle()

What is Does

Draws a circle with a single line onto your TFT display.

How to Use It

You will need to specify:

  • An X-Y coordinate for the circle center
  • An integer specifying the radius
  • A 16 bit Color used to draw the circle

Adafruit GFX drawCircle Usage

drawCircle Arduino Sample Sketch

This example simply draws an animated circle that starts in the upper left hand corner of your display and moves it to the lower right hand corner.

The technique used here is to:

  1. Draw the circle using the circle color
  2. wait a little bit
  3. Draw the circle again at the same location using the background color
  4. Draw the circle using the circle color in a new location

 

// Henry's Bench
//  Adafruit GFX drawCircle
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>


// Pallete - Where you assign names to colors you like
#define BACKCOLOR 0xFFFF // White
#define LINECOLOR1 0x0000 

#define CS 10
#define DC 9

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

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

void loop(){
  
    for(int x = 0; x < 128; x++){
     tft.drawCircle(x, x, 10, LINECOLOR1);
     delay(5);
     tft.drawCircle(x,x, 10, BACKCOLOR);     
    } 
     
}

Adafruit GFX fillCircle()

What is Does

Exactly like the draw circle excepts that it fills the circle with the specified color.

How to Use It

You will need to specify:

  • An X-Y coordinate for the circle center
  • An integer specifying the radius
  • A 16 bit Color used to draw the circle

Adafruit GFX fillCircle Usage

drawCircle Arduino Sample Sketch

ClownFaceCircles by themselves are pretty boring.  That said,  with a little creativity you can do more with this command than simple drawing filled circles.  This sketch features a clown face that has been centered on my 128 x 128 screen.

The basic face is drawn in setup.   I’ve inserted some delays so that you can see how the face is built.

Once the face is built,   I move the eyes and flash the nose in the sketch loop.

 

// Henry's Bench
//  Adafruit GFX fillCircle
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>


// Pallete - Where you assign names to colors you like
#define BACKCOLOR 0x8410//0xA534 
#define FACECOLOR 0xFFFF
#define NOSECOLOR 0xF800
#define LIPCOLOR 0xFC10
#define HAIRCOLOR 0xFC08
#define EYEOUTLINE 0x0000
#define EYEBALL 0x001F


#define CS 10
#define DC 9

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

void setup() {
  Serial.begin(9600);
  tft.begin();
  tft.fillScreen(BACKCOLOR);

  delay(1000);  
  
  //Build the hair
  tft.fillCircle(30,45,18,HAIRCOLOR);
  tft.fillCircle(51,35,17,HAIRCOLOR);
  tft.fillCircle(72,33,17,HAIRCOLOR);
  tft.fillCircle(93,44,19,HAIRCOLOR);  
  
  delay(1000);
  
  //draw the face outline  
  tft.fillCircle(63,63,35, FACECOLOR);
  
  delay(1000);
  
  // draw the mouth 
  tft.fillCircle(63,80,12, LIPCOLOR);
  
  delay(1000);
  
  // cut out  a part of the circle to make the mouth smile
  tft.fillCircle(63,63,20, FACECOLOR);
  
  delay(1000);
  
  // add the nose
  tft.fillCircle(63,66,11,NOSECOLOR);
  
  delay(1000);
  
  // Draw the eye outline    
  tft.drawCircle(47,50,8,EYEOUTLINE);
  tft.drawCircle(79,50,8,EYEOUTLINE); 
  
  delay(1000);
  
  //move onto the loop to animate the eyes and nose
   
}


void loop(){
  int leftEyeX;
  int rightEyeX;
  
  
  // Move Eyeballs Left to Right
  for(int x = 0; x<8; x++){
    leftEyeX = 43 + x;
    rightEyeX = 75 + x; 
    tft.fillCircle(leftEyeX,50,3,EYEBALL);
    tft.fillCircle(rightEyeX,50,3,EYEBALL);
    delay(200);
    if(leftEyeX == 47){
      noseflash();
    }
    tft.fillCircle(leftEyeX,50,3,FACECOLOR);
    tft.fillCircle(rightEyeX,50,3,FACECOLOR);
    
   
  } 
  
  
  // Move Eyeballs Right to Left
  
   for(int x = 8; x>0; x--){
    leftEyeX = 43 + x;
    rightEyeX = 75 + x; 
    tft.fillCircle(leftEyeX,50,3,EYEBALL);
    tft.fillCircle(rightEyeX,50,3,EYEBALL);
    delay(200);
    if(leftEyeX == 47){
      noseflash();
    }
    tft.fillCircle(leftEyeX,50,3,FACECOLOR);
    tft.fillCircle(rightEyeX,50,3,FACECOLOR);
    
       
  }
     
}

void noseflash(){
    int noseRadius;
    
    for( int x = 0; x < 11; x++){
      noseRadius = 11 - x;
      tft.drawCircle(63,66,noseRadius,FACECOLOR);
      delay(10);
      tft.drawCircle(63,66,noseRadius,NOSECOLOR);
    }  
}