Here is where the differences in the tri-color/monochrome and chipset/dimensions start mattering. Check carefully to make sure you are running the right example and creating the matching library type for your display or you won't see anything happen on the EPD (or the image may be really weird looking).

CircuitPython eInk displayio Library Installation

To use displayio, you will need to install the appropriate library for your display. 

First make sure you are running the latest version of Adafruit CircuitPython for your board. You will need the latest version of CircuitPython.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  The introduction guide has a great page on how to install the library bundle for both express and non-express boards.

You will need to copy the appropriate displayio driver from the bundle lib folder to a lib folder on your CIRCUITPY drive. The displayio driver contains the initialization codes specific to your display that are needed to for it to work. Since there is more than one driver, you will need to copy the correct file over. Here is a list of each of the displays and the correct driver for that display.

To use the eInk displays with displayio, you will need to use the latest version of CircuitPython and a board that can fit `displayio`. See the Support Matrix to determine if `displayio` is available on a given board: https://circuitpython.readthedocs.io/en/latest/shared-bindings/support_matrix.html

Adafruit_CircuitPython_SSD1675

The older 250x122 monochrome display with SSD1675 driver uses the Adafruit_CircuitPython_SSD1675 library. Copy the adafruit_ssd1675.mpy file from the bundle to the lib folder on your CIRCUITPY drive.

Front of E-Ink display with monochrome graphic and "2.13 inch E-Ink Monochrome" text
Easy e-paper finally comes to microcontrollers, with this breakout that's designed to make it a breeze to add a monochromatic eInk display. Chances are you've seen one of those...
E-Ink display connected to Feather, refreshing itself
Easy e-paper finally comes to your Feather, with this breakout that's designed to make it a breeze to add a monochrome eInk display. Chances are you've seen one of those...
If you are not sure whether you have an older or newer display, you can try both drivers and see which one works.

Adafruit_CircuitPython_IL0373

The 212x104 Monochrome Flexible display, older 212x104 Tri-Color FeatherWing, and older 212x104 Tri-Color breakout use the Adafruit_CircuitPython_ILI0373 library. Copy the adafruit_il0373.mpy file from the bundle to the lib folder on your CIRCUITPY drive.

Hands flexing a 2.13" Flexible Monochrome E-Ink display.
Woah, the cyber-future is here! Flexible E-Ink has been demo'd at high-tech events for years but now you can actually get your paws on it. This display is true E-Ink / E-Paper,...

Adafruit_CircuitPython_SSD1680

The newer 250x122 HD Tri-Color breakout display and 250x122 HD Tri-Color FeatherWing use the Adafruit_CircuitPython_SSD1680 library. Copy the adafruit_ssd1680.mpy file from the bundle to the lib folder on your CIRCUITPY drive.

The newer 250x122 monochrome display with SSD1680 driver and 250x122 Monochrome FeatherWing with SSD1680 driver use the Adafruit_CircuitPython_SSD1680 library as well. Copy the adafruit_ssd1680.mpy file from the bundle to the lib folder on your CIRCUITPY drive.

No modifications between the Tri-Color and Monochrome display initializers are necessary.

Video of a 2.13" tri-color eInk display assembled on a breadboard with jumper wires and a QT Py. Friendly snake in white-and-red, Blinka, appears on the display.
Easy e-paper finally comes to microcontrollers, with this breakout that's designed to make it a breeze to add a tri-color eInk display. Chances are you've seen one of those...
E-Ink display connected to Feather,  with image of friendly snake
Easy e-paper comes to your Feather, with this breakout that's designed to make it a breeze to add a tri-color eInk display. Chances are you've seen one of those new-fangled...

Image File

To show you how to use the eInk with displayio, we'll show you how to draw a bitmap onto it. First start by downloading display-ruler.bmp

Copy display-ruler.bmp into the root directory of your CIRCUITPY drive.

Monochrome Display Usage

Older 2.13" 250x122 Monochrome Breakout and FeatherWing

In the examples folder for your SSD1675 displayio driver, there should be a test for your display which we have listed here:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""Simple test script for 2.13" 250x122 monochrome display.

