EMB6: Using ePaper display

VREL NExtGen laboratory node is equipped with b/w, ePaper module. It is a dot matrix display with a native resolution of 250×122 pixels. It has 64kB display memory and is controlled via SPI. The ePaper display presents data even if powered off, so don't be surprised that finishing your application does not automatically clean up the display, even if you use some other code later. To clean up the display, one has to clear the screen explicitly.

The ePaper display is slow and flashes several times during the update. It is also possible to update part of the screen only so that it speeds up displaying and involves more ghosting effects.

Prerequisites

Familiarise yourself with a hardware reference: this ePaper is controlled with 6 GPIOs as presented in the “Table 1: ESP32-S3 SUT Node Hardware Details” on the hardware reference page.
You are going to use a library to handle the ePaper drawing. It means you need to add it to your platformio.ini file. Use the template provided in the hardware reference section and extend it with the library definition:

lib_deps = zinggjm/GxEPD2@^1.5.0

Suggested Readings and Knowledge Resources

Hands-on Lab Scenario

Task to be implemented

Present an image on the screen and overlay the text “Hello World” over it.

Start

Check if you can see a full ePaper Display in your video stream. Book a device and create a dummy Arduino file with void setup()… and void loop()….

Prepare a small bitmap (e.g. 60×60 pixels) and convert it to the byte array with b/w settings.
Sample project favicon you can use is present in Figure 1:

Figure 1: IOT-OPEN.EU Reloaded favicon 60px x 60px

Steps

Remember to include the source array in the code when drawing an image.
The corresponding generated C array for the logo in Figure 1 (horizontal 1 bit per pixel, as suitable for ePaper Display) is present below:

// 'logo 60', 60x60px
const unsigned char epd_bitmap_logo_60 [] PROGMEM = {
0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xff, 0xf0, 
0xff, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0xff, 0xff, 0x01, 0xff, 0xf8, 0x0f, 0xff, 0xf0, 
0xff, 0xfc, 0x0f, 0xff, 0xff, 0x03, 0xff, 0xf0, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xc1, 0xff, 0xf0, 
0xff, 0xe0, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xf0, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xf0, 
0xff, 0x87, 0xff, 0xf0, 0xff, 0xfe, 0x1f, 0xf0, 0xff, 0x0f, 0xfe, 0x00, 0x07, 0xff, 0x0f, 0xf0, 
0xfe, 0x1f, 0xf8, 0x7f, 0xe1, 0xff, 0x87, 0xf0, 0xfc, 0x3f, 0xe3, 0xff, 0xfc, 0x7f, 0xc3, 0xf0, 
0xfc, 0x7f, 0x8f, 0xff, 0xff, 0x1f, 0xe3, 0xf0, 0xf8, 0xff, 0x3f, 0xff, 0xff, 0xcf, 0xf1, 0xf0, 
0xf1, 0xfe, 0x7f, 0xff, 0xff, 0xe7, 0xf8, 0xf0, 0xf1, 0xfc, 0xff, 0xff, 0xff, 0xf3, 0xf8, 0xf0, 
0xe3, 0xf9, 0xff, 0xfc, 0x7f, 0xf9, 0xfc, 0x70, 0xe3, 0xf3, 0xff, 0xfc, 0x0f, 0xfc, 0xfc, 0x70, 
0xc7, 0xf7, 0xff, 0xff, 0xc3, 0xfe, 0xfe, 0x30, 0xc7, 0xe7, 0xff, 0xff, 0xf1, 0xfe, 0x7e, 0x30, 
0xcf, 0xef, 0xff, 0xff, 0xfc, 0xff, 0x7f, 0x30, 0x8f, 0xcf, 0xff, 0xff, 0xfe, 0x7f, 0x3f, 0x10, 
0x8f, 0xdf, 0xff, 0xff, 0xff, 0x3f, 0xbf, 0x10, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0x3f, 0x9f, 0x90, 
0x9f, 0x9f, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x90, 0x1f, 0xbf, 0xff, 0xff, 0xff, 0x9f, 0xdf, 0x80, 
0x1f, 0xbf, 0xff, 0xf9, 0xff, 0xdf, 0xdf, 0x80, 0x1f, 0xbf, 0xff, 0xe0, 0x7f, 0xcf, 0xdf, 0x80, 
0x1f, 0x3f, 0xff, 0xe0, 0x7f, 0xcf, 0xcf, 0x80, 0x1f, 0x3f, 0xff, 0xc0, 0x3f, 0xcf, 0xcf, 0x80, 
0x1f, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xf0, 
0x1f, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf0, 
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf0, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf0, 
0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf0, 0x8f, 0xff, 0xff, 0xf9, 0xfc, 0x03, 0xf0, 0x10, 
0x8f, 0xff, 0xff, 0xf9, 0xf8, 0x01, 0xe0, 0x10, 0xcf, 0xff, 0xff, 0xf9, 0xf0, 0xf0, 0xf9, 0xf0, 
0xc7, 0xff, 0xff, 0xf9, 0xf3, 0xfc, 0xf9, 0xf0, 0xc7, 0xff, 0xff, 0xf9, 0xe3, 0xfc, 0x79, 0xf0, 
0xe3, 0xff, 0xff, 0xf9, 0xe3, 0xfc, 0x79, 0xf0, 0xe3, 0xff, 0xff, 0xf9, 0xe3, 0xfc, 0x79, 0xf0, 
0xf1, 0xff, 0xff, 0xf9, 0xe3, 0xfc, 0x79, 0xf0, 0xf1, 0xff, 0xff, 0xf9, 0xf3, 0xfc, 0x79, 0xf0, 
0xf8, 0xff, 0xff, 0xf9, 0xf1, 0xf8, 0xf9, 0xf0, 0xfc, 0x7f, 0xff, 0xf9, 0xf8, 0x61, 0xf8, 0xc0, 
0xfc, 0x3f, 0xff, 0xf9, 0xfc, 0x03, 0xf8, 0x00, 0xfe, 0x1f, 0xff, 0xf9, 0xff, 0x0f, 0xfe, 0x10, 
0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 
0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 
0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 
0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
};
 
