Documentation

2.13" Black & White E-Paper HAT SPI 250x122 for Raspberry Pi | ShillehTek Product Manual
Documentation / 2.13" Black & White E-Paper HAT SPI 250x122 for Raspberry Pi | ShillehTek Product Manual

2.13" Black & White E-Paper HAT SPI 250x122 for Raspberry Pi | ShillehTek Product Manual

DisplayE-InkE-PaperESP32manualRaspberry PishillehtekSPI

Overview

The 2.13" Black & White E-Paper HAT is a 250×122-pixel electrophoretic (e-ink) display designed primarily as a 40-pin HAT for Raspberry Pi, but it also includes a breakout header so you can drive it from an ESP32, Pi Pico, or Arduino over a 4-wire SPI interface. Like all e-paper displays, the image stays on the screen with zero power once it's been drawn — the panel only draws current during a refresh.

That makes it ideal for low-power, always-visible information displays: weather stations, room signs, name badges, smart-home dashboards, calendar widgets, and battery-powered IoT projects where you want the screen readable in direct sunlight and visible for weeks on a single charge. The display supports both full refresh (clean, no ghosting, slower) and partial refresh (faster, suitable for clocks and counters at the cost of mild ghosting).

The HAT exposes VCC, GND, DIN (MOSI), CLK (SCLK), CS, DC, RST, and BUSY pins, plus a small switch on the back to toggle between 3-line and 4-line SPI. For the vast majority of users (and all of the code in this manual), leave it set to 4-line SPI — the standard mode that all common drivers expect.

At a Glance

Resolution
250 x 122 px
Colors
Black & White
Operating Voltage
3.3V
Interface
4-wire SPI
Refresh Power
~26 mA (during refresh)
Idle Power
~0 mA (image persists)

Specifications

Parameter Value
Display Type Electrophoretic (E-Ink / E-Paper)
Screen Size 2.13 inch (diagonal)
Resolution 250 x 122 pixels
Color Depth 1-bit (Black & White, no grayscale)
Operating Voltage 3.3V
Operating Current ~26 mA during refresh, ~0 mA when idle
Communication Interface 4-wire SPI (3-line SPI selectable)
Full Refresh Time ~2 seconds
Partial Refresh Time ~0.3 seconds
Viewing Angle > 170°
Form Factor Raspberry Pi HAT (40-pin) + breakout pins
Operating Temperature 0°C to 50°C

Pinout Diagram

2.13 inch Black White E-Paper HAT pinout showing PWR/BUSY/RST/DC/CS/SCLK/DIN/GND/VCC pins and 3-line/4-line SPI interface config switch

Wiring Guide

Raspberry Pi Wiring

The easiest way to use this module with a Raspberry Pi is to plug it straight onto the 40-pin GPIO header as a HAT — no wiring required. If you need to mount the display elsewhere, the breakout pins on the side let you wire it up manually. Either way, the SPI interface must be enabled via raspi-config first.

E-Paper Pin Raspberry Pi Pin Details
VCC Pin 1 (3.3V)
GND Pin 6 (GND)
DIN Pin 19 (GPIO 10, MOSI) SPI Data In
CLK Pin 23 (GPIO 11, SCLK) SPI Clock
CS Pin 24 (GPIO 8, CE0) Chip Select
DC Pin 22 (GPIO 25) Data / Command
RST Pin 11 (GPIO 17) Reset
BUSY Pin 18 (GPIO 24) Busy status output
Info: Enable SPI before running any code: sudo raspi-config → Interface Options → SPI → Enable, then reboot. You can verify with ls /dev/spi*.
Tip: The 3-line/4-line interface switch on the back of the board should stay on the 4-line side (factory default). All Waveshare-style drivers assume 4-line SPI.

ESP32 Wiring

The ESP32 drives the e-paper over hardware SPI (VSPI by default). Power the display from the ESP32's 3.3V rail — do NOT use 5V.

E-Paper Pin ESP32 Pin Details
VCC 3.3V 3.3V only — NOT 5V
GND GND
DIN GPIO 23 (MOSI) VSPI MOSI
CLK GPIO 18 (SCK) VSPI Clock
CS GPIO 5 Chip Select
DC GPIO 17 Data / Command
RST GPIO 16 Reset
BUSY GPIO 4 Busy status input
Warning: The panel is strictly 3.3V. Powering VCC from 5V can permanently damage the driver IC. Use the ESP32's 3V3 pin, not VIN/USB.

Raspberry Pi Pico Wiring

The Pico drives this display nicely over SPI0 in MicroPython. Power the panel from the Pico's 3V3(OUT) pin.

E-Paper Pin Pico Pin Details
VCC 3V3(OUT) (Pin 36)
GND GND
DIN GP11 (SPI0 TX / MOSI)
CLK GP10 (SPI0 SCK)
CS GP9
DC GP8
RST GP12
BUSY GP13
Tip: The Pico's 3V3(OUT) can comfortably supply the ~26 mA the panel draws during refresh, so no external regulator is needed.

Arduino Wiring

Arduino (UNO/Nano/Mega) can drive this display via the GxEPD2 library, but be aware that a full 250×122 framebuffer needs ~3.8 KB of RAM — tight on a UNO (2 KB SRAM). GxEPD2 supports paged drawing to work around this. For full-buffer use, prefer a Mega, Nano Every, or another board with more RAM.

E-Paper Pin Arduino Pin Details
VCC 3.3V 3.3V only — NOT 5V
GND GND
DIN Digital Pin 11 (MOSI) SPI MOSI
CLK Digital Pin 13 (SCK) SPI Clock
CS Digital Pin 10 Chip Select
DC Digital Pin 9 Data / Command
RST Digital Pin 8 Reset
BUSY Digital Pin 7 Busy status input
Warning: The display is 3.3V only on both power AND logic. A 5V Arduino UNO will drive the SPI lines at 5V, which is out-of-spec for this panel. For best results use a 3.3V Arduino variant (Pro Mini 3.3V, Nano 33 IoT, MKR series) or add a level shifter on DIN, CLK, CS, DC, and RST.

Code Examples

Raspberry Pi (Python)

epaper_rpi.py
#!/usr/bin/env python3
# 2.13" Black & White E-Paper HAT - Raspberry Pi Example
# Uses the Waveshare epd2in13_V3 driver.
# Install: pip3 install waveshare-epaper
#   (or copy waveshare_epd/ from https://github.com/waveshareteam/e-Paper )

from waveshare_epd import epd2in13_V3
from PIL import Image, ImageDraw, ImageFont
import time

epd = epd2in13_V3.EPD()
epd.init()
epd.Clear(0xFF)  # start with a clean white screen

# Note: panel is rotated. Width/Height are the "landscape" 250x122.
image = Image.new("1", (epd.height, epd.width), 255)  # 1-bit, white
draw = ImageDraw.Draw(image)

font = ImageFont.load_default()
draw.text((10, 10), "Hello, ShillehTek!", font=font, fill=0)
draw.text((10, 40), "2.13\" E-Paper Display", font=font, fill=0)
draw.rectangle([(5, 5), (240, 80)], outline=0)

epd.display(epd.getbuffer(image))
time.sleep(2)

epd.sleep()  # very important: put the panel to sleep when done

ESP32 (Arduino / GxEPD2)

epaper_esp32.ino
// 2.13" Black & White E-Paper - ESP32 Arduino Example
// Library: GxEPD2 by Jean-Marc Zingg (install via Library Manager)

#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>

// CS=5, DC=17, RST=16, BUSY=4
GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT>
  display(GxEPD2_213_BN(/*CS=*/5, /*DC=*/17, /*RST=*/16, /*BUSY=*/4));

void setup() {
  Serial.begin(115200);
  display.init(115200);
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);

  display.setFullWindow();
  display.firstPage();
  do {
    display.fillScreen(GxEPD_WHITE);
    display.setCursor(10, 30);
    display.print("Hello, ShillehTek!");
    display.setCursor(10, 60);
    display.print("2.13\" E-Paper");
  } while (display.nextPage());

  display.hibernate(); // low-power sleep
}

void loop() {}

Raspberry Pi Pico (MicroPython)

