TFT Display

Let's draw to a display!

Here we'll use SPI to talk to a TFT display. And since we are on a powerful desktop PC, we can even use Pillow (PIL) to do the graphical heavy lifting.

Connect the Display

Here is the wiring diagram for connecting a 2.4" TFT LCD display via SPI. We aren't using touch, so don't need to worry about those pins.

Install Pillow/PIL

We'll just point you to the official Pillow/PIL page so you can follow the install instruction there.

You should be able to just use pip though.

Install CircuitPython RGB Display Library

This library provides support for the TFT display. To install, run:

Download: file
sudo pip3 install adafruit-circuitpython-rgb-display

Example Image

In this example, we'll load and display an image. Download the image below and save it to the same directory where the Python code will be stored. Make sure it is named blinka.bmp.

The Code

And here is the complete code listing to load and display the BMP file.

Download: file
import board
import digitalio
import adafruit_rgb_display.ili9341 as ili9341
from PIL import Image

# Setup display
cs_pin = digitalio.DigitalInOut(board.C0)
dc_pin = digitalio.DigitalInOut(board.C1)
disp = ili9341.ILI9341(board.SPI(), cs=cs_pin, dc=dc_pin, baudrate=64000000)

# Load image and convert to RGB
image ='blinka.bmp').convert('RGB')

# Display it (rotated by 90 deg)
disp.image(image, 90)

Save the above with a filename like and then run it with:

Download: file

and boom! you should get a happy little Blinka showing up on your display.

Fancier Demo for Linux

There's a lot of power in Pillow/PIL. It can do more than just load and display images. Here's another example that creates a Draw object, uses a TTF font, and then grabs some stats from the PC and displays them.

# Quick test of TFT FeatherWing (ILI9341) with Feather M0 or M4
# Will fill the TFT black and put a red pixel in the center, wait 2 seconds,
# then fill the screen blue (with no pixel), wait 2 seconds, and repeat.
import time
import random
import busio
import digitalio
import board

from adafruit_rgb_display.rgb import color565
import adafruit_rgb_display.ili9341 as ili9341

# Configuratoin for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.D9)
dc_pin = digitalio.DigitalInOut(board.D10)

# Config for display baudrate (default max is 24mhz):
BAUDRATE = 24000000

# Setup SPI bus using hardware SPI:
spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# Create the ILI9341 display:
display = ili9341.ILI9341(spi, cs=cs_pin, dc=dc_pin, baudrate=BAUDRATE)

# Main loop:
while True:
    # Fill the screen red, green, blue, then black:
    for color in ((255, 0, 0), (0, 255, 0), (0, 0, 255)):
    # Clear the display
    # Draw a red pixel in the center.
    display.pixel(display.width//2, display.height//2, color565(255, 0, 0))
    # Pause 2 seconds.
    # Clear the screen a random color
    display.fill(color565(random.randint(0, 255),
                          random.randint(0, 255),
                          random.randint(0, 255)))
    # Pause 2 seconds.

The example uses a ST7789 based TFT, so if you are using the same 2.4" TFT (ILI9341) from above, you'll need to change those lines of code to match. Use the image load example above for reference. You'll need to change the display import to:

Download: file
import adafruit_rgb_display.ili9341 as ili9341

and the display setup to:

Download: file
# Configuration for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.C0)
dc_pin = digitalio.DigitalInOut(board.C1)
reset_pin = None

# Config for display baudrate (default max is 24mhz):
BAUDRATE = 64000000

# Setup SPI bus using hardware SPI:
spi = board.SPI()

# Create the ST7789 display:
disp = ili9341.ILI9341(spi, cs=cs_pin, dc=dc_pin, rst=reset_pin, baudrate=BAUDRATE,
                        width=240, height=320)

With those changes in place, you should be able to run it and get some system stats showing up.

And it will update in near real-time.

This guide was first published on Sep 29, 2019. It was last updated on Sep 29, 2019.
This page (TFT Display) was last updated on Aug 06, 2020.