Introduction
E-ink displays are increasingly popular because they use very little power and can display information without any backlighting. This makes them ideal for projects where power consumption is a concern. However, interfacing them with microcontrollers can be challenging for beginners.
In this article, we’ll explore how to interface a “1.54” E-ink Display” with an Arduino board and display text and graphics on it.
What is E-ink Display?
E-ink (electronic ink) display is a type of electronic paper display technology used for displaying static images and text. It uses a process called electrophoresis to display content on the screen. The display consists of tiny capsules filled with positively charged white particles and negatively charged black particles suspended in a clear fluid. When an electric field is applied, the particles move to either the top or bottom of the capsule, creating the illusion of black or white pixels on the screen. Unlike traditional LCD displays, E-ink displays don’t require a backlight, making them energy-efficient and easy to read in direct sunlight.
Hardware Components
To interface an E-ink Display with Arduino, you’ll need the following hardware components to get started:
Components | Value | Qty |
---|---|---|
Arduino UNO | – | 1 |
USB Cable Type A to B | – | 1 |
DC Power for Arduino | – | 1 |
E-ink Display | 1.54inch | 1 |
Jumper Wires | – | 1 |
E-ink Display Pinout
Pin Label | Pin Type | Description |
VIN | Power | This is the input power pin. You can supply 5 V from the Arduino here. There is a 3.3 V linear voltage regulator on the display module. This pin serves as the input for the regulator. |
3V3 | Power | This is the output of the voltage regulator. The 3.3 V powers the display controller IC. You can also use this to power other modules, but ensure that the current consumption is kept below the regulator voltage rating. |
GND | Power | Ground connection pin. |
SCK | Signal | SPI Clock – Clock Pin of the serial peripheral interface |
MISO | Signal | SPI MISO – Master In Slave Out pin of the Arduino. This is the input pin of the Display controller and the output pin of the Arduino. |
MOSI | Signal | SPI MOSI – Master Out Slave In – This is the Arduino output pin and input pin for the display controller. |
ECS | Signal | E-ink Chip Select |
D/C | Signal | E-ink data command |
SRCS | Signal | SRAM chip select |
SDCS | Signal | SD Card chip select |
RST | Signal | E-ink reset |
BUSY | Signal | E-ink Busy signal |
ENA | Signal | Enable pin. This is connected to the Enable pin of the 3.3 V regulator. You can drive the pin Low to save Power when you have to. When you disable the display controller, the display RAM and the SD Card (if present) will all get disabled. You have to reinitialize the board again. |
E-ink Display Circuit
Make connections according to the circuit diagram given below.
Wiring / Connections
Arduino | E-ink Display |
---|---|
5V | VIN |
GND | GND |
D9 | ECS |
D10 | DC |
D6 | SRCS |
D8 | RES |
D7 | BUSY |
D5 | SDCS |
ICSP | SCK |
ICSP | MISO |
ICSK | MOSI |
Installing Arduino IDE
First, you need to install Arduino IDE Software from its official website Arduino. Here is a simple step-by-step guide on “How to install Arduino IDE“.
Installing Libraries
Before you start uploading a code, download and unzip the following libraries at /Program Files(x86)/Arduino/Libraries (default), in order to use the sensor with the Arduino board. Here is a simple step-by-step guide on “How to Add Libraries in Arduino IDE“.
Code
Now copy the following code and upload it to Arduino IDE Software.
#include "Adafruit_ThinkInk.h"
#define EPD_DC 10 // can be any pin, but required!
#define EPD_CS 9 // can be any pin, but required!
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6 // can set to -1 to not use a pin (uses a lot of RAM!)
#define EPD_RESET 8 // can set to -1 and share with chip Reset (can't deep sleep)
// 1.54" 152x152 Tricolor EPD with ILI0373 chipset
//ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 1.54" 152x152 Tricolor EPD with SSD1680 chipset
//ThinkInk_154_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 1.54" 200x200 Tricolor EPD with SSD1681 chipset
//ThinkInk_154_Tricolor_Z90 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.13" Tricolor EPD with SSD1680 chipset
//ThinkInk_213_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.13" Tricolor EPD with IL0373 chipset
//ThinkInk_213_Tricolor_Z16 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.7" Tricolor Featherwing or Breakout with IL91874 chipset
//ThinkInk_270_Tricolor_C44 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.7" Tricolor Featherwing or Breakout with EK79686 chipset
//ThinkInk_270_Tricolor_Z70 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.9" Tricolor Featherwing or Breakout with IL0373 chipset
ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.9" Tricolor Featherwing or Breakout with UC8151D chipset
//ThinkInk_290_Tricolor_Z13 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 2.9" Tricolor Featherwing or Breakout with SSD1680 chipset and negative offset
//ThinkInk_290_Tricolor_Z94 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Tricolor_Z21 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
void setup() {
Serial.begin(115200);
while (!Serial) { delay(10); }
Serial.println("Adafruit EPD full update test in red/black/white");
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);
}
The code snippet below shows the pin mapping. The pin mapping can be updated based on your actual hardware connections.
#define EPD_DC 10 // can be any pin, but required!
#define EPD_CS 9 // can be any pin, but required!
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6 // can set to -1 to not use a pin (uses a lot of RAM!)
#define EPD_RESET 8 // can set to -1 and share with chip Reset (can't deep sleep)
Code Explanation
This is an Arduino code that controls an E-ink display.
The first few lines of code define the pins that will be used to communicate with the display, including a pin for data/command (EPD_DC), chip select (EPD_CS), and a pin to check if the display is busy (EPD_BUSY). It also sets the SRAM_CS and EPD_RESET pins for use with specific displays.
Next, several different E-ink display models are instantiated using the Adafruit_ThinkInk library, each with their own set of parameters.
In the setup()
function, the serial connection is initialized, and the display is initialized with the begin()
method. In the loop()
function, there are several examples of using the display, including displaying text, drawing lines, and filling rectangles.
Finally, the testdrawtext()
the function is defined, which draws a block of text to the display.
Applications
Here are some applications of E-ink displays:
- E-book readers
- Smartwatches and fitness trackers
- Electronic shelf labels
- Digital signage and advertising displays
- Wearable technology
- Industrial displays
- Medical equipment displays
- Electronic price tags for retail stores
- Public transportation information displays
- Smart home interfaces
- Smart luggage tags
- Point-of-sale displays
- Mobile payment devices
- Electronic newspapers and magazines
Conclusion
An E-ink display with an Arduino board may seem daunting at first, but with the right approach, it can be a straightforward process. By following the steps outlined in this article, you can create your own E-ink display projects and take advantage of the low-power and versatile nature of these displays.