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.
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
To generate an array of bytes representing an image, it is easiest to use an online tool, e.g.:
Present an image on the screen and overlay the text “Hello World” over it.
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:
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 };
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
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))
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!";
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);
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;
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);
You should be able to see an image and a text on the ePaper Display.