C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2903.JPG

2.8 inch TFT LCD Touchscreen Display Module Quickstart Guide

The 2.8 inch TFT LCD Touchscreen Display Module is an Arduino Uno Shield that mounts easily in Arduino Uno boards. It has ample display with touchscreen display, making it a display and interactive module in one. Use this for display systems or data gathering with the onboard microSD card slot.

HARDWARE SPECIFICATIONS

  • 2.8 inch LCD TFT display
  • 4 wire resistive touchscree 240 x 320 pixels with individual pixel control
  • Arduino Uno Shield Form Factor
  • On-board 3.3V 300 mA LDO regulator
  • Bright, 4-white-LED backlight
  • Supports microSD card

PARTS LIST

For this quickstart guide, we will need the following materials:

  • 1 – Arduino Uno
  • 1 – 2.8 inch TFT Touchscreen Display Module

HARDWARE OVERVIEW

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2902.JPG

The table below describes the function of each pin in the module

LCD pins Description
LCD_RST LCD Reset Pin
LCD_CS LCD Chip Select
LCD_RS LCD Register Select
LCD_WR LCD Write
LCD_RD LCD Read
LCD_D0 LCD data bit 0
LCD_D1 LCD data bit 1
LCD_D2 LCD data bit 2
LCD_D3 LCD data bit 3
LCD_D4 LCD data bit 4
LCD_D5 LCD data bit 5
LCD_D6 LCD data bit 6
LCD_D7 LCD data bit 7
SD card pins
SD_SS SD card slave select
SD_DI SD card serial data in
SD_DO SD Card serial data out
SD_SCK SD card serial clock

WIRING CONNECTION

Mount the touchscreen display module into the Arduino Uno board.

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2904.JPG
C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2890.JPG

ARDUINO CODE

CALIBRATING TOUCHSCREEN

Open Arduino IDE. Copy the code below.

// Paint example specifically for the TFTLCD breakout board.
// DOES NOT CURRENTLY WORK ON ARDUINO LEONARDO
 
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <TouchScreen.h>
 
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
 
#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8   // can be a digital pin
 
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4
 
// Assign human-readable names to some common 16-bit color values:
#define  BLACK   0x0000
#define BLUE    0x001F
#define CYAN    0x07FF
#define WHITE   0xFFFF
 
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
 
#define PENRADIUS 3
#define MINPRESSURE 10
#define MAXPRESSURE 1000
 
int count = 0;
 
int TS_MINX = 500;
int TS_MINY = 500;
int TS_MAXX = 0;
int TS_MAXY = 0;
 
bool tft_y = false;
 
void setup(void) {
  Serial.begin(9600);
  Serial.println(F("TFT Calibration"));
 
  tft.reset();
 
  //The identifier is hardcoded as the library is unable to recognise the lcd chip
  uint16_t identifier = 0x9341;
 
  tft.begin(identifier);
  pinMode(13, OUTPUT);
  tft.fillScreen(BLACK);
 
  //Splash
  tft.setRotation(1);
  tft.setCursor(30, (tft.height() / 2) - 20);
  tft.setTextSize(2);
  tft.println("TFT Calibration v1.0");
  tft.setCursor(30, tft.height() / 2);
  tft.setTextSize(1);
  tft.setTextColor(WHITE);
  tft.print("Screen size:");
  tft.print(tft.width());
  tft.print("x");
  tft.println(tft.height());
  tft.setCursor(30, (tft.height() / 2) + 20);
  tft.println("Test wil begin in 2s...");
  delay(2000);
  tft.fillScreen(BLACK);
  //TFT Calibration
  tft.setCursor(30, (tft.height() / 2) - 20);
  tft.setTextSize(2);
  tft.println("TFT Calibration");
  tft.setCursor(30, (tft.height() / 2));
  tft.setTextSize(1);
  tft.setTextColor(WHITE);
  tft.print("Click on screen to begin...");
  tft_y = true;
}
 
