Updated guides have been published for the different sizes of eInk Breakouts, Shields, and FeatherWings:
CircuitPython Microcontroller Wiring
Using eInk displays with displayio
is really easy. First, wire up your eInk breakout as shown below. All displays have the same pinout, so if your display differs from the one in the Fritzing diagram, you can wire it up the same way.
- Feather 3V to display VIN
- Feather GND to display GND
- Feather SCK to display SCK
- Feather MOSI to display MOSI
- Feather D10 to display D/C
- Feather D9 to display ECS
- Feather D6 to display BUSY
- Feather D5 to display RST
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 CircuitPython version 5.0 or later.
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. Our 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.
Adafruit_CircuitPython_IL0373
- 1.54” Tri-Color eInk
- 2.13” Tri-Color eInk
- 2.13” Tri-Color eInk FeatherWing
- 2.13” Flexible Monochrome eInk
- 2.9” Flexible Monochrome eInk
- 2.9” Tri-Color eInk
Copy the adafruit_il0373.mpy
file from the bundle to the lib folder on your CIRCUITPY drive.
Adafruit_CircuitPython_SSD1608
- 1.54” Monochrome eInk
Copy the adafruit_ssd1608.mpy
file from the bundle to the lib folder on your CIRCUITPY drive.
Adafruit_CircuitPython_SSD1675
- 2.13” Monochrome eInk
- 2.13 Monochrome eInk FeatherWing
Copy the adafruit_ssd1675.mpy
file from the bundle to the lib folder on your CIRCUITPY drive.
Adafruit_CircuitPython_IL91874
- 2.7” Tri-Color eInk
Copy the adafruit_il91874.mpy
file from the bundle to the lib folder on your CIRCUITPY drive.
Adafruit_CircuitPython_IL0398
- 4.2” Tri-Color eInk
Copy the adafruit_il0398.mpy
file from the bundle to the lib folder on your CIRCUITPY drive.
Usage
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
Next copy display-ruler.bmp into the root directory of your CIRCUITPY drive.
In the examples folder for your displayio driver, there should be a test for your display, which will all be similar, but include specific parameters such as the width and height of the display. In this example, we will examine the 2.9" Tri-color breakout test. Here is the code in its entirety.
import time import board import displayio import fourwire # Make sure your display driver is uncommented import adafruit_il0373 #import adafruit_il91874 #import adafruit_ssd1608 #import adafruit_ssd1675 #import adafruit_il0398 # Set based on your display FLEXIBLE = False TRICOLOR = True ROTATION = 90 # 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 # For the Metro/Shield, esc is board.D10 and dc is board.D9 spi = board.SPI() # Uses SCK and MOSI ecs = board.D9 dc = board.D10 rst = board.D5 # set to None for FeatherWing/Shield busy = board.D6 # set to None for FeatherWing/Shield if TRICOLOR: highlight = 0xff0000 #third color is red (0xff0000) else: highlight = 0x000000 # Create the displayio connection to the display pins display_bus = fourwire.FourWire(spi, command=dc, chip_select=ecs, reset=rst, baudrate=1000000) time.sleep(1) # Wait a bit # Create the display object #display = adafruit_ssd1608.SSD1608(display_bus, width=200, height=200, # 1.54" HD Monochrome #display = adafruit_ssd1675.SSD1675(display_bus, width=122, height=250, # 2.13" HD Monochrome #display = adafruit_il91874.IL91874(display_bus, width=264, height=176, # 2.7" Tri-color #display = adafruit_il0398.IL0398(display_bus, width=400, height=300, # 4.2" Tri-color #display = adafruit_il0373.IL0373(display_bus, width=152, height=152, # 1.54" Tri-color #display = adafruit_il0373.IL0373(display_bus, width=296, height=128, swap_rams=FLEXIBLE, # 2.9" Tri-color OR Flexible Monochrome display = adafruit_il0373.IL0373(display_bus, width=212, height=104, swap_rams=FLEXIBLE, # 2.13" Tri-color OR Flexible Monochrome busy_pin=busy, rotation=ROTATION, highlight_color=highlight) # 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.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)
We start by importing the libraries that we need. In this case we need time
for adding delays, board the pin definitions, and of course displayio
.
import time import board import displayio import fourwire
Next you want to uncomment the import statement for the correct driver for your display. This should match the file you copied over earlier. In our case, the 2.9" uses the adafruit_il0373
driver, so we can leave it as is.
# Make sure your display driver is uncommented import adafruit_il0373 #import adafruit_il91874 #import adafruit_ssd1608 #import adafruit_ssd1675 #import adafruit_il0398
Next we want to set these variables based on your display. If you have a flexible display, you would want to change FLEXIBLE
to True
. If you have a monochrome display, you would want to change TRICOLOR
to False
. If you would like to change the rotation, you can do that here as well.
# Set based on your display FLEXIBLE = False TRICOLOR = True ROTATION = 90
Next we release any previously used displays. This is important because if the Feather is reset, the display pins are not automatically released and this makes them available for use again.
displayio.release_displays()
Next we assign the Pins to use. Note that we are not using the SRAM on the eInk display, so we only need to connect the SCK and MOSI SPI pins. We set the SPI object to the board's SPI with the easy shortcut function board.SPI()
. We also have the ePaper Display Chip Select and Data/Command pins.
For the breakout boards only, we define the Reset and Busy pins, otherwise you would change these to None in the case of a shield or FeatherWing.
spi = board.SPI() # Uses SCK and MOSI ecs = board.D9 dc = board.D10 rst = board.D5 # can be None to not use this pin busy = board.D6 # can be None to not use this pin
In the next section, we set the highlight color to either red or black based on whether you have a monochrome or tri-color display. You can leave this alone.
if TRICOLOR: highlight = 0xff0000 #third color is red (0xff0000) else: highlight = 0x000000
In the next line, we set the display bus to FourWire which makes use of the SPI bus. We pass it the D/C
, and CS
pins, which are also usually found on TFT displays and if this is a breakout, we also pass in the reset
pin.
We set the baudrate to 1 MHz instead of the default 24 MHz because the ePaper displays are not about the speed. They are about the patience of waiting many seconds for them to change and the infrequent updates.
After that, we pause for 1 second. Remember, patience.
display_bus = displayio.FourWire(spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000) time.sleep(1)
Next is the initializer. You will want to uncomment the one appropriate to your display. For the 2.9" display, we would want to comment out the line with 2.13" Tri-color OR Flexible Monochrome next to it and uncomment the line with 2.9" Tri-color OR Flexible Monochrome next to it.
# Create the display object #display = adafruit_ssd1608.SSD1608(display_bus, width=200, height=200, # 1.54" HD Monochrome #display = adafruit_ssd1675.SSD1675(display_bus, width=122, height=250, # 2.13" HD Monochrome #display = adafruit_il91874.IL91874(display_bus, width=264, height=176, # 2.7" Tri-color #display = adafruit_il0398.IL0398(display_bus, width=400, height=300, # 4.2" Tri-color #display = adafruit_il0373.IL0373(display_bus, width=152, height=152, # 1.54" Tri-color #display = adafruit_il0373.IL0373(display_bus, width=296, height=128, swap_rams=FLEXIBLE, # 2.9" Tri-color OR Flexible Monochrome display = adafruit_il0373.IL0373(display_bus, width=212, height=104, swap_rams=FLEXIBLE, # 2.13" Tri-color OR Flexible Monochrome busy_pin=busy, rotation=ROTATION, highlight_color=highlight)
Next we create a couple of variables including a displayio group and a file handle to the display-ruler.bmp that you placed in your CIRCUITPY root folder. You did do that, right?
# 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")
Next we take the file handle and read the bitmap data into a TileGrid
object. We also specify the pixel_shader to displayio.ColorConverter()
because we want displayio
to convert the image data into something that will look nice on the eInk. We take the TileGrid object and place it into the group.
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)
In the next line we add the group to the display.
display.root_group = g
Finally, we tell the display to refresh so that everything in memory is written out to the display.
display.refresh() print("refreshed")
Your display will look something like this:
After that we tell it to pause for 180 seconds or three minutes before continuing where your display would show the REPL.
time.sleep(180)
Text editor powered by tinymce.