Supported products:
  * Adafruit 2.13" Monochrome ePaper Display Breakout
    * https://www.adafruit.com/product/4197
  """

import time
import board
import displayio
import adafruit_ssd1675

# Starting in CircuitPython 9.x fourwire will be a seperate internal library
# rather than a component of the displayio library
try:
    from fourwire import FourWire
except ImportError:
    from displayio import FourWire


displayio.release_displays()

# This pinout works on a Feather M4 and may need to be altered for other boards.
spi = board.SPI()  # Uses SCK and MOSI
epd_cs = board.D9
epd_dc = board.D10
epd_reset = board.D5
epd_busy = board.D6

display_bus = FourWire(
    spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000
)
time.sleep(1)

display = adafruit_ssd1675.SSD1675(
    display_bus, width=250, height=122, rotation=270, busy_pin=epd_busy
)

g = displayio.Group()

with open("/display-ruler.bmp", "rb") as f:
    pic = displayio.OnDiskBitmap(f)
    # CircuitPython 6 & 7 compatible
    t = displayio.TileGrid(
        pic, pixel_shader=getattr(pic, "pixel_shader", displayio.ColorConverter())
    )
    # CircuitPython 7 compatible only
    # t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader)
    g.append(t)

    display.root_group = g

    display.refresh()

    print("refreshed")

    time.sleep(120)

Newer 2.13" 250x122 Monochrome Breakout and FeatherWing

In the examples folder for your SSD1680 displayio driver, there should be a test for your display which we have listed here:

# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense

"""Simple test script for 2.13" 250x122 tri-color display.
Supported products:
  * Adafruit 2.13" Tri-Color eInk Display Breakout
    * https://www.adafruit.com/product/4947
  * Adafruit 2.13" Tri-Color eInk Display FeatherWing
    * https://www.adafruit.com/product/4814
  * Adafruit 2.13" Mono eInk Display FeatherWing
    * https://www.adafruit.com/product/4195


"""

import time
import board
import displayio
import fourwire
import adafruit_ssd1680

displayio.release_displays()

# This pinout works on a Metro M4 and may need to be altered for other boards.
spi = board.SPI()  # Uses SCK and MOSI
epd_cs = board.D9
epd_dc = board.D10
epd_reset = board.D8  # Set to None for FeatherWing
epd_busy = board.D7  # Set to None for FeatherWing

display_bus = fourwire.FourWire(
    spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000
)
time.sleep(1)

# For issues with display not updating top/bottom rows correctly set colstart to 8
display = adafruit_ssd1680.SSD1680(
    display_bus,
    width=250,
    height=122,
    busy_pin=epd_busy,
    highlight_color=0xFF0000,
    rotation=270,
)


g = displayio.Group()

with open("/display-ruler.bmp", "rb") as f:
    pic = displayio.OnDiskBitmap(f)
    t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader)
    g.append(t)

    display.root_group = g

    display.refresh()

    print("refreshed")

    time.sleep(display.time_to_refresh + 5)
    # Always refresh a little longer. It's not a problem to refresh
    # a few seconds more, but it's terrible to refresh too early
    # (the display will throw an exception when if the refresh
    # is too soon)
    print("waited correct time")


# Keep the display the same
while True:
    time.sleep(10)

2.13" 212x104 Monochrome Flexible Display

In the examples folder for your IL0373 displayio driver, there should be a test for your display which we have listed here:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""Simple test script for 2.13" 212x104 monochrome display.

Supported products:
  * Adafruit Flexible 2.13" Monochrome
    * https://www.adafruit.com/product/4243
  """

import time
import board
import displayio
import fourwire
import adafruit_il0373

displayio.release_displays()

# This pinout works on a Feather M4 and may need to be altered for other boards.
spi = board.SPI()  # Uses SCK and MOSI
epd_cs = board.D9
epd_dc = board.D10
epd_reset = board.D5
epd_busy = board.D6

display_bus = fourwire.FourWire(
    spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000
)
time.sleep(1)

display = adafruit_il0373.IL0373(
    display_bus, width=212, height=104, rotation=90, busy_pin=epd_busy, swap_rams=True
)

g = displayio.Group()

with open("/display-ruler.bmp", "rb") as f:
    pic = displayio.OnDiskBitmap(f)
    # CircuitPython 6 & 7 compatible
    t = displayio.TileGrid(
        pic, pixel_shader=getattr(pic, "pixel_shader", displayio.ColorConverter())
    )
    # CircuitPython 7 compatible only
    # t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader)
    g.append(t)

    display.root_group = g

    display.refresh()

    time.sleep(120)

Configure and Upload

You will want to change the epd_reset and epd_busy to the correct values. If you are using the 2.13" Monochrome Breakout or the eInk Breakout Friend and wired it up as shown on the Wiring page, you will want to change it to these values:

epd_reset = board.D8
epd_busy = board.D7

If you are using the 2.13" Monochrome FeatherWing or the eInk FeatherWing Friend, you will want to change both of these values to None:

