Adafruit ILI9341: a 320x240 color TFT on SPI
Adafruit ILI9341 drives the 2.4 and 2.8 inch color screens built on the ILI9341 controller, 240 by 320 pixels at 16 bits of color, many of them with a resistive touch panel and an SD card slot on the same board. It is a thin driver: the drawing and text calls come from Adafruit GFX, and this library adds the ILI9341鈥檚 start-up, rotation and fast pixel transfer.
Built in on Mokxi: #include <Adafruit_ILI9341.h> and it builds, with nothing to install. Free, and no account needed.
What Adafruit ILI9341 does
The screen sits on the SPI bus. Its SCK and MOSI (often labeled SDI) go to the board鈥檚 SPI pins, MISO is optional, and three more pins are your choice: CS selects the screen, DC tells it whether a byte is a command or pixel data, and RST resets it. These modules are 3.3 V parts; on a 5 V Uno, the data lines need a level shifter or series resistors, or the screen stays white.
A full screen is 153,600 bytes of pixels, so redrawing everything is slow on an 8-bit board. The fast way to work is to draw the static parts once and then repaint only the small rectangles that change.
| Library Manager name | Adafruit ILI9341 |
|---|---|
| Author | Adafruit |
| Include | #include <Adafruit_ILI9341.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | TFT display, 240x320 |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <Adafruit_ILI9341.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Adafruit ILI9341" by Adafruit from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add Adafruit ILI9341 to lib_deps in PlatformIO. Mokxi follows the calls of release 1.6.1, so a sketch written here builds there too.
What to know in the simulator: readcommand8() answers from the commands sent, as there is no MISO. The PyPortal鈥檚 parallel-bus constructor builds, and begin() says on Serial that the parallel bus is not simulated.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
Adafruit_ILI9341 tft(10, 9, 8)
CS, DC and RST pins on the hardware SPI bus. Pass -1 for RST if it is tied to the board鈥檚 reset.
tft.begin()
Starts SPI and sends the controller its set-up. Call it before any drawing.
tft.setRotation(3)
Landscape (1 or 3) or portrait (0 or 2). In landscape the screen is 320 wide and 240 tall.
tft.fillScreen(ILI9341_BLACK)
Paints the whole screen. ILI9341_RED, ILI9341_NAVY and the other ILI9341_ names are ready-made 16-bit colors.
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK)
Text color and the background behind each character, so changing numbers overwrite cleanly.
tft.setTextSize(3);
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setCursor(20, 100);
tft.print(count);tft.fillRect(x, y, w, h, color)
A filled rectangle from Adafruit GFX, the cheapest way to clear one area before redrawing it.
tft.drawRoundRect(x, y, w, h, 8, ILI9341_CYAN)
An outlined button shape with rounded corners; with fillRoundRect() and centered text it makes a touch button.
Example: Touch paint
On the Arduino Uno R3. It runs in the browser exactly as printed.
// Touch paint: draw on a 2.8 inch ILI9341 with its XPT2046 touch panel.
//
// display CS -> 10 DC -> 9 RST -> 8 MOSI -> 11 SCK -> 13 LED -> 5 V
// touch T_CS -> 7 T_CLK -> A2 T_DIN -> A0 T_DO -> A1
//
// Press on the picture while it runs, and drag.
//
// Two chips on one module, each an SPI device with its own chip select. They
// could share one bus, since each only listens while its own select is low;
// here the touch controller has a bus of its own on A0 to A2, an SPIClass
// made on those pins, so the two sets of wires never meet.
// Each reading is a control byte and sixteen clocks: the start bit, the
// channel, then twelve bits of result in bits 14 to 3 (the >> 3). Pressure is
// 4095 + Z1 - Z2, large for a press and near nothing for none.
//
// The readings are raw counts, about 200 at one edge of the picture and 3900
// at the other, so map() turns them into pixels. With the display and the
// touch at the same rotation, a bigger x is further right.
//
// The row of colors along the top is the palette: touch one to pick it.
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>
Adafruit_ILI9341 tft(10, 9, 8);
SPIClass touchBus(A2, A1, A0, 7); // SCK, MISO, MOSI, SS
XPT2046_Touchscreen ts(7);
const uint16_t PALETTE[] = {ILI9341_RED, ILI9341_YELLOW, ILI9341_GREEN,
ILI9341_CYAN, ILI9341_BLUE, ILI9341_WHITE};
const int SWATCH = 40;
uint16_t ink = ILI9341_YELLOW;
void setup() {
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
for (int i = 0; i < 6; i++) tft.fillRect(i * SWATCH, 0, SWATCH, 20, PALETTE[i]);
ts.begin(touchBus);
ts.setRotation(1);
}
void loop() {
if (!ts.touched()) return;
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());
if (y < 20) {
if (x >= 0 && x < 6 * SWATCH) ink = PALETTE[x / SWATCH];
return;
}
tft.fillRect(x - 2, y - 2, 5, 5, ink);
}Open it in the editor, wired and ready to run 路 Touch paint: the project page
Common errors and how to fix them
The screen lights up white and never shows anything
Usually the controller never got its set-up: CS or DC on the wrong pin, or 5 V logic on a 3.3 V module. Check the pins in the constructor, and level-shift SCK, MOSI, CS, DC and RST on a 5 V board.
Colors are wrong or the picture is mirrored
The panel may not be an ILI9341. Many similar-looking modules use an ST7789 or ILI9488; read the chip name on the listing and use the matching library, such as Adafruit ST7789 or TFT_eSPI.
Updating the screen takes most of a second
fillScreen() on every loop sends the whole frame. Draw the layout once in setup() and repaint only the rectangles with values that changed.
Projects that use Adafruit ILI9341
Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.
Try Adafruit ILI9341 without installing anything
Open the example, change the sketch, and keep your version in a free account.