GxEPD2 Library Setup
GxEPD2 Library Setup
Overview
Section titled “Overview”This section covers the installation and configuration of the GxEPD2 library, the most popular driver library for e-paper displays on ESP32. After completing this section, you will be able to:
- Install the GxEPD2 library in PlatformIO and Arduino IDE
- Select the correct display constructor for your e-paper model
- Initialize the display in your sketch
- Verify the library is working correctly
Prerequisites
Section titled “Prerequisites”Before starting this section, please ensure:
- E-paper display is wired correctly (see 02-02)
- PlatformIO IDE or Arduino IDE is installed
- ESP32 board support is configured
- Completed Chapter 01 (Basic Sketch structure)
Key Concepts
Section titled “Key Concepts”GxEPD2 Library Overview
Section titled “GxEPD2 Library Overview”GxEPD2 is an e-paper display library for ESP32 and other Arduino-compatible boards, built on top of the AdaFruit GFX graphics library. It supports a wide range of e-paper displays from Waveshare, GoodDisplay, and other manufacturers.
Key Features:
- Support for 40+ e-paper display models
- Built on AdaFruit GFX for consistent drawing API
- Support for black/white and tri-color displays
- Partial refresh capability (selected models)
- Configurable SPI pins
Library Architecture
Section titled “Library Architecture”GxEPD2 Library├── GxEPD2 core class (display initialization & control)├── Display-specific constructors (40+ models)├── AdaFruit GFX dependency (text, shapes, bitmaps)├── SPI bus management└── Partial refresh supportDisplay Class and Constructor
Section titled “Display Class and Constructor”Each e-paper display model has a specific constructor class. The naming convention follows the display driver IC:
GxEPD2_<driver IC>(CS, DC, RST, BUSY)Common Examples:
| Display | Driver IC | Constructor |
|---|---|---|
| Waveshare 1.54” B/W | SSD1608 | GxEPD2_154_D67(CS, DC, RST, BUSY) |
| Waveshare 2.13” B/W | SSD1680 | GxEPD2_213_B72(CS, DC, RST, BUSY) |
| Waveshare 2.13” B/W/R | SSD1680 | GxEPD2_213_Z19c(CS, DC, RST, BUSY) |
| Waveshare 2.9” B/W | SSD1680 | GxEPD2_290_T5(CS, DC, RST, BUSY) |
| Waveshare 4.2” B/W | SSD1683 | GxEPD2_420(CS, DC, RST, BUSY) |
| Waveshare 7.5” B/W | SSD1680 | GxEPD2_750_T7(CS, DC, RST, BUSY) |
Implementation Steps
Section titled “Implementation Steps”Step 1: Install Dependencies
Section titled “Step 1: Install Dependencies”For PlatformIO:
Add the following to platformio.ini:
[env:esp32dev]platform = espressif32board = esp32devframework = arduinomonitor_speed = 115200
lib_deps = zinggjm/GxEPD2@^1.5.4 adafruit/Adafruit GFX Library@^1.11.5Then run:
pio pkg installFor Arduino IDE:
- Open Sketch → Include Library → Manage Libraries
- Search for
GxEPD2by Jean-Marc Zingg - Click Install
- Search for
Adafruit GFX Library - Click Install
Step 2: Identify Your Display Constructor
Section titled “Step 2: Identify Your Display Constructor”Find the correct constructor for your display:
// Include the library#include <GxEPD2_BW.h> // For black/white displays// or#include <GxEPD2_3C.h> // For tri-color displays (B/W/R or B/W/Y)
// Define SPI pins#define EPD_CS 5#define EPD_DC 17#define EPD_RST 16#define EPD_BUSY 4
// Select your display constructor// Example: Waveshare 2.13" B/W (SSD1680 driver)GxEPD2_BW<GxEPD2_213_B72, GxEPD2_213_B72::HEIGHT> display( GxEPD2_213_B72(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));How to Find Your Constructor:
- Check the display’s product page for the driver IC
- Look in
GxEPD2_Example(File → Examples → GxEPD2) - Use the constructor matching your display’s size and color
Step 3: Initialize the Display
Section titled “Step 3: Initialize the Display”#include <GxEPD2_BW.h>#include <GxEPD2_3C.h>
// Pin definitions#define EPD_CS 5#define EPD_DC 17#define EPD_RST 16#define EPD_BUSY 4
// Display constructor for 2.13" B/WGxEPD2_BW<GxEPD2_213_B72, GxEPD2_213_B72::HEIGHT> display( GxEPD2_213_B72(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
void setup() { Serial.begin(115200); Serial.println("GxEPD2 Initialization Test");
// Initialize the display display.init(115200); // Serial speed for debug output
// Set rotation (0-3) display.setRotation(1);
// Clear the display to white display.fillScreen(GxEPD_WHITE); display.display();
Serial.println("Display initialized successfully!");
// Display some text display.setCursor(10, 10); display.setTextColor(GxEPD_BLACK); display.print("Hello, E-Ink!"); display.display();}
void loop() { // Nothing here}Step 4: Understanding init() Parameters
Section titled “Step 4: Understanding init() Parameters”display.init(baud_rate, initial, reset, pwr_enable);| Parameter | Type | Default | Description |
|---|---|---|---|
baud_rate | uint32_t | Required | SPI speed (typically 115200 or 4000000) |
initial | bool | true | Full initialization sequence |
reset | bool | true | Hardware reset before init |
pwr_enable | bool | false | Enable power for certain displays |
Recommendation: Always use display.init(115200) for initial testing.
Step 5: Complete Test Sketch
Section titled “Step 5: Complete Test Sketch”#include <GxEPD2_BW.h>
// Pin definitions#define EPD_CS 5#define EPD_DC 17#define EPD_RST 16#define EPD_BUSY 4
// Constructor for 2.13" B/W displayGxEPD2_BW<GxEPD2_213_B72, GxEPD2_213_B72::HEIGHT> display( GxEPD2_213_B72(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
void setup() { Serial.begin(115200); delay(1000);
Serial.println("Testing GxEPD2 Library...");
// Initialize display.init(115200); display.setRotation(0);
// Draw shapes display.fillScreen(GxEPD_WHITE);
display.fillRect(10, 10, 50, 30, GxEPD_BLACK);
display.drawCircle(100, 60, 20, GxEPD_BLACK);
display.setCursor(10, 100); display.setTextColor(GxEPD_BLACK); display.print("GxEPD2 Ready!");
// Update display display.display();
Serial.println("Test complete!");}
void loop() {}Verification
Section titled “Verification”After uploading the test sketch, you should see:
- The display clears to white
- A black rectangle in the top-left corner
- A circle in the center area
- The text “GxEPD2 Ready!” at the bottom
If any of these elements are missing, check the Troubleshooting section below.
Serial Monitor Output:
Testing GxEPD2 Library...Display initialized successfully!Test complete!Troubleshooting
Section titled “Troubleshooting”Issue 1: Compilation Error — “Display class not found”
Section titled “Issue 1: Compilation Error — “Display class not found””Symptom:
error: 'GxEPD2_213_B72' does not name a typeSolution:
- Check the display constructor name in the library documentation
- Verify you included the correct header (
GxEPD2_BW.horGxEPD2_3C.h) - Try updating the library to the latest version
Issue 2: Display Shows Random Pixels
Section titled “Issue 2: Display Shows Random Pixels”Symptom:
- Screen shows random dots or lines
- Text appears garbled
Possible Causes:
- Wrong constructor selected
- SPI speed too high
- Power supply unstable
Solutions:
// Try reducing SPI speed in init()display.init(400000); // Lower speed for stability- Double-check the constructor matches your exact display model
- Add a 10µF capacitor between VCC and GND
Issue 3: Display Stays White After Upload
Section titled “Issue 3: Display Stays White After Upload”Symptom:
- Screen remains white
- No visible output
Solutions:
- Verify all wiring connections
- Check that
display.display()is called after drawing - Ensure the BUSY pin is connected and configured correctly
- Test with a different constructor (check for display variants)
Best Practices
Section titled “Best Practices”- ✅ Always call
display.display()after drawing — Without this, nothing appears on screen - ✅ Use
display.init()with serial debug enabled (115200 baud) during development - ✅ Set rotation before drawing — Changing rotation mid-sketch causes layout confusion
- ❌ Don’t update the display more than once per minute — Excessive updates wear out the display
- ❌ Avoid partial refreshes on tri-color displays — They can cause image ghosting
Summary
Section titled “Summary”- GxEPD2 is the standard e-paper driver library for ESP32, built on AdaFruit GFX
- Each display model needs a specific constructor — check the correct one in library examples
- Initialization sequence: install library → select constructor → init → draw → display()
- Always call
display.display()to push buffer contents to the screen - Keep refresh frequency low to preserve display life and reduce power consumption
References
Section titled “References”Target Audience: Alibaba.com IoT Pre-sales Engineers
Status: ✅ Completed