epd_reset = None
epd_busy = None

Save it to your CIRCUITPY drive as code.py and it should automatically run. Your display will look something like this:

Tri-Color Display Usage

2.13" 250x122 HD Tri-Color Breakout and FeatherWing

In the examples folder for your SSD1680 displayio driver, there should be a test for your display which we have listed here:

# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense

"""Simple test script for 2.13" 250x122 tri-color display.
Supported products:
  * Adafruit 2.13" Tri-Color eInk Display Breakout
    * https://www.adafruit.com/product/4947
  * Adafruit 2.13" Tri-Color eInk Display FeatherWing
    * https://www.adafruit.com/product/4814
  * Adafruit 2.13" Mono eInk Display FeatherWing
    * https://www.adafruit.com/product/4195


"""

import time
import board
import displayio
import fourwire
import adafruit_ssd1680

displayio.release_displays()

# This pinout works on a Metro M4 and may need to be altered for other boards.
spi = board.SPI()  # Uses SCK and MOSI
epd_cs = board.D9
epd_dc = board.D10
epd_reset = board.D8  # Set to None for FeatherWing
epd_busy = board.D7  # Set to None for FeatherWing

display_bus = fourwire.FourWire(
    spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000
)
time.sleep(1)

# For issues with display not updating top/bottom rows correctly set colstart to 8
display = adafruit_ssd1680.SSD1680(
    display_bus,
    width=250,
    height=122,
    busy_pin=epd_busy,
    highlight_color=0xFF0000,
    rotation=270,
)


g = displayio.Group()

with open("/display-ruler.bmp", "rb") as f:
    pic = displayio.OnDiskBitmap(f)
    t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader)
    g.append(t)

    display.root_group = g

    display.refresh()

    print("refreshed")

    time.sleep(display.time_to_refresh + 5)
    # Always refresh a little longer. It's not a problem to refresh
    # a few seconds more, but it's terrible to refresh too early
    # (the display will throw an exception when if the refresh
    # is too soon)
    print("waited correct time")


# Keep the display the same
while True:
    time.sleep(10)

 2.13" 212x104 Older Standard Tri-Color Breakout and FeatherWing

In the examples folder for your IL0373 displayio driver, there should be a test for your display which we have listed here:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""Simple test script for Adafruit 2.13" 212x104 tri-color display
Supported products:
  * Adafruit 2.13" Tri-Color Display Breakout
  * https://www.adafruit.com/product/4086 (breakout) or
  * https://www.adafruit.com/product/4128 (FeatherWing)
"""

import time
import board
import displayio
import fourwire
import adafruit_il0373

# Used to ensure the display is free in CircuitPython
displayio.release_displays()

# Define the pins needed for display use
# This pinout is for a Feather M4 and may be different for other boards
spi = board.SPI()  # Uses SCK and MOSI
epd_cs = board.D9
epd_dc = board.D10
epd_reset = board.D5
epd_busy = board.D6

# Create the displayio connection to the display pins
display_bus = fourwire.FourWire(
    spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000
)
time.sleep(1)  # Wait a bit

# Create the display object - the third color is red (0xff0000)
display = adafruit_il0373.IL0373(
    display_bus,
    width=212,
    height=104,
    rotation=90,
    busy_pin=epd_busy,
    highlight_color=0xFF0000,
)

# Create a display group for our screen objects
g = displayio.Group()

# Display a ruler graphic from the root directory of the CIRCUITPY drive
with open("/display-ruler.bmp", "rb") as f:
    pic = displayio.OnDiskBitmap(f)
    # Create a Tilegrid with the bitmap and put in the displayio group
    # CircuitPython 6 & 7 compatible
    t = displayio.TileGrid(
        pic, pixel_shader=getattr(pic, "pixel_shader", displayio.ColorConverter())
    )
    # CircuitPython 7 compatible only
    # t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader)
    g.append(t)

    # Place the display group on the screen
    display.root_group = g

    # Refresh the display to have it actually show the image
    # NOTE: Do not refresh eInk displays sooner than 180 seconds
    display.refresh()
    print("refreshed")

    time.sleep(180)

You will want to change the epd_reset and epd_busy to the correct values. If you wired it up as shown on the Wiring page, you will want to change it to these values:

epd_reset = board.D8
epd_busy = board.D7

Save it to your CIRCUITPY drive as code.py and it should automatically run. Your display will look something like this:

This guide was first published on Mar 15, 2021. It was last updated on Nov 28, 2023.

This page (CircuitPython Usage) was last updated on Nov 28, 2023.

Text editor powered by tinymce.