Partial updates on Waveshare 2.66" E-paper

I have a Waveshare 2.66" E-paper display. I have set it up according to Waveshare's guide using Waveshare's library, found here.

I'm trying to display three words, each on their own line. The first word should appear, then the second, then the third, with the previous words remaining visible. Instead, I see the previous word disappears when I display the new word. I understand this display supports partial updates.

I ran the library demo code and experimented to better understand it. My code is below. I've commented it with my understanding of what each line is doing. I'd be grateful to learn where I'm going wrong.

#include <SPI.h>
#include "epd2in66.h"
#include "imagedata.h"
#include "epdpaint.h"

#define COLORED     0
#define UNCOLORED   1

UBYTE image[600]; // create a 1D array
Paint paint(image, 56, 20);    // make array 2D with defined width and height, this is the image buffer, width should be the multiple of 8 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // initialize serial
  Epd epd; // initialize display
  if (epd.Init() != 0) { // if display initialize hasn't worked...
    Serial.print("e-Paper init failed..."); // ...tell the user
    return;
  }
 
  paint.SetRotate(ROTATE_0);  // use default screen orientation
  epd.Clear();  // clear physical display
  epd.Init_Partial();   // enable partial update functionality

  paint.Clear(COLORED);   // set all image buffer pixels to black
  paint.DrawStringAt(0, 0, "HELLO", &Font16, UNCOLORED); // write text to image buffer, coordinates define where to start writing in the buffer
  epd.DisplayFrame_part(paint.GetImage(),0,0,56,20); // at defined location and area, update this part of the screen with the image buffer 
  delay(1000);
  paint.Clear(COLORED);
  paint.DrawStringAt(0, 0, "HEY", &Font16, UNCOLORED);
  epd.DisplayFrame_part(paint.GetImage(),0,30,56,20);
  delay(1000);
  paint.Clear(COLORED);
  paint.DrawStringAt(0, 0, "HI", &Font16, UNCOLORED);
  epd.DisplayFrame_part(paint.GetImage(),0,60,56,20);
}
  
void loop() {
  // put your main code here, to run repeatedly:
}

You'd have to look the specifications up by the model number to be sure.

I believe that 'Partial Update' is something you have to call special functions for.

I've checked the product page, it says partial refresh is supported.

As far as I can see epd.Init_Partial() and epd.DisplayFrame_part are the only special partial update functions.

Using the GxEPD2_BW library and this https://create.arduino.cc/projecthub/galoebn/e-paper-display-using-partial-updates-a8af20 I was able to get partial updates working.

I've just installed that library and the example you linked. I edited line 8 to use the 2.66" display included in the GxEPD2 library but it isn't exactly the same model I have. When I try to compile I get a 'Global variables use 6236 bytes (304%) of dynamic memory' error.

#define ENABLE_GxEPD2_GFX 0

#include <GxEPD2_BW.h> // including both doesn't use more code or ram
#include <GxEPD2_3C.h> // including both doesn't use more code or ram
#include <U8g2_for_Adafruit_GFX.h>

//if you have another microcontroller or another e-ink display module you have to change the following line
GxEPD2_BW<GxEPD2_266_BN, GxEPD2_266_BN::HEIGHT> display(GxEPD2_266_BN(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEM029T94, Waveshare 2.9" V2 variant

U8G2_FOR_ADAFRUIT_GFX u8g2Fonts;

void setup()
{
  display.init();
  display.setTextColor(GxEPD_BLACK);
  display.firstPage();
  display.setRotation(1);

  u8g2Fonts.begin(display); // connect u8g2 procedures to Adafruit GFX
  delay(1000);

  uint16_t bg = GxEPD_WHITE;
  uint16_t fg = GxEPD_BLACK;
  u8g2Fonts.setForegroundColor(fg);         // apply Adafruit GFX color
  u8g2Fonts.setBackgroundColor(bg);

  do{
    display.fillScreen(GxEPD_WHITE);

    u8g2Fonts.setFont(u8g2_font_fub20_tr);   //font is set
    u8g2Fonts.setCursor(20, 80);             //cursor(x,y)
    u8g2Fonts.print("Millis: ");   //print the text
  }while (display.nextPage());
}


void loop() {
  display.setPartialWindow(115, 50, 200, 40);
  display.firstPage();

  do{
    display.fillScreen(GxEPD_WHITE);
    u8g2Fonts.setCursor(120, 80);
    u8g2Fonts.print(millis());
  }while(display.nextPage());
}

Please consider reading GxEPD2 README.md, section Paged Drawing, Picture Loop.

@ZinggJM thanks for your response, I have read the readme and the article within on picture loops.

I understand I need to reduce the buffer size for my Arduino Uno. I'm trying to understand how and where this is set, this is beyond my current coding knowledge. I see in GxEPD2_BW.h that page height is the second input where the template is defined. In my code above that would be GxEPD2_266_BN::HEIGHT.

I've never seen :: before, I think it's the height within the scope of GxEPD2_266_BN.

When I right click and 'Go to definition' I see it's defined as 296 and it's read only.

I'm feeling quite lost but hopefully going in the right direction.

GxEPD2_Example and GxEPD2_HelloWorld both have a GxEPD2_display_selection.h and a GxEPD2_display_selection_new_style.h that show how to do this and do it for you.

Yes, you would simply use a (small enough) fraction of GxEPD2_266_BN::HEIGHT instead. Or any other value except zero.

I now have GxEDP2_HelloWorld working and I've modified it to draw a few shapes, do full or partial updates and so on. I had tried this before, but it made a lot more sense having read up on paged drawing.

I think I have what I need to progress my project now. Thank you for your support :slightly_smiling_face:

@Racer_Rob ,Thank you for the feedback!

It might be useful for other readers, if you answer the questions I usually ask:
Please post a link to the e-paper display you use, and report the processor/board, with a link if not a standard Arduino.

Jean-Marc

@ZinggJM , certainly, the display is a Waveshare 2.66inch 296x152 and my board is a standard Arduino Uno R3.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.