Dear people,
I am working with the GxEPD library of @ZinggJM and it has thus far saved my life. I am busy working on my Thesis project in which I am printing strings of text ("Tasks") to the E-ink display. However, once my display has done a partial update it slows my void loop considerably. While I only call the partial update when there is a new task. The display powers down after 1 minute of inactivity, and does a full refresh after receiving a task then. Even after the powerdown, my loop is still slowed. Because the display is part of a bigger project using NFC and Bluetooth among other things, it is important my loop is not slowed too much. Does anyone have an idea what it could be?
My display: https://www.waveshare.com/2.9inch-e-paper-module.htm
Display library: #include <GxDEPG0290BS/GxDEPG0290BS.h> 2.9" b/w Waveshare
Working with Arduino Mega 2560.
The code below shows all the relevant code regarding the E-ink display:
#include <Wire.h>
#include <Adafruit_PN532.h>
#include <EEPROM.h>
#include <GxEPD.h>
#include <Adafruit_GFX.h>
// Display libraries
#include <GxDEPG0290BS/GxDEPG0290BS.h> //2.9" b/w Waveshare
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include "displayBitmaps.h"
// Initialization Display pins
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9);
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7);
const char* name = "FreeMonoBold9pt7b";
const GFXfont* displayFont = &FreeMonoBold9pt7b;
String Task = "";
unsigned long lastTimeTextPrinted = 0;
const unsigned long displayResetInterval = 5000;
bool blankDisplaySet = false;
unsigned long lastInteractionTime = 0;
const unsigned long displayPowerdownInterval = 60000; // 1 minute
Void setup() {
Serial.begin(38400); // Serial in IDE
Serial.println("Serial setup complete");
//Display init
display.init(38400);
showPartialUpdatePaged();
Serial.println("Display initialized");
}
My functions in the loop relevant for the E-ink display:
void loop() {
newLoop = millis();
Serial.print("Result newLoop - lastLoop = ");
Serial.println(newLoop - lastLoop);
lastLoop = millis();
/*If new task received:*/processReceivedTask();
setBlankDisplay();
powerdownDisplay();
}
My functions:
// Function to process received tasks
void processReceivedTask() {
Task = currentMessage.substring(1); // Removes the "T"
currentMessage = "";
taskPaired = false;
Serial.println("Received task: " + Task);
const char* text = Task.c_str();
display.drawPagedToWindow(showTextInBox, 20, 20, 256, 88, text);
}
void showTextInBox(const char* text)
{
uint16_t box_x = 20;
uint16_t box_y = 0;
uint16_t box_w = 276;
uint16_t box_h = 128;
uint16_t textHeight = 18; // Adjust according to your font size
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
String line = "";
String word = "";
// Calculate the number of lines needed to display the text
int numLines = 1; // Start with at least one line
for (size_t i = 0; i < strlen(text); i++) {
if (text[i] == ' ' || text[i] == '\0') {
if (line.length() + word.length() + 1 <= 22) {
line += " ";
line += word;
} else {
numLines++; // Increment line count
line = word; // Start new line
}
word = ""; // Reset word
} else {
word += text[i];
}
}
// Calculate vertical offset to center the text
uint16_t totalTextHeight = numLines * textHeight;
uint16_t cursor_y = box_y + (box_h - totalTextHeight) / 2 + textHeight; // Center vertically
// Reset the line and word variables for actual printing
line = "";
word = "";
// Print the text with line breaks
for (size_t i = 0; i < strlen(text); i++) {
if (text[i] == ' ' || text[i] == '\0') {
if (line.length() + word.length() + 1 <= 22) {
if (line.length() > 0) {
line += " ";
}
line += word;
} else {
// Print the current line
display.setCursor(box_x, cursor_y);
display.print(line);
cursor_y += textHeight; // Move cursor down for the next line
line = word; // Start new line
}
word = ""; // Reset word
} else {
word += text[i]; // Add character to word
}
}
// Print the last line if any
if (line.length() > 0) {
if (line.length() + word.length() + 1 <= 22) {
if (line.length() > 0) {
line += " ";
}
line += word;
}
display.setCursor(box_x, cursor_y);
display.print(line);
}
lastTimeTextPrinted = millis();
blankDisplaySet = false;
}
void showPartialUpdatePaged()
{
uint16_t box_x = 20;
uint16_t box_y = 0;
uint16_t box_w = 276;
uint16_t box_h = 128;
String startup = "System Started";
const char* text = startup.c_str();
display.setFont(displayFont);
display.setTextColor(GxEPD_BLACK);
// draw background
display.drawExampleBitmap(whiteBackground, sizeof(whiteBackground));
// partial update to full screen to preset for partial update of box window (this avoids strange background effects)
display.drawExampleBitmap(whiteBackground, sizeof(whiteBackground), GxEPD::bm_partial_update);
// show updates in the update box
// reset the background
display.drawExampleBitmap(whiteBackground, sizeof(whiteBackground), GxEPD::bm_partial_update);
display.setRotation(1);
display.drawPagedToWindow(showTextInBox, box_x, box_y, box_w, box_h, text);
}
void setBlankDisplay(){
if (!blankDisplaySet){
if (millis() - lastTimeTextPrinted >= displayResetInterval) {
lastTimeTextPrinted = millis();
display.drawExampleBitmap(whiteBackground, sizeof(whiteBackground), GxEPD::bm_default | GxEPD::bm_partial_update);
blankDisplaySet = true;
}
}
}
void powerdownDisplay(){
if (millis() - lastInteractionTime >= displayPowerdownInterval) {
lastInteractionTime = millis();
display.drawExampleBitmap(whiteBackground, sizeof(whiteBackground), GxEPD::bm_default | GxEPD::bm_partial_update);
display.powerDown();
}
}
My Serial output:
_PowerOn : 91944
_Update_Full : 5097924
_Update_Part : 734740
_Update_Part : 734908
_Update_Part : 734336
Display initialized
Result newLoop - lastLoop = 14678
Result newLoop - lastLoop = 56
Result newLoop - lastLoop = 57
Result newLoop - lastLoop = 57
Result newLoop - lastLoop = 56
//etc...
Received task: task 1
_Update_Part : 734444 //Printing task
Result newLoop - lastLoop = 6484
Result newLoop - lastLoop = 521
Result newLoop - lastLoop = 520
Result newLoop - lastLoop = 520
Result newLoop - lastLoop = 521
Result newLoop - lastLoop = 521
Result newLoop - lastLoop = 520
Result newLoop - lastLoop = 520
Result newLoop - lastLoop = 520
_Update_Part : 734964 //setBlankDisplay function
Result newLoop - lastLoop = 2040
Result newLoop - lastLoop = 521
Result newLoop - lastLoop = 520
Result newLoop - lastLoop = 521
Result newLoop - lastLoop = 521
Result newLoop - lastLoop = 520
Result newLoop - lastLoop = 520
//etc...
I want to thank you in advance! I hope I have provided all the necessary information.
Sanne