void drawCir(int prevX, int prevY, int x, int y) {
  tft.fillCircle(prevX, prevY, 15, BLACK);
  tft.fillCircle(x, y, 15, BLUE);
  tft.fillCircle(x, y, 7, CYAN);
}
 
void loop()
{
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);
  // if sharing pins, you'll need to fix the directions of the touchscreen pins
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
 
  if (tft_y) {
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
      debugPt(p);
      Serial.print("\tCount = "); Serial.println(count);
 
      switch (count) {
        case 0:
          tft.fillRect(30, (tft.height() / 2), 180, (tft.height() / 2) + 10, BLACK);
          tft.setCursor(30, (tft.height() / 2));
          tft.print("Press the dots on the corners of the screen.");
          drawCir(0, 0, 0, 0);
          getMinMax(p);
          count++;
          break;
        case 1:
          drawCir(0, 0, tft.width(), 0);
          getMinMax(p);
          count++;
          break;
        case 2:
          drawCir(tft.width(), 0, tft.width(), tft.height());
          getMinMax(p);
          count++;
          break;
        case 3:
          drawCir(tft.width(), tft.height(), 0, tft.height());
          getMinMax(p);
          count++;
          break;
        case 4:
          Serial.print("\nMin X = "); Serial.print(TS_MINX);
          Serial.print("Min Y = "); Serial.print(TS_MINY);
          drawCir(0, tft.height(), tft.width() + 16, tft.height() + 16);
          tft.fillRect(30, (tft.height() / 2), 300, (tft.height() / 2) + 10, BLACK);
          tft.setCursor(30, tft.height() / 2);
          tft.print("Calibration completed!");
          tft.setCursor(30, (tft.height() / 2) + 20);
          tft.print("Min X:");
          tft.print(TS_MINX);
          tft.setCursor(110, (tft.height() / 2) + 20);
          tft.print("Min Y:");
          tft.print(TS_MINY);
          tft.setCursor(30, (tft.height() / 2) + 30);
          tft.print("Max X:");
          tft.print(TS_MAXX);
          tft.setCursor(110, (tft.height() / 2) + 30);
          tft.print("Max Y:");
          tft.print(TS_MAXY);
          tft.setCursor(30, (tft.height() / 2) + 50);
          tft.print("Main Loop will comemence in 5s...");
          delay(5000);
          tft_y = false;
          break;
      }
      delay(200);
    }
  } else {
    tft.setRotation(0);
 
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
      p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
      p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
      tft.fillCircle(p.x, p.y, PENRADIUS, BLUE);
    }
  }
}
 
void debugPt(TSPoint pt) {
  Serial.print("\nX = "); Serial.print(pt.x);
  Serial.print("\tY = "); Serial.print(pt.y);
  Serial.print("\tPressure = "); Serial.print(pt.z);
}
 
 
void getMinMax(TSPoint pt) {
  if (pt.x < TS_MINX) {
    TS_MINX = pt.x;
  }
  if (pt.y < TS_MINY) {
    TS_MINY = pt.y;
  }
  if (pt.x > TS_MAXX) {
    TS_MAXX = pt.x;
  }
  if (pt.y > TS_MAXY) {
    TS_MAXY = pt.y;
  }
}
 
void drawTestScreen() {
  tft.setCursor(tft.width() / 2, tft.height() / 2);
  tft.setTextSize(1);
  tft.setTextColor(WHITE);
  tft.print("Screen size:");
  tft.print(tft.width());
  tft.print("x");
  tft.println(tft.height());
 
  tft.println("Calibration");
  tft.println("-------------------");
  tft.println("Press on the dot to begin");
}

Upload the code. Wait for the display to look similar as shown below:

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2891.JPG

Using the included stylus, click on the display.

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2892.JPG

Clink on the blue dots for the screen to do its calibration.

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2893.JPG

Once done, the display will show some values for Min X, Min Y, Max X and Max Y. Copy these values since they will be used for the next code.

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2895.JPG

Go back to Arduino IDE, and copy the code below. Replace TS_MINX value with Min X value, TS_MINY value with Min Y value, TS_MAXX value with Max X value and TS_MAXY value with Max Y value.

