You can use this technique with any PiTFT, from the 240x135 mini PiTFT up to the 320x480. It isn't as fast as the kernel module support version but it'll work no matter what kernel/OS/version/etc and so is a lot less painful.
This is not a kernel driver that will let you have the console appear on the TFT. However, this is handy when you can't install an fbtft driver, and want to use the TFT purely from 'user Python' code!
It's easy to use RGB TFT display breakouts with Python and the Adafruit CircuitPython RGB Display module. This module allows you to write Python code to control the display directly. There is a fair amount of initial setup required though, which this page covers.
Install System Packages
The RGB TFT Python support relies of several operating system packages. To make sure those are installed, run the following:
sudo apt install -y fonts-dejavu python3-pil python3-numpy
This will install:
- DejaVu font - May already be installed. This font is used by the code examples.
- PIL/Pillow - The Python Imaging Library. Provides the basic graphical support.
- NumPy - Fancy math stuff that helps the library run faster.
Blinka Setup
There's enough to this step that it is covered in a separate guide. So be sure to go through the Blinka Setup guide first:
The rest of these installation steps assume you have gone through the Blinka Setup guide and have the Blinka virtual environment activated.
Make sure the Blinka virtual environment is activated before proceeding.
Install Python RGB Display Library
OK, finally, install the actual Python RGB display library with the following:
pip3 install adafruit-circuitpython-rgb-display
If using a Pi5, also run this command after the install is complete (this is a work around hack):
pip3 uninstall RPi.GPIO
Reconfigure Chip Select Pins
The TFT Bonnet uses the CE0 pin for SPI chip select. There's a good chance the default operating system install will have control of that pin. We want to control it ourselves, via the CircuitPython library. Therefore, we need to disable the operating system's usage of the CE0 pin. More info here:
To disable the CE0 pin, run the following commands:
pip3 install --upgrade adafruit-python-shell click wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/main/raspi-spi-reassign.py sudo -E env PATH=$PATH python3 raspi-spi-reassign.py --ce0=disabled
This will require a reboot after the script runs. Don't forget to re-enable the Blinka virtual environment after rebooting.
This button test demo will test to make sure you have everything setup correctly. Save the file to your Raspberry Pi in your home directory as rgb_display_pillow_bonnet_buttons.py.
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT # Copyright (c) 2017 Adafruit Industries # Author: James DeVito # Ported to RGB Display by Melissa LeBlanc-Williams # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # This example is for use on (Linux) computers that are using CPython with # Adafruit Blinka to support CircuitPython libraries. CircuitPython does # not support PIL/pillow (python imaging library)! """ This example is for use on (Linux) computers that are using CPython with Adafruit Blinka to support CircuitPython libraries. CircuitPython does not support PIL/pillow (python imaging library)! """ import time import random from colorsys import hsv_to_rgb import board from digitalio import DigitalInOut, Direction from PIL import Image, ImageDraw, ImageFont from adafruit_rgb_display import st7789 # Create the display cs_pin = DigitalInOut(board.CE0) dc_pin = DigitalInOut(board.D25) reset_pin = DigitalInOut(board.D24) BAUDRATE = 24000000 spi = board.SPI() disp = st7789.ST7789( spi, height=240, y_offset=80, rotation=180, cs=cs_pin, dc=dc_pin, rst=reset_pin, baudrate=BAUDRATE, ) # Input pins: button_A = DigitalInOut(board.D5) button_A.direction = Direction.INPUT button_B = DigitalInOut(board.D6) button_B.direction = Direction.INPUT button_L = DigitalInOut(board.D27) button_L.direction = Direction.INPUT button_R = DigitalInOut(board.D23) button_R.direction = Direction.INPUT button_U = DigitalInOut(board.D17) button_U.direction = Direction.INPUT button_D = DigitalInOut(board.D22) button_D.direction = Direction.INPUT button_C = DigitalInOut(board.D4) button_C.direction = Direction.INPUT # Turn on the Backlight backlight = DigitalInOut(board.D26) backlight.switch_to_output() backlight.value = True # Create blank image for drawing. # Make sure to create image with mode 'RGB' for color. width = disp.width height = disp.height image = Image.new("RGB", (width, height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) # Clear display. draw.rectangle((0, 0, width, height), outline=0, fill=(255, 0, 0)) disp.image(image) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) # Draw a black filled box to clear the image. draw.rectangle((0, 0, width, height), outline=0, fill=0) udlr_fill = "#00FF00" udlr_outline = "#00FFFF" button_fill = "#FF00FF" button_outline = "#FFFFFF" fnt = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 30) while True: up_fill = 0 if not button_U.value: # up pressed up_fill = udlr_fill draw.polygon( [(40, 40), (60, 4), (80, 40)], outline=udlr_outline, fill=up_fill ) # Up down_fill = 0 if not button_D.value: # down pressed down_fill = udlr_fill draw.polygon( [(60, 120), (80, 84), (40, 84)], outline=udlr_outline, fill=down_fill ) # down left_fill = 0 if not button_L.value: # left pressed left_fill = udlr_fill draw.polygon( [(0, 60), (36, 42), (36, 81)], outline=udlr_outline, fill=left_fill ) # left right_fill = 0 if not button_R.value: # right pressed right_fill = udlr_fill draw.polygon( [(120, 60), (84, 42), (84, 82)], outline=udlr_outline, fill=right_fill ) # right center_fill = 0 if not button_C.value: # center pressed center_fill = button_fill draw.rectangle((40, 44, 80, 80), outline=button_outline, fill=center_fill) # center A_fill = 0 if not button_A.value: # left pressed A_fill = button_fill draw.ellipse((140, 80, 180, 120), outline=button_outline, fill=A_fill) # A button B_fill = 0 if not button_B.value: # left pressed B_fill = button_fill draw.ellipse((190, 40, 230, 80), outline=button_outline, fill=B_fill) # B button # make a random color and print text rcolor = tuple(int(x * 255) for x in hsv_to_rgb(random.random(), 1, 1)) draw.text((20, 150), "Hello World", font=fnt, fill=rcolor) rcolor = tuple(int(x * 255) for x in hsv_to_rgb(random.random(), 1, 1)) draw.text((20, 180), "Hello World", font=fnt, fill=rcolor) rcolor = tuple(int(x * 255) for x in hsv_to_rgb(random.random(), 1, 1)) draw.text((20, 210), "Hello World", font=fnt, fill=rcolor) # Display the Image disp.image(image) time.sleep(0.01)
Run it with this command:
python3 rgb_display_pillow_bonnet_buttons.py
Once it is running, push the buttons. The corresponding buttons should light up on the display.
Page last edited January 21, 2025
Text editor powered by tinymce.