Example: A Single Bitmap

The first example reads a bitmap image placed on the board's CIRCUITPY drive and displays it on the eInk display.

Image

The image used in this example is a CircuitPython text image which shows various elements. You can download it by clicking the green button below.

For making your own graphic that can display decently on the three colors available on these displays, see the guide Preparing Graphics for E-Ink Displays.

If the picture is larger than the display width and height, the rest will truncate and not be displayed. It is suggested that you scale the image in an image editor prior to use as the code will not scale a bitmap.

Scale the bitmap you want to use to your display width and height in an image editor and dither or otherwise use only black/white/red. The code cannot perform image scaling on bitmap files.

Code

The code below will take a bitmap placed on the board's flash drive (in the CIRCUITPY root directory) and display it on the eInk display. See the comments in the code for how each step contributes to the process.

Please select the code specific to your display and microcontroller as the two code blocks below are not interchangeable for both sets of hardware. The examples are nearly identical though.

2.13" eInk FeatherWing Example

The pins reflect the combination of the FeatherWing eInk display and a Feather M4. It also has the pixel dimensions for the 2.13" display.

"""
  Simple test script for 2.7" 264x176 Tri-Color display shield
  Supported products:
  * Adafruit 2.7" Tri-Color ePaper Display Shield
    https://www.adafruit.com/product/4229

  This program only requires the adafruit_il91874 library in /lib
  for CircuitPython 5.0 and above which has displayio support.
"""

import time
import board
import displayio
import adafruit_il91874

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

# Define the pins needed for display use on the Metro
spi = board.SPI()
epd_cs = board.D10
epd_dc = board.D9

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

# Create the display object - the third color is red (0xff0000)
display = adafruit_il91874.IL91874(
    display_bus, width=264, height=176, highlight_color=0xFF0000, rotation=90
)

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

# Display a ruler graphic from the root directory of the CIRCUITPY drive
f = open("/display-ruler.bmp", "rb")

pic = displayio.OnDiskBitmap(f)
# Create a Tilegrid with the bitmap and put in the displayio group
t = displayio.TileGrid(pic, pixel_shader=displayio.ColorConverter())
g.append(t)

# Place the display group on the screen (does not refresh)
display.show(g)

# Show the image on the display
display.refresh()

print("refreshed")

# Do Not refresh the screen more often than every 180 seconds
#   for eInk displays! Rapid refreshes will damage the panel.
time.sleep(180)

2.7" eInk Shield Example

The pins reflect the combination of the shield eInk display and a Metro M4. It also has the pixel dimensions of the 2.7" display.

"""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 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 = displayio.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
f = open("/display-ruler.bmp", "rb")

pic = displayio.OnDiskBitmap(f)
# Create a Tilegrid with the bitmap and put in the displayio group
t = displayio.TileGrid(pic, pixel_shader=displayio.ColorConverter())
g.append(t)

# Place the display group on the screen
display.show(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)

Code Review

For an overview of using displayio for displays with CircuitPython, the excellent guide CircuitPython Display Support Using displayio is your first stop. If you would like a deeper dive into the model used for displays, refer to this guide.

Adafruit suggests using the displayio.release_displays function before looking to execute additional code to ensure displays connected to the hardware are released by CircuitPython.

Next is to let the microcontroller know which pins are used on the display. The pins used are very display dependent, it is suggested the guide on the display be referred to for known a known, working configuration prior to looking to change things up. displayio.FourWire sets up the displayio connection to the display bus.

With the bus, the program establishes the connection to the display driver. The size of the display (width and height), the orientation (rotation), busy pin, and the highlight color are given. For this tri-color display, red (0xff0000) is specified.

The rest of the code follows the standard displayio display setup and use:

  • Create a display group
  • Open a bitmap to put on the display
  • Create a bitmap object
  • Create a TileGrid to put objects in with the bitmap and append the tile group to the display group
  • Show the display on the screen
  • Refresh the screen

Finally the program waits at least 3 minutes. Then the program will complete and go to the REPL. If the bitmap should stay on the screen, add while True: and pass statements at the end of the program.

This guide was first published on Nov 13, 2019. It was last updated on Nov 13, 2019.
This page (Example: A Single Bitmap) was last updated on Jul 14, 2020.