Saturday, 19 September 2015

How to use the TFT display 2.2" QVGA with Arduino, Part 2/2.

Arduino applications with ILI9341 library (Part 2)

By Giovanni Carrera
SD wirings.
On the other side there is a 4-pin connector (not welded) for driving the SD card on the module, the following table shows the connections:
TFT board
J4 Pin
SD Sck

If you want to use the SD card, the pin SD Cs must be connected to D10,another free pin of Arduino, while the other SPI signals must be connected together with those of the TFT display because in the module they are separate.
In the examples of the library there is a program that loads bitmap images from the SD card, it has been tested successfully, after transferring the files to the SD and correct one of the names in the program. In the sketch was used pin D4 of Arduino for the chip select of SD, but this is already used for resetting the TFT, so you need to change the program and assign the Cs of SD pin D10 Arduino (pin 16 of CPU).

Example#1:  alphanumeric writing  on the TFT

I did not find any documents describing the graphic functions library Seeed ILI9341. Were extremely useful the examples of graphics and text applications provided with the library. From these sketches and the library functions, well enough commented, I have written the following sketch of the test:
/* Text writing program using ILI9341 library
   using size 2 fonts, 20 characters/line are available
   in this case 20 pixel are needed for spacing
   G. Carrera 3 gen 2013

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

void setup()
  TFT_BL_ON;      // turn on the TFT backlight
  Tft.TFTinit();  // initialize the TFT library
  //write a string, x=0, y=0, size:2, color: yellow
  Tft.drawString("Prova display TFT",0,0,2,YELLOW);
  Tft.drawString("Misure analogiche:",0,40,2,WHITE);

void loop()
  // to cancel the previous values, it covers with a black rectangle:
  Tft.fillRectangle(100, 80, 100, 120,BLACK);
  int dato = analogRead(A0);// read the channel #0
  //write an integer, position: x,y, size:3, color: red
  Tft.drawString("Ch0:",10,80,3, RED);
  Tft.drawNumber(dato, 100, 80, 3, GREEN);
  dato = analogRead(A1);// read the channel #1
  Tft.drawString("Ch1:",10,120,3, RED);
  Tft.drawNumber(dato, 100, 120, 3, GREEN);
  dato = analogRead(A2);// read the channel #2
  Tft.drawString("Ch2:",10,160,3, RED);
  Tft.drawNumber(dato, 100, 160, 3, GREEN);
I have tried to describe in the comments the syntax of used functions. The library seems to support four font sizes. The size 1 is hard to read, using the size 2 there are 20 characters per line and must be spaced at least 20 pixels. So you can create a display with 16 rows x 20 columns. By comparing the list with the previous, we note that the 0,0 is the top left.
Since the data are updated approximately every second, you have to delete the pixels written in the previous loop. So as not to rewrite the permanent written, it was decided to cancel the measures with a filled rectangle (FillRectangle), black, large enough to cover the writing. The writings of the measures are of size 3 with a pitch of 40 pixels.

Example#2:  graphics of analog data samples.
Before writing this program I have studied the graphic functions library. In Appendix I listed the main functions.
You can not even call digital oscilloscope the proposed system, but is a good starting point and can already be useful in many applications. The limits are evident: the relative slowness of Arduino (Uno) and writing on a display interfaced with a low speed serial bus.
Note that you must delete the previous point before drawing the current one. To do this I have created two buffers, one for the measures to be graphed and one for the previously tracks, to be outlined in black. You could also reset all memory or draw a black rectangle. The following figure shows the representation of a sinusoidal signal of about 1 Hz.
/* Program TFT_oscillo
 Using the ILI9341 library
 Graphics the time series of 240 8 bit samples
 G. Carrera 18 gen 2013

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

Unsigned long deltat = 14; //sample period in milliseconds
unsigned int data[240];// data buffer
unsigned int datap[240];// previous values buffer (to be clear)
unsigned long pms = 0;
unsigned int ch0;
unsigned int i = 0;

void setup()
  TFT_BL_ON;// TFT backlight on
  Tft.TFTinit();  // TFT library initialize
  // draw string, (x, y), size: 3, color: yellow
  Tft.drawString("GCar - Oscillo",0,0,2,YELLOW);
  Tft.drawString("GCar - Oscillo",0,0,2,BLACK);// black to clear

void loop()
  unsigned long cms = millis();
  // checks if elapsed deltat milliseconds
  if(cms - pms > deltat) {
    pms = cms;// updates pms
    // converts A0
    ch0 = analogRead(A0);
    data[i]= map(ch0, 0, 1023, 0, 319);
    if (i > 239){
      for (int i=0; i <= 239; i++){
        // graphic of data acquired
        Tft.setPixel(i+10, datap[i], BLACK);//clear the previous dot
        Tft.setPixel(i+10, data[i], CYAN);// print new dot
        datap[i]= data[i];// updates previous data
      i = 0;

APPENDIX: library  TFTv2 functions

The following was obtained by analyzing the library files and the data-sheet controller ILI9341. It describes only the main functions.


Display resolution: 240 × 320, with X = 0 to 239 and Y = 0 to 319. The position 0,0 is the top left. The controller has a graphics memory of 240 × 320 × 18 bits = 172800 bytes. The 18 bit color damage 218 = 262,144 colors, with 6 bits for each basic color (RGB). For increased data transfer rates can be used for 16-bit pixels with 65,536 colors (R: 5-bit G: 6-bit, B: 5-bit). As seen on the type of variable color (INT16U), the library uses 16-bit.

TFT_BL_ON;// Turn on the LED backlight

TFT_BL_OFF; //Turn Off the backlight

Tft.TFTinit (void);// initializes the display

Alphanumeric print functions
Tft.drawChar Print a rough character position pox, Poy, of size size and color fgcolor:
Tft.drawChar (INT8U ascii, INT16U pox, INT16U Poy, INT16U size, INT16U fgcolor);

Tft.drawString Print the string string, the position pox, Poy, of size size and color fgcolor:
Tft.drawString (char * string, INT16U pox, INT16U Poy, INT16U size, INT16U fgcolor);

Tft.drawNumber Print the integer long_num position pox, Poy, of size size and color fgcolor:
Tft.drawNumber (long long_num, INT16U pox, INT16U Poy, INT16U size, INT16U fgcolor);

Tft.drawFloat Print floatNumber number with decimal decimal places, the position pox, Poy, of size size and color fgcolor:
Tft.drawFloat (float floatNumber, INT8U decimal, INT16U pox, INT16U Poy, INT16U size, INT16U fgcolor);

Graphic functions
Tft.drawHorizontalLine draw a horizontal line from the position pox, POY, long length and color color:
Tft.drawHorizontalLine (INT16U pox, INT16U Poy, INT16U length, INT16U color);

Tft.drawVerticalLine draws a vertical line from the position pox, POY, long length and color color:
Tft.drawVerticalLine (INT16U pox, INT16U Poy, INT16U length, INT16U color);

Tft.drawLine draw a horizontal line from the position x0, y0 the position x1, y1, color color:
Tft.drawLine (INT16U x0, y0 INT16U, INT16U x1, y1 INT16U, INT16U color);

Tft.drawRectangle draws a rectangle on the position pox, POY, long length, wide width and color color:
Tft.drawRectangle (INT16U pox, INT16U Poy, INT16U length, width INT16U, INT16U color);

Tft.fillRectangle draws a rectangle filled the position pox, POY, long length, wide width and color color:
Tft.fillRectangle (INT16U pox, INT16U Poy, INT16U length, width INT16U, INT16U color);

Tft.drawCircle trace a circle of center pox, Poy, of radius r color color:
Tft.drawCircle (POX int, int Poy, int r, INT16U color);

Tft.drawTraingle trace a triangle vertices poX1, poY1, poX2, poY2, poX3, poY3 and color color:
Tft.drawTraingle (poX1 int, int poY1, poX2 int, int poY2, poX3 int, int poY3, INT16U color);

Tft.setPixel track a point to position pox, Poy and color color:
Tft.setPixel (INT16U pox, INT16U Poy, INT16U color);

Tft.setXY is positioned to point pox, Poy:
Tft.setXY (INT16U pox, INT16U Poy);


  1. Hola! Can you give me advice how to rotate screen(landscape). I tried UTFT( i dont know how use hardware spi, software spi very slow for me) and modifications by -__- ( but it is not works. How to get functions as UTFT and speed from ili9341gmtii( I have uno and nanoV3

  2. Many TFT display, like the one I used, have SPI interface, so they're pretty slow. For more speed you need a TFT with a parallel interface.
    Warning, the TFT of this project has 3.3V TTL signals, so you have to use an Arduino with 3.3V supply or a voltage level adapter circuit.
    To rotate the picture you have to reduce the size, it is not an easy thing with the small ram size of Arduino Uno.

    1. I use voltage divider.(
      But why gmtii`s lib works so fast? i`m going to rewrite all characters by pixel, it will take a lot of time =) 8x8, but i guess it will work

    2. If you're referring to the pseudo-oscilloscope, it does not work in real time, but acquires the signal and then make the graphics. I do not understand why you want to rewrite the characters, maybe do you want to use the longest side?

  3. Nice post. I was checking constantly this blog and I am impressed! Extremely helpful information specially the last part I care for such info a lot. I was seeking this particular information for a very long time. Thank you and good luck.
    Liquid Level Sensor