CircuitPython Hardware ILI9341 TFT & FeatherWing
2017-12-13 | By Adafruit Industries
License: See Original Project Adafruit Feather
Courtesy of Adafruit
Guide by Tony DiCola
Overview
Note the video above was made showing the MicroPython version of this library. Follow the guide to see both CircuitPython and MicroPython versions of the ILI9341 library.
Small TFT displays are a great way to add graphics to your projects. These are like tiny little LCD monitors that you can drive with a simple SPI serial interface. You can even use these displays in CircuitPython and MicroPython using a module from Adafruit! This module allows you to do basic drawing like putting pixels and filling rectangles on TFT displays like the TFT FeatherWing. You can start to explore a fun world of Python and graphical TFT displays!
This guide explores how to use ILI9341/ILI9340 TFT displays with CircuitPython and MicroPython. Note that right now drawing support for these displays is limited to basic pixel and rectangle drawing commands. You can use another library to draw basic graphics or to draw text. In addition, the touchscreens commonly found on these small TFT displays are not currently supported by the Python module. In the future, a touchscreen module might be available, but for now these displays are only for viewing graphics.
Hardware
Parts
You'll need the following parts to follow this guide:
CircuitPython board
This guide focuses on the ESP8266 and Feather M0/SAMD21-based boards, but any CircuitPython board that supports SPI should work.
If your board doesn't come with CircuitPython running on it already then check out your board's guide for how to load CircuitPython firmware. For example the Feather M0 express guide is a good reference.
ILI9341/9340 TFT Display Breakout or FeatherWing
If you're using a Feather the TFT FeatherWing is the perfect option that easily connects to the Feather. For other boards, you'll need an ILI9341 or ILI9340 display breakout, like this large 2.8" TFT display breakout. ILI9340 displays like the 2.2" TFT breakout or 2.4" TFT breakout should work too. Make sure the display you're using has the ILI9341 or ILI9340 driver chip!
Breadboard, jumper wires, and soldering tools
If you aren't using a Feather and FeatherWing you'll need a breadboard and jumper wires to connect the components.
You'll need to solder headers to the boards. Check out the guide to excellent soldering if you're new to soldering.
Make sure to follow the board and TFT FeatherWing or 2.8" TFT display breakout guide to assemble and test the hardware before continuing!
Wiring
If you're using a TFT FeatherWing and Feather just slide the wing onto the Feather board and you're all set! The FeatherWing will automatically be connected to the board using its SPI connection.
If you're using a TFT display breakout you'll need to connect its power, ground, and SPI connections to the board. For example, the wiring for a 2.8" TFT breakout to Feather HUZZAH ESP8266 might look like:
- Board SCK / SPI clock to Display CLK / SPI clock.
- Board MO / MOSI / data output to Display MOSI / data input.
- Board GPIO 0 (or any other GPIO pin) to Display CS / chip select.
- Board GPIO 15 (or any other GPIO pin) to Display DC / data/command.
- Board 3.3V power to Display VIN / voltage input.
- Board GND / ground to Display GND / ground.
- Display 3.3V output to IM3, IM2, and IM1 (but not IM0!) pins. This configures the breakout to use its SPI interface. See the breakout guide for details on soldering closed these connections to make the SPI interface the default.
CircuitPython
Adafruit CircuitPython Module Install
To use the TFT display with your Adafruit CircuitPython board you'll need to install the Adafruit_CircuitPython_RGB_Display module on your board. Remember this module is for Adafruit CircuitPython firmware and not MicroPython.org firmware!
Bundle Install
For express boards that have extra flash storage, like the Feather/Metro M0 express and Circuit Playground express, you can easily install the necessary libraries with Adafruit's CircuitPython bundle. This is an all-in-one package that includes the necessary libraries to use the ILI9341 display with CircuitPython. To install the bundle follow the steps in your board's guide.
Remember for non-express boards like the Trinket M0, Gemma M0, and Feather/Metro M0 basic you'll need to manually install the necessary libraries from the bundle:
- adafruit_rgb_display
- adafruit_bus_device
- adafruit_register
If your board supports USB mass storage, like the M0-based boards, then simply drag the files to the board's file system. Note on boards without external SPI flash, like a Feather M0 or Trinket/Gemma M0, you might run into issues on Mac OSX with hidden files taking up too much space when drag and drop copying, see this page for a workaround.
If your board doesn't support USB mass storage, like the ESP8266, then use a tool like ampy to copy the file to the board. You can use the latest version of ampy and its new directory copy command to easily move module directories to the board.
Furthermore, CircuitPython for M0 boards after version 0.8.1 do not have the framebuf module built in to save flash space. So, please download and install the pure Python implementation of framebuf and copy it to lib folder of the board as well.
Before continuing, make sure your board's root filesystem has the adafruit_rgb_display, adafruit_bus_device, and adafruit_register folders/modules copied over.
Usage
The following section will show how to control the LED backpack from the board's Python prompt / REPL. You'll walk through how to control the TFT display and learn how to use the CircuitPython module built for the display. As a reference, be sure to see the micropython-adafruit-rgb-display module documentation too.
First connect to the board's serial REPL so you are at the CircuitPython >>> prompt.
SPI Initialization
On CircuitPython the SPI bus must be initialized before the display can be used by your code. Run the following code to import the necessary modules and initialize the SPI bus:
import board
import busio
import digitalio
spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# For the ESP8266
cs = digitalio.DigitalInOut(board.GPIO0)
dc = digitalio.DigitalInOut(board.GPIO15)
# For the Feather M0s
#cs = digitalio.DigitalInOut(board.D9)
#dc = digitalio.DigitalInOut(board.D10)
These lines create the SPI bus interface and two digital inputs/outputs for the chip select and data/command lines connected to the display. Notice that the pin numbers might be different depending on your board and how it's wired. Read the comments above and pick the correct two cs and dc lines to run for your setup.
Display Initialization
Next, to import the display library and initialize it run the following code:
from adafruit_rgb_display import ili9341, color565
display = ili9341.ILI9341(spi, cs=cs, dc=dc)
When creating the display instance of the ILI9341 class you'll need to know which pins are connected to the display's CS, DC, and optionally RST or reset line. For the TFT FeatherWing see its guide for details on these pin connections.
The CS and DC parameters to the ILI9341 class initializer are required and should be a pin from the board module. In CircuitPython they are DigitalInOut objects instead of pins directly (like GPIO0) so that other types of GPIO can be used such as GPIO expanders.
There are a few optional keyword arguments you can specify too:
- rst - This is a GPIO pin connected to the RST or reset line on the display. The default for this is to not be specified and reset is not used.
- width - The width of the display in pixels, the default is 240.
- height - The height of the display in pixels, the default is 320.
Drawing
Once the display is initialized you're ready to perform basic fill and pixel drawing. First to fill the display with a solid color use the fill function:
display.fill(color565(255, 0, 0))
You should see the display fill entirely with a solid red color after running the command above.
Notice how the color565 function is called to get a color that's passed to the fill function. This color565 function takes in the red, green, and blue color component values which should range from 0 (lowest intensity) to 255 (highest intensity). Try filling the display with different color values!
To clear the display back to black, fill it with a zero color value:
display.fill(0)
You can draw individual pixels with the pixel function. For example, to draw a white pixel at the origin position 0, 0:
display.pixel(0, 0, color565(255, 255, 255))
Or to draw a pixel at the opposite corner at position 239, 319:
display.pixel(239, 319, color565(255, 255, 255))
The pixel function takes the following parameters:
- X position of the pixel to draw.
- Y position of the pixel to draw.
- Color of the pixel. Use the ili9341.color565 function to generate this color value from red, green, blue component values.
In addition to pixel drawing there's a filled rectangle drawing command called fill_rectangle. For example, to draw a blue box in one quadrant of the screen run:
display.fill_rectangle(0, 0, 120, 170, color565(0, 0, 255))
The fill_rectangle function takes the following parameters:
- X position of the rectangle upper left corner.
- Y position of the rectangle upper left corner.
- Width of the rectangle in pixels.
- Height of the rectangle in pixels.
- Color of the rectangle. Again, use the ili9341.color565 function to generate this value.
That's all there is to drawing on the ILI9341 display with CircuitPython! Right now, only basic fill, pixel, and filled rectangle drawing commands are supported. However, since this is a pixel-based display you can also draw text with the bitmap font library. There's even a basic graphics library to draw lines and other shapes!
MicroPython
Note this page describes how to use a MicroPython.org version of this library with MicroPython boards. Skip back to the previous page if you're using a CircuitPython board like the Feather M0 express!
In addition to CircuitPython, there's an older MicroPython version of the TFT library that you can use with some MicroPython boards. Before you get started it will help to be familiar with these guides for working with MicroPython:
- MicroPython Basics: What is MicroPython?
- MicroPython Basics: How to Load MicroPython on a Board
- MicroPython Basics: Load Files & Run Code
See all the MicroPython guides in the learning system for more information.
MicroPython Module Install
To use the TFT display with your MicroPython board you'll need to install the micropython-adafruit-rgb-display MicroPython module on your board. Remember this module is for MicroPython.org firmware and not Adafruit CircuitPython!
First make sure you are running the latest version of MicroPython for your board. If you're using the ESP8266 MicroPython port you must be running version 1.8.5 or higher as earlier versions do not support using .mpy modules as shown in this guide.
Next download the latest ili9341.mpy and rgb.mpy file from the releases page of the micropython-adafruit-rgb-display GitHub repository and use a tool like ampy to copy the files to the board.
Usage
The following section will show how to control the ILI9341 display from the board's Python prompt / REPL. First connect to the board's serial REPL so you are at the MicroPython >>> prompt.
SPI Initialization
On MicroPython.org firmware which uses the machine API you can initialize SPI like the MicroPython SPI guide mentions. For example, on the ESP8266 with TFT FeatherWing you can run:
import machine
spi = machine.SPI(1, baudrate=32000000)
Notice how the baudrate is specifying the SPI bus clock speed at 32mhz. This means pixel data will be sent very quickly to the display--much quicker than a software SPI interface. These displays can actually run up to about 64mhz but the ESP8266 SPI hardware can't support that fast of a speed!
Display Initialization
Next to import the display library and initialize it run the following code:
import ili9341
display = ili9341.ILI9341(spi, cs=machine.Pin(0), dc=machine.Pin(15))
When creating the display instance of the ILI9341 class you'll need to know which pins are connected to the display's CS, DC, and optionally RST or reset line. For the TFT FeatherWing see its guide for details on these pin connections.
The CS and DC parameters to the ILI9341 class initializer are required and should be a pin instance. There are a few optional keyword arguments you can specify too:
- rst - This is a GPIO pin connected to the RST or reset line on the display. The default for this is to not be specified and reset is not used.
- width - The width of the display in pixels, the default is 240.
- height - The height of the display in pixels, the default is 320.
Drawing
After initializing SPI and the display you're ready to start drawing on it. The usage of the drawing library is exactly the same as with CircuitPython so check out the CircuitPython drawing information--the same code will work on MicroPython too!
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum