In this tutorial, you will learn about interfacing a tri-color E-ink display with an Arduino or an ESP32.
E-Ink, or electronic paper (E-Paper), is a display technology that mimics the appearance of ink on paper. It uses tiny microcapsules filled with colored particles. When an electric field is applied, the particles move to the surface, creating text and images.
E-paper offers several advantages. Its low power consumption allows devices to run for weeks or months on a single charge. The display mimics traditional paper, providing excellent readability in bright sunlight and wide viewing angles without glare. Additionally, E-Paper is thin and lightweight. However, E-Paper has a slow refresh, a limited color range and is comparatively expensive.
Required Parts
You will need an E-Paper display and for this tutorial I picked a 3-color, 2.9 inch display with a resolution of 296×128 pixels. However, you could also use a monochrome E-Paper with a different size.
We will connect the E-Paper to an Arduino and an ESP32. Pretty much any Arduino or ESP32 model will work but the ESP32 is the better choice. The ESP32 lite listed below is especially suitable, since it has a battery interface and E-Papers are great for battery powered projects.
2.9″ tri-color E-Paper Display
Arduino Uno
USB Cable for Arduino UNO
ESP32 lite
USB Data Cable
Dupont Wire Set
Breadboard
Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.
Basics of e-Paper Displays
E-paper technology is based on Microcapsule Electrophoretic Display (EPD) technology. The E-paper sheet consists of a transparent conductive polymer layer that serves as the front electrode, along with millions of microcapsules, each about the diameter of a human hair, embedded in a polymer material. These microcapsules contain colored particles or pigments (black, white, …) in a transparent fluid. The E-paper sheet is then laminated onto a substrate, which acts as the bottom electrode.
The bottom electrode is typically divided into segments or pixels, allowing independent control of the voltage on each segment. This capability enables the display to form various images. Once an image is created, the voltage can be removed, and the particles will remain in their current positions. This characteristic allows an E-paper to maintain a static image without consuming power.
Two Pigment Ink System
In a two-pigment electronic ink system, each microcapsule contains negatively charged white particles and positively charged black particles suspended in a clear fluid. When an electric field is applied, either positive or negative, the corresponding particles migrate to the top of the microcapsule. This movement makes the particles visible, causing the surface to appear either white or black at that specific location.
By controlling the electric fields applied to each microcapsule, the display can show a range of gray shades, however, most monocolor E-Papers support only black and white.
Three Pigment Ink System
A three-pigment electronic ink system expands on the principles of the two-pigment system by incorporating an additional color. In this system, the microcapsules or microcups contain negatively charged white particles, positively charged black particles, and a third set of positively charged pigments, typically red or yellow.
When an electric field is applied, the particles respond based on their charge. For instance, a negative electric field will cause the positively charged red particles to rise to the surface. A split charge rises the black particles to the top. And a positive charge, will bring the white particles to the front.
Tri-color 2.9″ E-Paper Display Module
If you want to control an E-Paper from a microcontroller you will need a driver that controls the electrical fields for the display. You can buy the E-Paper and driver separately or as a module that integrates the E-Paper and the driver in one unit.
The display module we are using in this tutorial is a tri-color (white, black, red) display with a size of 2.9 inch, a resolution of 296×128 pixels and an embedded controller with an SPI interface for communication. The picture below shows the front and back of the display module:
Note that the module has a little jumper pad/switch at the back to switch from 4-wire SPI to 3-wire SPI. We are going to use the default 4-wire SPI here. So you should not have to change anything.
The display module runs on 3.3V or 5V, with a standby power of 0.017mW and consumes only about 26.4mW while refreshing. The time for a full refresh is 15 seconds and a partial refresh is not supported. If you want to learn more about the differences between a full and a partial refresh, have a look at our Partial Refresh of e-Paper Display tutorial.
Pinout of e-Paper Display
The display model comes with an 8-pin connector for SPI communication and power supply that has the following pins:
BUSY indicates the the display is busy refreshing content. RST stands for Reset. DC is the Data Command pin, CS is the Chip Select, and CLK is the Clock pin. DIN is the Data Input pin. VCC and GND are for the power supply. The display has an integrated voltage regulator and you can use 3.3V or 5V to power it.
Installing GxEPD2 library for e-Paper
Before we can draw or write on the E-Paper we need to install two libraries. The Adafruit_GFX library is a core graphics library that provides a common set of graphics primitives (text, points, lines, circles, etc.). And the GxEPD2 library provides the graphics driver software to control an E-Paper via SPI.
Open the Library Manger, search for “Adafruit_GFX” and “GxEPD2” and press “INSTALL”. After the installation the libraries should appear in the Library Manager as follows.
In the following two sections, I will show you how to connect the E-Paper display to an ESP32 or an Arduino. The ESP32 is preferable over the Arduino, since it has a much larger memory, which makes the code simpler.
Connecting e-Paper Display to ESP32
The picture below shows how to connect an ESP32 lite to the E-Paper display. While most pins can be configured you will need to know the default SPI pins for your ESP32 board, specifically for the DIN and CLK signal. In case of the ESP32 lite, DIN is at pin 23 and CLK is at pin 18.
If you need help finding the default SPI pins, have a look at the Find I2C and SPI default pins tutorial.
The following table shows all the connection you have to make. Note that you can power the display module with 3.3V or 5V but the ESP32-lite has only a 3.3V output.
e-Paper display | ESP32 lite |
---|---|
CS/SS | 5 |
SCL/SCK | 18 |
SDA/DIN/MOSI | 23 |
BUSY | 15 |
RES/RST | 2 |
DC | 0 |
VCC | 3.3V |
GND | G |
You can use a breadboard to wire everything up. But I actually connected the display directly to the ESP32 with Dupont wires. The picture below shows how my setup looked like.
Test code for e-Paper with ESP32
Next we write some simple code to test the function of the display. We are going to show the text “Makerguides”, with “Maker” in black color and “guides” in red color.
#include "GxEPD2_3C.h" #define EPD_CS 5 #define EPD_DC 0 #define EPD_RST 2 #define EPD_BUSY 15 // SCL/SCK/CLK = 18, // SDA/DIN/MOSI = 23 GxEPD2_3C<GxEPD2_290_C90c, GxEPD2_290_C90c::HEIGHT> epd(GxEPD2_290_C90c(EPD_CS , EPD_DC, EPD_RST, EPD_BUSY)); void setup() { epd.init(115200); epd.setRotation(1); epd.setTextSize(2); epd.setFullWindow(); epd.fillScreen(GxEPD_WHITE); epd.setCursor(80, 60); epd.setTextColor(GxEPD_BLACK); epd.print("Maker"); epd.setCursor(140, 60); epd.setTextColor(GxEPD_RED); epd.print("guides"); epd.display(); epd.hibernate(); } void loop() {}
Let’s break down the code into its parts for a better understanding.
Library Inclusion
We start by including the necessary library for controlling the E-Paper display. The library GxEPD2_3C.h
provides the functions needed to interact with the tri-color display.
#include "GxEPD2_3C.h"
If you have a 4-color display you would include GxEPD2_4C.h
or GxEPD2_7C.h
for a 7-color display, instead. If you have a black and white (BW) e-Paper, include GxEPD2_BW.h
Pin Definitions
Next, we define the pins used to connect the display to the ESP32 via the SPI interface:
#define EPD_CS 5 #define EPD_DC 0 #define EPD_RST 2 #define EPD_BUSY 15
Display Object Creation
We create an instance of the E-Paper display object using the defined pins. The template parameters also specify the type of display and its height.
GxEPD2_3C<GxEPD2_290_C90c, GxEPD2_290_C90c::HEIGHT> epd(GxEPD2_290_C90c(EPD_CS , EPD_DC, EPD_RST, EPD_BUSY));
This is the most critical line of the code. If your display doesn’t show anything or corrupted text/images then either the display is not correctly wired or the wrong display driver is chosen.
The Readme for GxEPD2 library lists all the supported displays and you can find the specifics in the header files, e.g. GxEPD2.h. Find the display driver specific for your display. This may take some trial and error.
Setup Function
In the setup()
function, we initialize the communication to the display with a baud rate of 115200. We also set the rotation of the display to 1 (90 degrees), which is Landscape mode.
epd.init(115200); epd.setRotation(1);
Next, we configure the text size and prepare the display for drawing.
epd.setTextSize(2); epd.setFullWindow(); epd.fillScreen(GxEPD_WHITE);
We then set the cursor position and text color to black before printing “Maker” on the display.
epd.setCursor(80, 60); epd.setTextColor(GxEPD_BLACK); epd.print("Maker");
After that, we change the cursor position and text color to red to print “guides”.
epd.setCursor(140, 60); epd.setTextColor(GxEPD_RED); epd.print("guides");
Both printing commands together, will print the text “Makerguides” in the middle of the display. The output on your display should look as follows:
Finally, we call epd.display()
to render the text on the screen and put the display into hibernation mode to save power.
epd.display(); epd.hibernate();
Loop Function
The loop()
function is empty in this example, as we only need to initialize and display the text once. The display will remain in a low-power state and will keep displaying the text, even if the power supply is completely removed.
void loop() {}
If you upload and run the code you will see the display flickering for about 15 seconds, while the text is slowly emerging (see the short video clip below).
This is called a “Full refresh” and it clears the entire screen and redraws all the pixels. This process ensures that any ghosting or leftover images from previous contents are eliminated.
A “Partial refresh“, on the other hand, only updates specific areas of the screen. This method is much faster (< 0.3 sec) and avoids the flickering. For examples, see the Partial Refresh of e-Paper Display tutorial.
While partial refreshes are commonly supported by monochrome E-Paper displays, many tri-color displays, including the one used in this project, don’t support it. That limits their application to use cases, where content updates are infrequent, e.g. once an hour or so. Otherwise the flicking and slow refresh is too distracting.
Connecting E-Paper Display to Arduino
In this section we connect the E-Paper Display to an Arduino Uno instead of an ESP32. The number of connections we need to make are the same, just the pins are different. As mentioned before, most pins can be configured but for DIN and CLK lines we need to use SPI specific pins. In case of an Arduino Uno, DIN is at pin 11 and CLK is at pin 13.
The following table lists all the other connection you have to make. For power you could use 5V instead of 3.3V.
e-Paper display | Arduino UNO |
---|---|
CS/SS | 4 |
SCL/SCK/CLK | 13 |
SDA/DIN/MOSI | 11 |
BUSY | 7 |
RES/RST | 6 |
DC | 5 |
VCC | 3.3V |
GND | G |
Test code for E-Paper with Arduino Uno
The code to test the E-Paper with an Arduino Uno is similar to the one using an ESP32, with two important differences, caused by the small memory of an Arduino Uno.
Have a quick look at the code first and maybe read the ESP32 example code for context. Then we will discuss the differences.
#include "GxEPD2_3C.h" #define EPD_CS 4 #define EPD_DC 5 #define EPD_RST 6 #define EPD_BUSY 7 // SCL/SCK/CLK = 13, // SDA/DIN/MOSI = 11 #define MAX_BUFF 1024 #define MAX_HEIGHT(EPD) ((MAX_BUFF / 2) / (EPD::WIDTH / 8)) GxEPD2_3C<GxEPD2_290_C90c, MAX_HEIGHT(GxEPD2_290_C90c)> epd(GxEPD2_290_C90c(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); void setup() { epd.init(115200); epd.setRotation(1); epd.setTextSize(2); epd.setFullWindow(); epd.firstPage(); do { epd.fillScreen(GxEPD_WHITE); epd.setCursor(80, 60); epd.setTextColor(GxEPD_BLACK); epd.print("Maker"); epd.setCursor(140, 60); epd.setTextColor(GxEPD_RED); epd.print("guides"); } while (epd.nextPage()); epd.hibernate(); } void loop() {}
As before, the code writes the text “Makerguides” in black and red on the display. However, the way the display object is created is different. Specifically, we have to define the hight (MAX_HEIGHT
) of the display:
#define MAX_BUFF 1024 #define MAX_HEIGHT(EPD) ((MAX_BUFF / 2) / (EPD::WIDTH / 8)) GxEPD2_3C<GxEPD2_290_C90c, MAX_HEIGHT(GxEPD2_290_C90c)> epd(GxEPD2_290_C90c(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
The E-Paper display has a resolution of 296 * 128 pixels, which means a total of 37888 pixels need to be set to update the content shown on the display. Typically, the content is written to a display buffer first and then sent to the display. However, an Arduino Uno has only 2KB SRAM = 2048 bytes, which is too small to hold the complete buffer. We therefore define a smaller display buffer MAX_BUFF
= 1024.
With the smaller display buffer we cannot send the complete buffer but only a stripe of MAX_HEIGHT
, which is derived from MAX_BUFF
and the width (EPD::WIDTH
) of the display. We compute the hight of display via MAX_HEIGHT(GxEPD2_290_C90c)
.
Paged drawing
The display is then updated using a paged drawing mode. This method divides the display into smaller sections or stripes called “pages”. Instead of loading the entire content, the Arduino only processes one page at a time.
You can see this in the do
–while
loop in the setup
function, where pages are repeatedly drawn until the complete content of the display is updated.
epd.firstPage(); do { ... } while (epd.nextPage());
When updating the display, the Arduino draws the content for the current page into memory, then sends that page to the E-Paper display. After the page is updated, the Arduino can clear the buffer and load the next page.
Note that the display buffer and the code for the sketch share the same memory. If your code becomes bigger you may have to reduce MAX_BUFF
to fit both into SRAM. If you get the following error message when compiling the code, you know MAX_BUFF
is set too high:
Not enough memory; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing your footprint. data section exceeds available space in board. Compilation error: data section exceeds available space in board
The explicit do
–while
loop for paged drawing is rather unwieldy and ugly. Luckily the GxEPD2 library provides another option. You can define a drawing function and then call epd.drawPaged(...)
for paged drawing. The following code example shows, how that looks like for the test code above:
... void draw(const void* pv) { epd.fillScreen(GxEPD_WHITE); epd.setCursor(80, 60); epd.setTextColor(GxEPD_BLACK); epd.print("Maker"); epd.setCursor(140, 60); epd.setTextColor(GxEPD_RED); epd.print("guides"); } void setup() { ... epd.drawPaged(draw, 0); epd.hibernate(); } void loop() {}
The drawing function draw()
takes a pointer pv
, which allows you to pass on parameters, though we don’t use this here. When calling epd.drawPaged(draw, 0)
, we simply pass 0
as a parameter pointer.
The use of drawing functions for paged redraws makes the code more readable and extendable. You can have multiple drawing functions, which are especially use full when performing partial and full refreshes. See the Digital Clock on e-Paper Display tutorial for an example.
Note that you can use paged drawing even if your microcontroller is big enough to hold the complete display buffer. For instance, the test code for the Arduino Uno would run without changes (apart from the wiring) on an ESP32 and generally paged drawing is recommended.
Recommendation
The Waveshare Manual provides the following recommendations when operating an E-Paper display (shortened and rephrased by me):
Full refresh: The e-Paper display will flicker several times during the refresh process (the number of flickers depends on the refresh time), and the flicker is to remove any afterimages to achieve the best display effect.
Partial refresh: In this case the display has no flickering effect during the refresh process. After several partial refreshing operations, a full refresh operation should be performed to remove the residual image. Otherwise the residual image may become permanent.
It is recommended to set the refresh interval of the e-ink screen to at least 180 seconds (except for products that support the partial refresh).
After a refresh operation, it is recommended to power off or hibernate the display. This will prolong the life of the display and reduces power consumption.
When using a three-color e-ink screen, it is recommended to update the display screen at least once every 24 hours.
E-Paper displays are recommended for indoor use and not for outdoor use. If you want to use the display outdoors, place it in a shaded area and completely cover the white glue part of the e-Paper screen’s connection ribbon with 3M tape.
Conclusions
E-paper displays offer several advantages that make them appealing for various projects. They consume very little power, especially when displaying static images, which is ideal for battery-operated devices. Their excellent readability in bright sunlight makes them suitable for outdoor applications, while their wide viewing angles ensure clarity from different perspectives. Additionally, e-paper displays are thin and lightweight, allowing for easy integration into various designs.
However, E-paper displays have a slow refresh rate compared to LCDs or OLEDs, which can limit their use in projects that require dynamic content. The color options are also limited; black and white displays only show two colors, while tri-color displays are restricted to three colors, which can affect design flexibility. Furthermore, e-paper displays can be more expensive than other display types, particularly for larger sizes.
Monochrome E-paper displays have much faster refresh rates (< 3 seconds) than tri-color displays and typically support partial refresh for an even fast, flicker-free update. They are fast enough for clock displays, for instance. See our tutorials Digital Clock on e-Paper Display and Analog Clock on e-Paper Display.
The very slow refresh time (15 seconds) of tri-color displays limit their applications. The most common use case are electronic price labels. But you could use it for other application with slow refresh cycles as well. For instance, weather data need to be updated only every 15 minutes or so.
Our Weather Station on e-Paper Display tutorial uses a monochrome E-Paper but a tri-color E-Paper would be an option. And if you need even more colors, have a look at the 4-color E-paper display with ESP32 tutorial.
If you have any questions, feel free to ask in the comment section.
Happy tinkering ; )
I am Puneeth. I love tinkering with open-source projects, Arduino, ESP32, Pi and more. I have worked with many different Arduino boards and currently I am exploring, Arduino powered LoRa, Power line communication and IoT.