epaper_pico.py
# 2.13" Black & White E-Paper - Pico MicroPython Example
# Driver: copy Pico_ePaper-2.13.py from Waveshare's GitHub
#   ( https://github.com/waveshareteam/Pico_ePaper_Code )
# Save as Pico_ePaper.py on the Pico, then:

from machine import Pin, SPI
import framebuf
import time

# Driver wires CS=9, DC=8, RST=12, BUSY=13, SCK=10, MOSI=11
from Pico_ePaper import EPD_2in13

epd = EPD_2in13()
epd.Clear(0xff)

# Width/Height come from the driver
epd.fill(0xff)
epd.text("Hello, ShillehTek!", 5, 10, 0x00)
epd.text("2.13\" E-Paper", 5, 30, 0x00)
epd.text("Pico + MicroPython", 5, 50, 0x00)
epd.rect(0, 0, epd.width, epd.height, 0x00)

epd.display(epd.buffer)
time.sleep(2)

epd.sleep()

Arduino UNO / Mega (GxEPD2)

epaper_arduino.ino
// 2.13" Black & White E-Paper - Arduino Example
// Library: GxEPD2 by Jean-Marc Zingg
// CS=10, DC=9, RST=8, BUSY=7

#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>

GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT>
  display(GxEPD2_213_BN(/*CS=*/10, /*DC=*/9, /*RST=*/8, /*BUSY=*/7));

void setup() {
  display.init();
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);

  // Paged drawing keeps RAM usage low on UNO (2 KB SRAM)
  display.setFullWindow();
  display.firstPage();
  do {
    display.fillScreen(GxEPD_WHITE);
    display.setCursor(10, 30);
    display.print("Hello, ShillehTek!");
    display.setCursor(10, 60);
    display.print("2.13\" E-Paper");
  } while (display.nextPage());

  display.hibernate();
}

void loop() {}

Frequently Asked Questions

Can I just plug this on top of my Raspberry Pi as a HAT?
Yes. The board is designed as a 40-pin Raspberry Pi HAT, so it plugs directly onto the GPIO header of a Pi 3, Pi 4, Pi 5, or Pi Zero (with a header soldered on). Enable SPI in raspi-config, install the Waveshare driver, and you're ready to go. The breakout pins are only needed if you want to wire it elsewhere.
Does the image stay on the screen when power is removed?
Yes — that's one of the best features of e-paper. Once an image is drawn, it stays visible indefinitely with zero power draw. The display only consumes current (~26 mA) during a refresh. That makes it ideal for battery-powered displays that update once a minute, hour, or day.
What's the difference between full refresh and partial refresh?
Full refresh takes ~2 seconds and flashes the whole screen black-and-white several times before settling. It gives the cleanest image with no ghosting. Partial refresh updates just the changed pixels in ~0.3 seconds, which is great for clocks or counters, but ghosting builds up over time. Do a full refresh every 30-50 partial updates to clear it.
Can I get grayscale or color out of this panel?
No. This is a 1-bit (purely black & white) panel — every pixel is either black or white. There is no grayscale support in the hardware. For grayscale or color, look at the 4-color or 7-color variants of e-paper displays.
What's the 3-line / 4-line SPI switch on the back of the board?
It selects between a 3-wire SPI mode (without the DC pin) and the standard 4-wire SPI mode (with a separate Data/Command pin). Leave it on 4-line — that's the factory default and what all common Waveshare, GxEPD2, and Pimoroni drivers expect. 3-line mode is rarely used and not supported by most libraries.
Can I use this with an Arduino UNO?
You can, but with caveats. A full 250×122 framebuffer is ~3.8 KB — more than the UNO's 2 KB of SRAM — so you need to use GxEPD2's paged drawing API. Also note the panel is 3.3V on both VCC and logic, while the UNO is a 5V board, so a level shifter is recommended for reliability. Mega, Nano Every, or 3.3V Arduino variants are easier choices.
Why does my display flash white and black many times when refreshing?
That's a full refresh, and it's normal behavior for e-paper. The driver pulses each pixel through multiple voltage waveforms to fully reset the e-ink particles — that's what eliminates ghosting and gives a clean image. If you want faster, less flashy updates, use partial refresh, but do a full refresh occasionally to clear accumulated ghosting.