/*
   Small Program to Simulate a Numpad using a 2.4" TFT Touchscreen
   Program does not act as an USB HID Device, for reference purposes only
   Tested on Arduino UNO Only and 0x9341
   By William Tavares

   Note:
   This version is coplete with styling and numbers,
   if you want the smaller version get the "numpad-layout" program
   from my Github https://github.com/williamtavares/Arduino-Uno-NumPad

   Open the Serial Monitor to see the program running
   Enjoy!
*/

#include <Adafruit_GFX.h>
#include <TouchScreen.h>
#include <Adafruit_TFTLCD.h>

#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8   // can be a digital pin

// calibration mins and max for raw data when touching edges of screen
// YOU CAN USE THIS SKETCH TO DETERMINE THE RAW X AND Y OF THE EDGES TO GET YOUR HIGHS AND LOWS FOR X AND Y
#define TS_MINX 136
#define TS_MINY 98
#define TS_MAXX 887
#define TS_MAXY 901

//SPI Communication
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4

//Color Definitons
#define BLACK     0x0000
#define BLUE      0x001F
#define GREY      0xCE79
#define LIGHTGREY 0xDEDB
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define MINPRESSURE 1
#define MAXPRESSURE 1000

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
// Pins A2-A6
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 364);

//Size of key containers 70px
#define BOXSIZE 70

//2.4 = 240 x 320
//Height 319 to fit on screen

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

//Container variables for touch coordinates
int X, Y, Z;

//Screen height without hidden pixel
double tHeight = tft.height() - 1;
//Centering the mid square
double center = (tft.width() / 2) - (BOXSIZE / 2);
//Space between squares
double padding = 10;
//Position of squares to the left and right of center
double fromCenter = BOXSIZE + padding;
//Second row Y-Axis position
double secondRow = BOXSIZE + padding;
//Third row Y-Axis position
double thirdRow = secondRow + BOXSIZE + padding;
//Fourth row Y-Axis position
double fourthRow = thirdRow + BOXSIZE + padding;
//Y-Axis align for all squares
double verticalAlign = (tHeight - ((BOXSIZE * 4) + (padding * 3))) / 2;
//Left column starting x posision
double leftColPositionX = center - fromCenter;
//Mid column starting x posision
double midColPositionX = center;
//Right column starting x posision
double rightColPositionX = center + fromCenter;

void setup() {
  Serial.begin(9600);

  tft.reset();
  uint16_t identifier = tft.readID();
  tft.begin(identifier);

  //Background color
  tft.fillScreen(LIGHTGREY);

  // draw num pad
  createButtons();
  insertNumbers();
  Serial.println(F("Press any button on the TFT screen: "));



}

