The final example displays text over a bitmap on the eInk display, making a name badge useful for gatherings or conferences.
Images
This example uses a square picture file in BMP format to display on the left side of the display. It could be someone's picture, a logo, or other art.
For using the 2.13" display with a height of 104 pixels, make your image 104x104.
For using the 2.7" display with a height of 176 pixels, make your image 176x176.
As the eInk display can only use 3 colors, see the companion guide Preparing Graphics for E-Ink Displays. You may have to play with images to see how they might display best on your chosen display.
Here are sample pictures used with the examples. For the 2.13" display, use the smaller picture and for the 2.7" shield, use the larger picture. Copy the image to the board's CIRCUITPY drive as picture.bmp.
Code
The code below will display a square picture on the left and use the internal terminalio
font to place two small lines of text on the right of the eInk display. You can set the foreground and background color. See the comments 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.
# SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries # # SPDX-License-Identifier: MIT """ Simple badge 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) This program requires the adafruit_il0373 library and the adafruit_display_text library in the CIRCUITPY /lib folder for CircuitPython 5.0 and above which has displayio support. """ import time import board import displayio import adafruit_il0373 import terminalio from adafruit_display_text import label BLACK = 0x000000 WHITE = 0xFFFFFF RED = 0xFF0000 # Change text colors, choose from the following values: # BLACK, RED, WHITE TEXT_COLOR = BLACK BACKGROUND_COLOR = WHITE # 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 DISPLAY_WIDTH = 212 DISPLAY_HEIGHT = 104 # Create the display object - the third color is red (0xff0000) display = adafruit_il0373.IL0373(display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, rotation=90, busy_pin=epd_busy, highlight_color=0xff0000) # Create a display group for our screen objects g = displayio.Group() # Set a background background_bitmap = displayio.Bitmap(DISPLAY_WIDTH, DISPLAY_HEIGHT, 1) # Map colors in a palette palette = displayio.Palette(1) palette[0] = BACKGROUND_COLOR # Put the background into the display group bg_sprite = displayio.TileGrid(background_bitmap, pixel_shader=palette, x=0, y=0) g.append(bg_sprite) # Display a picture from the root directory of the CIRCUITPY drive # Picture should be HEIGHTxHEIGHT square ideally for a portrait # But could be the entire WIDTHxHEIGHT for a non-portrait filename = "/picture.bmp" # Create a Tilegrid with the bitmap and put in the displayio group # CircuitPython 6 & 7 compatible pic = displayio.OnDiskBitmap(open(filename, "rb")) t = displayio.TileGrid( pic, pixel_shader=getattr(pic, 'pixel_shader', displayio.ColorConverter()) ) g.append(t) # # CircuitPython 7+ compatible # pic = displayio.OnDiskBitmap(filename) # t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader) # g.append(t) # Draw simple text using the built-in font into a displayio group # For smaller text, change scale=2 to scale=1 text_group = displayio.Group(scale=2, x=DISPLAY_HEIGHT + 10, y=int(DISPLAY_HEIGHT/2) - 13) first_name = "Limor" text_area = label.Label(terminalio.FONT, text=first_name, color=TEXT_COLOR) text_group.append(text_area) # Add this text to the text group g.append(text_group) # Draw simple text using the built-in font into a displayio group text_group = displayio.Group(scale=2, x=DISPLAY_HEIGHT + 10, y=int(DISPLAY_HEIGHT/2) + 13) last_name = "Ladyada" text_area = label.Label(terminalio.FONT, text=last_name, color=TEXT_COLOR) text_group.append(text_area) # Add this text to the text group g.append(text_group) # Place the display group on the screen display.show(g) # Refresh the display to have it actually show # NOTE: Do not refresh eInk displays more often than 180 seconds! display.refresh() # Wait the minimum 3 minutes between refreshes. Then loop to freeze. time.sleep(180) while True: pass
2.7" eInk Shield Example
The pins reflect the combination of the shield eInk display and a Metro M4. It has the pixel dimensions of the 2.7" display.
# SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries # # SPDX-License-Identifier: MIT """ Simple Badge script for a 2.7" 264x176 Tri-Color eInk display shield Supported products: * Adafruit 2.7" Tri-Color ePaper Display Shield https://www.adafruit.com/product/4229 This program requires the adafruit_il91874 and the adafruit_display_text library in /lib on the CIRCUITPY drive for CircuitPython 5.0 and above which has displayio support. """ import time import board import displayio import adafruit_il91874 import terminalio from adafruit_display_text import label BLACK = 0x000000 WHITE = 0xFFFFFF RED = 0xFF0000 # Change text colors, choose from the following values: # BLACK, RED, WHITE TEXT_COLOR = BLACK BACKGROUND_COLOR = WHITE # 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 DISPLAY_WIDTH = 264 DISPLAY_HEIGHT = 176 # Create the display object - the third color is red (0xff0000) display = adafruit_il91874.IL91874(display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, highlight_color=0xff0000, rotation=90) # Create a display group for our screen objects g = displayio.Group() # Set a background background_bitmap = displayio.Bitmap(DISPLAY_WIDTH, DISPLAY_HEIGHT, 1) # Map colors in a palette palette = displayio.Palette(1) palette[0] = BACKGROUND_COLOR # Put the background into the display group bg_sprite = displayio.TileGrid(background_bitmap, pixel_shader=palette, x=0, y=0) g.append(bg_sprite) # Display a picture from the root directory of the CIRCUITPY drive # Picture should be HEIGHTxHEIGHT square ideally for a portrait # But could be the entire WIDTHxHEIGHT for a non-portrait filename = "/picture.bmp" # Create a Tilegrid with the bitmap and put in the displayio group # CircuitPython 6 & 7 compatible pic = displayio.OnDiskBitmap(open(filename, "rb")) t = displayio.TileGrid( pic, pixel_shader=getattr(pic, 'pixel_shader', displayio.ColorConverter()) ) g.append(t) # # CircuitPython 7+ compatible # pic = displayio.OnDiskBitmap(filename) # t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader) # g.append(t) # Draw simple text using the built-in font into a displayio group # For smaller text, change scale=2 to scale=1 as scale 2 doesn't # allow for much text but the text is bigger. text_group = displayio.Group(scale=2, x=DISPLAY_HEIGHT + 5, y=int(DISPLAY_HEIGHT/2) - 13) first_name = "Limor" text_area = label.Label(terminalio.FONT, text=first_name, color=TEXT_COLOR) text_group.append(text_area) # Add this text to the text group g.append(text_group) # Draw simple text using the built-in font into a displayio group # For smaller text, change scale=2 to scale=1 as scale 2 doesn't # allow for much text but the text is bigger. text_group = displayio.Group(scale=2, x=DISPLAY_HEIGHT + 5, y=int(DISPLAY_HEIGHT/2) + 13) last_name = "Fried" text_area = label.Label(terminalio.FONT, text=last_name, color=TEXT_COLOR) text_group.append(text_area) # Add this text to the text group g.append(text_group) # Place the display group on the screen display.show(g) # Refresh the display to have it actually show # NOTE: Do not refresh eInk displays more often than 180 seconds! display.refresh() # Wait the minimum 3 minutes between refreshes. Then loop to freeze. time.sleep(180) while True: pass
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 displayio
know which pins are used on the display. The specific 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.
The display dimensions (display-specific) are defined. Then 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 is very similar to the last two examples. First a bitmap graphic named picture.bmp is read from the root directory of the CIRCUITPY drive. The graphic is set in the display group with displayio.TileGrid
. Then two lines of text are defined. They are placed a few pixels to the right of the bitmap and equidistant to the middle of the display's height.
Not much text can fit in this manor. There are two methods you can get more text width:
- Changing
scale=2
toscale=1
will give more characters per line but the text will be smaller. - If you need ultimate flexibility, it is suggested you create all your design elements into one bitmap picture and use the first example to display just the bitmap.
The program places all the group elements on screen with display.show
then refreshes the display with display.refresh
to actually have the graphics show up. It takes 2-3 seconds for an eInk display to erase the previous image and display the new image.
Finally the program waits 3 minutes. A while True:
and pass
loop is at the end of the program so the REPL does not erase the badge graphics. Pressing the reset button will start the program again.