// Total bytes used to store images in PROGMEM = 496
const int epd_bitmap_allArray_LEN = 1;
const unsigned char* epd_bitmap_allArray[1] = {
	epd_bitmap_logo_60
};

Step 1

Include necessary libraries.

#include <SPI.h>
#include <GxEPD2.h>
#include <GxEPD2_BW.h>
//Fonts
#include <Fonts/FreeMonoBold12pt7b.h>

The code above also includes a font to draw text on the ePaper Display. There are many fonts one can use, and a non-exhaustive list is present below (files are located in the Adafruit GFX Library, subfolder Fonts):

   FreeMono12pt7b.h
   FreeMono18pt7b.h
   FreeMono24pt7b.h
   FreeMono9pt7b.h
   FreeMonoBold12pt7b.h
   FreeMonoBold18pt7b.h
   FreeMonoBold24pt7b.h
   FreeMonoBold9pt7b.h
   FreeMonoBoldOblique12pt7b.h
   FreeMonoBoldOblique18pt7b.h
   FreeMonoBoldOblique24pt7b.h
   FreeMonoBoldOblique9pt7b.h
   FreeMonoOblique12pt7b.h
   FreeMonoOblique18pt7b.h
   FreeMonoOblique24pt7b.h
   FreeMonoOblique9pt7b.h
   FreeSans12pt7b.h
   FreeSans18pt7b.h
   FreeSans24pt7b.h
   FreeSans9pt7b.h
   FreeSansBold12pt7b.h
   FreeSansBold18pt7b.h
   FreeSansBold24pt7b.h
   FreeSansBold9pt7b.h
   FreeSansBoldOblique12pt7b.h
   FreeSansBoldOblique18pt7b.h
   FreeSansBoldOblique24pt7b.h
   FreeSansBoldOblique9pt7b.h
   FreeSansOblique12pt7b.h
   FreeSansOblique18pt7b.h
   FreeSansOblique24pt7b.h
   FreeSansOblique9pt7b.h
   FreeSerif12pt7b.h
   FreeSerif18pt7b.h
   FreeSerif24pt7b.h
   FreeSerif9pt7b.h
   FreeSerifBold12pt7b.h
   FreeSerifBold18pt7b.h
   FreeSerifBold24pt7b.h
   FreeSerifBold9pt7b.h
   FreeSerifBoldItalic12pt7b.h
   FreeSerifBoldItalic18pt7b.h
   FreeSerifBoldItalic24pt7b.h
   FreeSerifBoldItalic9pt7b.h
   FreeSerifItalic12pt7b.h
   FreeSerifItalic18pt7b.h
   FreeSerifItalic24pt7b.h
   FreeSerifItalic9pt7b.h