void loop() {


  retrieveTouch();
  int boxHeightRow1 = verticalAlign + BOXSIZE;
  int boxHeightRow2 = secondRow + BOXSIZE;
  int boxHeightRow3 = thirdRow + BOXSIZE;
  int boxHeightRow4 = fourthRow + BOXSIZE;

  if (Z > MINPRESSURE && Z < MAXPRESSURE) {

    //redraw numpad to clear old number
    tft.fillScreen(LIGHTGREY);
    createButtons();
    insertNumbers();
    //default text setup for number display on tft
    tft.setCursor(100, 120);
    tft.setTextColor(RED);
    tft.setTextSize(9);

    //Check if element clicked is in left column
    if (X > leftColPositionX && X < (leftColPositionX + BOXSIZE)) {
      //Check if element clicked is in row 1
      if (Y > verticalAlign) {
        if (Y < boxHeightRow1) {
          Serial.println("1");
          tft.println("1");
          delay(150);
        }
        //Check if element clicked is in row 2
        else if (Y < boxHeightRow2) {
          Serial.println("4");
          tft.println("4");
          delay(150);
        }
        //Check if element clicked is in row 3
        else if (Y < boxHeightRow3) {
          Serial.println("7");
          tft.println("7");
          delay(150);
        }
        //Check if element clicked is in row 4
        else if (Y < boxHeightRow4) {
          Serial.println("0");
          tft.println("0");
          delay(150);
        }
      }
      //Check if element clicked is in mid column
    } else if (X > midColPositionX && X < (midColPositionX + BOXSIZE)) {
      //Check if element clicked is in row 1
      if (Y > verticalAlign) {
        if (Y < boxHeightRow1) {
          Serial.println("2");
          tft.println("2");
          delay(150);
        }
        //Check if element clicked is in row 2
        else if (Y < boxHeightRow2) {
          Serial.println("5");
          tft.println("5");
          delay(150);
        }
        //Check if element clicked is in row 3
        else if (Y < boxHeightRow3) {
          Serial.println("8");
          tft.println("8");
          delay(150);
        }
        //Check if element clicked is in row 4
        else if (Y < boxHeightRow4) {
          Serial.println("0");
          tft.println("0");
          delay(150);
        }
      }
      //Check if element clicked is in third column
    } else if (X > rightColPositionX && X < (rightColPositionX + BOXSIZE)) {
      if (Y > verticalAlign) {
        //Check if element clicked is in row 1
        if (Y < boxHeightRow1) {
          Serial.println("3");
          tft.println("3");
          delay(150);
        }
        //Check if element clicked is in row 2
        else if (Y < boxHeightRow2) {
          Serial.println("6");
          tft.println("6");
          delay(150);
        }
        //Check if element clicked is in row 3
        else if (Y < boxHeightRow3) {
          Serial.println("9");
          tft.println("9");
          delay(150);
        }
        //Check if element clicked is in row 3
        else if (Y < boxHeightRow4) {
          Serial.println(".");
          tft.println(".");
          delay(150);
        }
      }
    }

    // good for debuggin, prints out the x,y cordinates of the press
    // tft.setTextSize(3);
    // tft.print("X = "); tft.println(X);
    // tft.print("Y = "); tft.println(Y);

  }
}

void retrieveTouch()
{
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);

  //If sharing pins, you'll need to fix the directions of the touchscreen pins
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);




  //Scale from 0->1023 to tft.width
    //X = map(p.x, TS_MAXX, TS_MINX, 0, tft.width());
  //  Y = map(p.y, TS_MAXY, TS_MINY, 0, tft.height());

  // on my tft the numbers are reversed so this is used instead of the above
  X = tft.width() - map(p.x, TS_MAXX, TS_MINX, 0, tft.width());
  Y = map(p.y, TS_MAXY, TS_MINY, 0, tft.height());
  Z = p.z;



}

void createButtons() {
  //(initial x,initial y,width,height,color)
  double secondRowVertialAlign = secondRow + verticalAlign;
  double thirdRowVertialAlign = thirdRow + verticalAlign;
  double fourthRowVertialAlign = fourthRow + verticalAlign;

  /***Draw filled squares with specified dimensions and position***/
  //First Row
  tft.fillRect(leftColPositionX, verticalAlign, BOXSIZE, BOXSIZE, GREY);
  tft.fillRect(midColPositionX, verticalAlign, BOXSIZE, BOXSIZE, GREY);
  tft.fillRect(rightColPositionX, verticalAlign, BOXSIZE, BOXSIZE, GREY);

  //Second Row
  tft.fillRect(leftColPositionX, secondRowVertialAlign, BOXSIZE, BOXSIZE, GREY);
  tft.fillRect(midColPositionX, secondRowVertialAlign, BOXSIZE, BOXSIZE, GREY);
  tft.fillRect(rightColPositionX, secondRowVertialAlign, BOXSIZE, BOXSIZE, GREY);

  //Third Row
  tft.fillRect(leftColPositionX, thirdRowVertialAlign, BOXSIZE, BOXSIZE, GREY);
  tft.fillRect(midColPositionX, thirdRowVertialAlign, BOXSIZE, BOXSIZE, GREY);
  tft.fillRect(rightColPositionX, thirdRowVertialAlign, BOXSIZE, BOXSIZE, GREY);

  //Fourth Row
  tft.fillRect(leftColPositionX, fourthRowVertialAlign, (BOXSIZE * 2) + padding, BOXSIZE, GREY);
  tft.fillRect(rightColPositionX, fourthRowVertialAlign, BOXSIZE, BOXSIZE, GREY);

  /***Draw Borders around squares***/
  //First Row
  tft.drawRect(leftColPositionX, verticalAlign, BOXSIZE, BOXSIZE, BLACK);
  tft.drawRect(midColPositionX, verticalAlign, BOXSIZE, BOXSIZE, BLACK);
  tft.drawRect(rightColPositionX, verticalAlign, BOXSIZE, BOXSIZE, BLACK);

  //Second Row
  tft.drawRect(leftColPositionX, secondRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);
  tft.drawRect(midColPositionX, secondRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);
  tft.drawRect(rightColPositionX, secondRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);

  //Third Row
  tft.drawRect(leftColPositionX, thirdRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);
  tft.drawRect(midColPositionX, thirdRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);
  tft.drawRect(rightColPositionX, thirdRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);

  //Fourth Row
  tft.drawRect(leftColPositionX, fourthRowVertialAlign, (BOXSIZE * 2) + padding, BOXSIZE, BLACK);
  tft.drawRect(rightColPositionX, fourthRowVertialAlign, BOXSIZE, BOXSIZE, BLACK);
}

