====== STM_6: 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: STM32WB55 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 ===== * [[en:iot-open:introductiontoembeddedprogramming2:cppfundamentals]] * [[en:iot-open:hardware2:stm32|]] * [[en:iot-open:hardware2:actuators_light|]] * [[en:iot-open:practical:hardware:sut:stm32|]] To generate an array of bytes representing an image, it is easiest to use an online tool, e.g.: * [[https://javl.github.io/image2cpp/]] ===== 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. 64x64 pixels) and convert it to the byte array with b/w settings.\\ Sample project favicon you can use is present in Figure {{ref>iotopenfavicon}}:
{{ :en:iot-open:practical:hardware:sut:stm32:logo64.png?64 |}} IOT-OPEN.EU Reloaded favicon 64px x 64px
==== Steps ==== Remember to include the source array in the code when drawing an image.\\ The corresponding generated C array for the logo in Figure {{ref>iotopenfavicon}} (horizontal 1 bit per pixel, as suitable for ePaper Display) is present below: // 'logo64', 64x64px const unsigned char epd_bitmap_logo_64 [] PROGMEM = { 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xef, 0xff, 0xe1, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xe8, 0xff, 0xf0, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xfe, 0x5f, 0xf8, 0x7f, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xf7, 0xfc, 0x3f, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xf3, 0xfe, 0x3f, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x8f, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x8f, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xc7, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xe3, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xe3, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf1, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf1, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf9, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf8, 0xf1, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfd, 0xf8, 0xf1, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xfd, 0xf8, 0xf1, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xfd, 0xf8, 0xf1, 0xfc, 0x00, 0x1c, 0x03, 0xff, 0xfc, 0xf8, 0xf1, 0xfc, 0x00, 0x1c, 0x03, 0xfe, 0xfe, 0xf8, 0xf1, 0xff, 0xff, 0xfe, 0x07, 0xfe, 0xff, 0xf8, 0xf1, 0xff, 0xff, 0xfe, 0x07, 0xfd, 0xfd, 0xf8, 0xf1, 0xff, 0xff, 0xff, 0x9f, 0xfd, 0xfd, 0xf8, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfd, 0xf8, 0xf1, 0xff, 0xe1, 0xff, 0xff, 0xfb, 0xfd, 0xf9, 0xf1, 0xff, 0x80, 0x7f, 0xff, 0xfb, 0xf9, 0xf9, 0xf1, 0xff, 0x00, 0x3f, 0xff, 0xf7, 0xfb, 0xf1, 0xf1, 0xfe, 0x3f, 0x3f, 0xff, 0xef, 0xf3, 0xf1, 0xf1, 0xfe, 0x7f, 0x1f, 0xff, 0xcf, 0xff, 0xf3, 0xf1, 0xfc, 0x7f, 0x9f, 0xff, 0x5f, 0xef, 0xe3, 0xf1, 0xfc, 0x7f, 0x9f, 0xfe, 0xbf, 0xcf, 0xe3, 0xf1, 0xfc, 0xff, 0x9f, 0xe9, 0xff, 0xef, 0xc7, 0xf1, 0xfc, 0x7f, 0x9f, 0xef, 0xff, 0xbf, 0xc7, 0xf1, 0xfe, 0x7f, 0x9f, 0xff, 0xff, 0x3f, 0x8f, 0xf1, 0xfe, 0x3f, 0x1f, 0xff, 0xfe, 0xff, 0x8f, 0xf1, 0xff, 0x00, 0x3f, 0xff, 0xfe, 0xff, 0x1f, 0xf1, 0xff, 0x80, 0x7f, 0xff, 0xf9, 0xfe, 0x3f, 0xf1, 0xff, 0xc1, 0xff, 0xff, 0xe7, 0xfc, 0x7f, 0xf1, 0xff, 0xff, 0xff, 0xfe, 0x9f, 0xf8, 0x7f, 0xf1, 0xff, 0xff, 0xff, 0xe8, 0xff, 0xf0, 0xff, 0xf1, 0xff, 0xff, 0xbf, 0xef, 0xff, 0xe1, 0xff, 0xf1, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xc3, 0xff, 0xf1, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0x07, 0xff, 0xf1, 0xfe, 0x00, 0x03, 0xff, 0xfc, 0x1f, 0xff, 0xf1, 0xfc, 0x7f, 0x9f, 0xff, 0xf0, 0x3f, 0xff, 0xf1, 0xfc, 0xff, 0x9f, 0xff, 0x80, 0xff, 0xff, 0xf1, 0xfc, 0xff, 0x9f, 0xc0, 0x03, 0xff, 0xff, 0xf1, 0xfc, 0x7f, 0x9f, 0xc0, 0x1f, 0xff, 0xff, 0xf1, 0xfe, 0x7f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; === Step 1 === Include necessary libraries and the definition of the font. // Epaper Display libraries #include #include // Fonts #include The code above 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: // The epaper display's model is selected #define GxEPD2_DRIVER_CLASS GxEPD2_213_BN #define GxEPD2_DISPLAY_CLASS GxEPD2_BW // Definition of GPIOs except SPI pins #define EPAPER_DC_PIN D4 #define EPAPER_CS_PIN D1 #define EPAPER_RST_PIN D5 #define EPAPER_BUSY_PIN D7 // Definition of the size of the buffer #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 ePaper display controller: static GxEPD2_DISPLAY_CLASS display(GxEPD2_DRIVER_CLASS(/*CS=*/ EPAPER_CS_PIN, /*DC=*/ EPAPER_DC_PIN, /*RST=*/ EPAPER_RST_PIN, /*BUSY=*/ EPAPER_BUSY_PIN)); You can also declare a message to display as an array of characters: static const char HelloWorldMsg[] = "Hello IoT World!"; === Step 4 === Configure GPIOs and initialise the ePaper controller class. It uses the standard SPI connection. pinMode(EPAPER_CS_PIN, OUTPUT); pinMode(EPAPER_RST_PIN, OUTPUT); pinMode(EPAPER_DC_PIN, OUTPUT); pinMode(EPAPER_BUSY_PIN,INPUT_PULLUP); digitalWrite(EPAPER_CS_PIN,LOW); display.epd2.selectSPI(SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0)); \\ Delay here is to ensure a stable CS signal before SPI data sending delay(100); display.init(115200); digitalWrite(EPAPER_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 and calculate the starting point ''(x, y)'' for the centred text: int16_t tbx, tby; uint16_t tbw, tbh; display.getTextBounds(HelloWorldMsg, 0, 0, &tbx, &tby, &tbw, &tbh); uint16_t x = ((display.width() - tbw) / 2) - tbx; //center in x arrow uint16_t y = ((display.height() - tbh) / 4) - tby; //one fourth from the top === Step 6 === Then display the contents of the image and the text in the ePaper display: display.setFullWindow(); display.fillScreen(GxEPD_WHITE); display.setCursor(x, y); display.print(HelloWorldMsg); display.display(true); display.drawImage((uint8_t*)epd_bitmap_logo_64,0,0,64,64); 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 ===== {{:en:iot-open:logo_iot_200_px.png?200|}}\\ 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 [[https://en.wikipedia.org/wiki/Creative_Commons_license|Creative Commons Licence]], free for Non-Commercial use.
{{:en:iot-open:ccbync.png?100|}}