This page will get you up and running with the 3.7" 416x240 Tri-Color eInk display. This display uses the UC8253 driver.
Arduino
First, follow the steps on the Arduino Setup page to install the necessary libraries and dependencies for the example code.
Then, you can run this example code on your board:
// SPDX-FileCopyrightText: 2025 Ladyada for Adafruit Industries
//
// SPDX-License-Identifier: MIT
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// 3.7" Tricolor Display with 417x240 pixels and UC8253 chipset
ThinkInk_370_Tricolor_BABMFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
EPD_BUSY, EPD_SPI);
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit EPD full update test in red/black/white");
Serial.println("3.7 Tri-Color EPD with UC8253 chipset");
display.begin(THINKINK_TRICOLOR);
}
void loop() {
Serial.println("Banner demo");
display.clearBuffer();
display.setTextSize(3);
display.setCursor((display.width() - 144) / 2, (display.height() - 24) / 2);
display.setTextColor(EPD_BLACK);
display.print("Tri");
display.setTextColor(EPD_RED);
display.print("Color");
display.display();
delay(15000);
Serial.println("Color rectangle demo");
display.clearBuffer();
display.fillRect(display.width() / 3, 0, display.width() / 3,
display.height(), EPD_BLACK);
display.fillRect((display.width() * 2) / 3, 0, display.width() / 3,
display.height(), EPD_RED);
display.display();
delay(15000);
Serial.println("Text demo");
// large block of text
display.clearBuffer();
display.setTextSize(1);
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
EPD_BLACK);
display.display();
delay(15000);
display.clearBuffer();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, EPD_BLACK);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i, EPD_RED);
}
display.display();
delay(15000);
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}
Upload the sketch to your board and open up the Serial Monitor (Tools -> Serial Monitor) at 115200 baud. You'll see the display recognized over SPI. Then, as different demos are sent to the display, you'll see the demo name print to the Serial Monitor.
CircuitPython
To use with CircuitPython, you need to first install the Adafruit_CircuitPython_UC8253 library, and its dependencies, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following folders and file:
- adafruit_uc8253.mpy
# SPDX-FileCopyrightText: 2025 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 3.7" 240x416 tricolor display (ThinkInk_370_Tricolor_BABMFGNR)."""
import time
import board
import busio
import displayio
from fourwire import FourWire
import adafruit_uc8253
displayio.release_displays()
if "EPD_MOSI" in dir(board): # Feather RP2040 ThinkInk
spi = busio.SPI(board.EPD_SCK, MOSI=board.EPD_MOSI, MISO=None)
epd_cs = board.EPD_CS
epd_dc = board.EPD_DC
epd_reset = board.EPD_RESET
epd_busy = board.EPD_BUSY
else:
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(spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000)
time.sleep(1)
display = adafruit_uc8253.UC8253(
display_bus, width=416, height=240, busy_pin=epd_busy, rotation=270, highlight_color=0xFF0000
)
g = displayio.Group()
pic = displayio.OnDiskBitmap("/display-ruler-1280x720.bmp")
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)
Once everything is saved to the CIRCUITPY drive, the code will begin running. Your display will show the display ruler bitmap.
Python
First, follow the steps on the Python Setup page to install the necessary libraries and dependencies for the example code.
Pillow Graphics Demo
The great part about using a display on a Raspberry Pi is that you can use Pillow graphics alongside the CircuitPython driver.
The following example uses Pillow for text and drawing shapes. Copy or download the following example to your computer, and run the following, replacing code.py with whatever you named the file:
sudo -E env PATH=$PATH python3 code.py
# SPDX-FileCopyrightText: 2019 Melissa LeBlanc-Williams for Adafruit Industries
# SPDX-License-Identifier: MIT
"""
ePaper Display Shapes and Text demo using the Pillow Library.
3.7" Tri-Color 416x240 display
https://www.adafruit.com/product/6394
"""
import board
import busio
import digitalio
from PIL import Image, ImageDraw, ImageFont
from adafruit_epd.uc8253 import Adafruit_UC8253_Tricolor
# First define some color constants
WHITE = (0xFF, 0xFF, 0xFF)
BLACK = (0x00, 0x00, 0x00)
RED = (0xFF, 0x00, 0x00)
# Next define some constants to allow easy resizing of shapes and colors
BORDER = 20
FONTSIZE = 24
BACKGROUND_COLOR = BLACK
FOREGROUND_COLOR = WHITE
TEXT_COLOR = BLACK
# create the spi device and pins we will need
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
ecs = digitalio.DigitalInOut(board.CE0)
dc = digitalio.DigitalInOut(board.D22)
srcs = None
rst = digitalio.DigitalInOut(board.D27)
busy = digitalio.DigitalInOut(board.D17)
display = Adafruit_UC8253_Tricolor(240, 416,
spi,
cs_pin=ecs,
dc_pin=dc,
sramcs_pin=srcs,
rst_pin=rst,
busy_pin=busy
)
display.rotation = 3
width = display.width
height = display.height
image = Image.new("RGB", (width, height))
WHITE = (0xFF, 0xFF, 0xFF)
RED = (0xFF, 0x00, 0x00)
BLACK = (0x00, 0x00, 0x00)
# clear the buffer
display.fill(WHITE)
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
# empty it
draw.rectangle((0, 0, width, height), fill=WHITE)
# Draw an outline box
draw.rectangle((1, 1, width - 2, height - 2), outline=BLACK, fill=WHITE)
# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = 15
shape_width = 45
top = padding
bottom = height - padding
# Move left to right keeping track of the current x position for drawing shapes.
x = padding
# Draw an ellipse.
draw.ellipse((x, top, x + shape_width, bottom), outline=RED, fill=WHITE)
x += shape_width + padding
# Draw a rectangle.
draw.rectangle((x, top, x + shape_width, bottom), outline=RED, fill=BLACK)
x += shape_width + padding
# Draw a triangle.
draw.polygon(
[(x, bottom), (x + shape_width / 2, top), (x + shape_width, bottom)],
outline=BLACK,
fill=RED,
)
x += shape_width + padding
# Draw an X.
draw.line((x, bottom, x + shape_width, top), fill=BLACK)
draw.line((x, top, x + shape_width, bottom), fill=RED)
x += shape_width + padding
# Load default font.
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 30)
draw.text((x, top), "Hello", font=font, fill=BLACK)
draw.text((x, top + 30), "World!", font=font, fill=BLACK)
# Display image.
display.image(image)
display.display()
Your display will show a circle, rectangle, triangle and a large X next to "Hello World!" text.
Page last edited October 08, 2025
Text editor powered by tinymce.