void insertNumbers() {
  //Centers text horizontally on all three columns
  double leftColCursorX   = leftColPositionX + (BOXSIZE / 3);
  double midColCursorX    = midColPositionX  + (BOXSIZE / 3);
  double rightColCursorX  = rightColPositionX + (BOXSIZE / 3);
  //Centers text horizontally on all four rows
  double firstRowCursorY  = verticalAlign + (BOXSIZE / 3);
  double secondRowCursorY = secondRow + firstRowCursorY;
  double thirdRowCursorY  = thirdRow  + firstRowCursorY;
  double fourthRowCursorY = fourthRow + firstRowCursorY;

  tft.setTextSize(4);
  tft.setTextColor(BLACK);

  //Insert Number 1
  tft.setCursor(leftColCursorX, firstRowCursorY);
  tft.println("1");

  tft.setCursor(midColCursorX, firstRowCursorY);
  tft.println("2");

  //Insert Number 3
  tft.setCursor(rightColCursorX, firstRowCursorY);
  tft.println("3");

  //Insert Number 4
  tft.setCursor(leftColCursorX, secondRowCursorY);
  tft.println("4");

  //Insert Number 5
  tft.setCursor(midColCursorX, secondRowCursorY);
  tft.println("5");

  //Insert Number 6
  tft.setCursor(rightColCursorX, secondRowCursorY);
  tft.println("6");

  //Insert Number 7
  tft.setCursor(leftColCursorX, thirdRowCursorY);
  tft.println("7");

  //Insert Number 8
  tft.setCursor(midColCursorX, thirdRowCursorY);
  tft.println("8");

  //Insert Number 9
  tft.setCursor(rightColCursorX, thirdRowCursorY);
  tft.println("9");

  //Insert Number 0
  tft.setCursor(leftColPositionX + BOXSIZE, fourthRowCursorY);
  tft.println("0");

  //Insert Period Character
  tft.setCursor(rightColCursorX, fourthRowCursorY);
  tft.println(".");
}

Upload the code.

OUTPUT

The touchscreen display shows a keypad with numbers 0-9 and a period.

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2896.JPG

Touching one number displays a number corresponding to the touched number. If 0 (Zero) is pressed, a 0 number showed up on the center of the display.

C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2900.JPG C:\Users\Jarvis_v1\Downloads\SHAREit\iPhone 5s\photo\IMG_2899.JPG

References and other Aplications

You can find more information, examples and references below.

Display Project by educ8tvs.tv:
Touch Screen with SD Card Socket for Arduino Uno (by dmainmon)
2.8 TFT LCD Touchscreen Shield (by cyaninfinite)
2.8 TFT LCD Touchscreen Datasheet