ILI9341 touch TFT

The red 2.8 inch 240x320 TFT with a resistive touch panel: an ILI9341 display and an XPT2046 touch controller on one board.

It has fourteen pins down its edge. Aliases: 2.8 inch touch TFT, XPT2046 touch screen.

To touch it, press on the picture while the circuit runs, and drag to move your finger. Let go and the finger lifts.

Pins

Pin What it does
VCC, GND Supply and ground.
CS The display's chip select, active low.
RST The display's reset, active low.
DC The display's command or data line.
MOSI, SCK The display's SPI data in and clock.
LED The backlight.
MISO The display's data out, never driven: nothing is read back from it.
T_CLK The touch controller's SPI clock.
T_CS The touch controller's chip select, active low.
T_DIN The touch controller's data in.
T_DO The touch controller's data out: the readings.
T_IRQ Low while the panel is pressed.

The two chips are separate SPI devices. Sketches usually share one bus between them: T_CLK to SCK, T_DIN to MOSI, T_DO to MISO, and each chip select on a pin of its own. That works because each chip only listens while its own select is low, and T_DO only drives while T_CS is low.

Properties

None.

What the model gets right

The touch controller. Each reading is a real conversation with the XPT2046: a control byte with its start bit and channel, then sixteen clocks with the twelve-bit result in bits 14 to 3 (the >> 3 in every driver). X, Y and the two pressure channels Z1 and Z2 are computed from the resistance of the two plates and of the contact between them, so the libraries' own pressure sum, 4095 + Z1 - Z2, is large for a press and near 0 for none. T_IRQ goes low while the panel is pressed, as long as the last command left the interrupt enabled.

The film is on the glass. Readings come from where your finger is on the glass, not on the picture. Rotate the display and a sketch has to turn its touch readings the same way, as on the bench; the X reading runs along the 240-pixel edge and Y along the 320 whatever the rotation. The edges of the picture read about 200 and 3900, not 0 and 4095, because the film is a little bigger than the picture; map() them to pixels.

The display half is the ILI9341 part exactly.

What it does not model

Noise and jitter, which real panels have plenty of, so averaging does nothing here. Conversion time and the busy pin. The temperature, battery and auxiliary inputs, which read 0. The pressure of a press does not change with how hard you click.

Code

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>

Adafruit_ILI9341 tft(10, 9, 8);   // CS, DC, RST; MOSI 11, SCK 13
XPT2046_Touchscreen ts(7);         // T_CS; T_CLK, T_DIN, T_DO on 13, 11, 12

void setup() {
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(ILI9341_BLACK);
  ts.begin();
  ts.setRotation(1);
}

void loop() {
  if (ts.touched()) {
    TS_Point p = ts.getPoint();
    int x = map(p.x, 200, 3900, 0, tft.width());
    int y = map(p.y, 200, 3900, 0, tft.height());
    tft.fillCircle(x, y, 3, ILI9341_YELLOW);
  }
}

That is a paint program. Adafruit_ILI9341.h and XPT2046_Touchscreen.h are Mokxi's own, on the same calls as upstream. With the display and the touch at the same rotation, a larger p.x is further right on the picture and a larger p.y further down.

Common mistakes

T_DO not wired to MISO: every reading is 0. The display and the touch at different rotations. T_CS left floating, so the touch chip answers when the display is being talked to.

See it in action

Touch paint at /templates is this paint program with a palette along the top, and the touch controller on a bus of its own on A0 to A2. Press Run and draw on the glass.