Step 2

Declare GPIOs and some configurations needed to handle the ePaper display properly:

#define GxEPD2_DRIVER_CLASS GxEPD2_213_BN
#define GxEPD2_DISPLAY_CLASS GxEPD2_BW
#define USE_HSPI_FOR_EPD
#define ENABLE_GxEPD2_GFX 0
 
#define SPI_SCLK_PIN 18
#define SPI_MOSI_PIN 15
 
#define EPAPER_SPI_DC_PIN 13
#define EPAPER_SPI_CS_PIN 10
#define EPAPER_SPI_RST_PIN 9
#define EPAPER_BUSY_PIN 8
 
#define SCREEN_WIDTH 250
#define SCREEN_HEIGHT 122
#define MAX_DISPLAY_BUFFER_SIZE 65536ul 
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))

Step 3

Declare hardware SPI controller and ePaper display controller:

static SPIClass hspi(HSPI);
 
static GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ EPAPER_SPI_CS_PIN, /*DC=*/ EPAPER_SPI_DC_PIN, /*RST=*/ EPAPER_SPI_RST_PIN, /*BUSY=*/ EPAPER_BUSY_PIN));

You can also declare a message to display as an array of characters:

static const char HelloWorld[] = "Hello IoT!";

Step 4

Initialise SPI and, on top of that, the ePaper controller class:

    hspi.begin(SPI_SCLK_PIN, -1, SPI_MOSI_PIN, -1);
    delay(100);
    pinMode(EPAPER_SPI_CS_PIN, OUTPUT);
    pinMode(EPAPER_SPI_RST_PIN, OUTPUT);
    pinMode(EPAPER_SPI_DC_PIN, OUTPUT);
    pinMode(EPAPER_BUSY_PIN,INPUT_PULLUP);
    delay(100);
    digitalWrite(EPAPER_SPI_CS_PIN,LOW);
    display.epd2.selectSPI(hspi, SPISettings(4000000, MSBFIRST, SPI_MODE0));
    delay(100);
    display.init(115200);
    digitalWrite(EPAPER_SPI_CS_PIN,HIGH);    

Step 5

Set display rotation, font and text colour:

digitalWrite(EPAPER_SPI_CS_PIN,LOW);
display.setRotation(1);
display.setFont(&FreeMonoBold12pt7b);
display.setTextColor(GxEPD_BLACK);

then get the external dimensions of the string to be printed:

int16_t tbx, tby; uint16_t tbw, tbh;
display.getTextBounds(HelloWorld, 0, 0, &tbx, &tby, &tbw, &tbh);
 
uint16_t x = ((display.width() - tbw) / 2) - tbx;
uint16_t y = ((display.height() - tbh) / 2) - tby;

Step 6

Then display contents of the image and the text in the ePaper display:

display.setFullWindow();
display.firstPage();
do
  {
    display.drawImage((uint8_t*)epd_bitmap_logo_60,0,0,60,60);
    display.setCursor(x, y);
    display.print(HelloWorld);
  }
while (display.nextPage());
digitalWrite(EPAPER_SPI_CS_PIN,HIGH);

Result validation

You should be able to see an image and a text on the ePaper Display.

Project information


This Intellectual Output was implemented under the Erasmus+ KA2.
Project IOT-OPEN.EU Reloaded – Education-based strengthening of the European universities, companies and labour force in the global IoT market.
Project number: 2022-1-PL01-KA220-HED-000085090.

Erasmus+ Disclaimer
This project has been funded with support from the European Commission.
This publication reflects the views of only the author, and the Commission cannot be held responsible for any use that may be made of the information contained therein.

Copyright Notice
This content was created by the IOT-OPEN.EU Reloaded consortium, 2022,2024.
The content is Copyrighted and distributed under CC BY-NC Creative Commons Licence, free for Non-Commercial use.

en/iot-open/practical/hardware/sut/esp32/emb6_1.txt · Last modified: 2024/04/05 09:24 by pczekalski
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0