MH-ET Live partial update with GxEPD2

Hello! I'm testing an MH-ET Live 2.9" E-paper display (BW) with ESP32-WROOM (D1 MINI). I have a very simple test code using this example: E-paper display using partial updates | Arduino Project Hub

The code differs in that I don't have a Waveshare board and so not a V2 definition but the panel should be similar. At least the type seems to match the definition of 290_T94 and printing text works after full update.

Partial update does work but there are some issues. Some characters get corrupted or rather they do not get updated properly (see attached image). Any idea what could cause this? The image is just one example and the "corrupted" character is mostly in the same position while the other characters update just fine. It's not always (but it is most often) the last character either but it always is only one of them.

Weird thing is that when I use a much smaller font (eg. u8g2_font_7x14_tr), there is no issue.

I have tested a full screen partial update and that does not solve the issue so it's not about the partial update window size.

Also in my code the header has a couple of additional definitions of which I'm not sure what is the purpose or are they actually needed or even the cause if this behaviour. I've also looked at some of the GxEPD2 examples but they're very comprehensive and I really need a simplified example to test with. I like to understand the code I'm using.

Arduino IDE and all the libraries are the latest versions. Oh and I'm mostly a hardware guy, very experienced in electronics but not so much in coding.

#include <GxEPD2_BW.h>
#include <U8g2_for_Adafruit_GFX.h>
#define EPD_SS 5
#define EPD_DC 10
#define EPD_RST 26
#define EPD_BUSY 13
#define MAX_DISPLAY_BUFFER_SIZE 800
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_290_T94, MAX_HEIGHT(GxEPD2_290_T94)>

display(GxEPD2_290_T94(EPD_SS, EPD_DC, EPD_RST, EPD_BUSY)); //GxEPD2_290_T94 -> MH ET Live 2.9" B/W

U8G2_FOR_ADAFRUIT_GFX  u8g2Fonts;

void setup()
{
  display.init(115200);

//For partial update test
  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);  // 20px font
    u8g2Fonts.setCursor(20, 80);
    u8g2Fonts.print("Millis: ");
    }while (display.nextPage());

}

void loop() {
// For partial update test

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

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

  delay(2000);

}

Try this:

void loop() {
// For partial update test

  display.setPartialWindow(115, 50, 200, 40);
  display.firstPage();
  unsigned long timeNow = millis();
  do {
    display.fillScreen(GxEPD_WHITE);
    u8g2Fonts.setCursor(120, 80);
    u8g2Fonts.print(timeNow);
  }while(display.nextPage());

  delay(2000);

}

@Pete4 Hi,

It is always a good idea to start with an example of the library you use.
GxEPD2/examples/GxEPD2_Example at master · ZinggJM/GxEPD2 · GitHub
There you might take a look at GxEPD2_display_selection_new_style.h and at the different driver classes supported for you display size:

//#define GxEPD2_DRIVER_CLASS GxEPD2_290     // GDEH029A1   128x296, SSD1608 (IL3820), (E029A01-FPC-A1 SYX1553)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T5  // GDEW029T5   128x296, UC8151 (IL0373), (WFT0290CZ10)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T5D // GDEW029T5D  128x296, UC8151D, (WFT0290CZ10)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_I6FD // GDEW029I6FD  128x296, UC8151D, (WFT0290CZ10)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T94 // GDEM029T94  128x296, SSD1680, (FPC-7519 rev.b)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T94_V2 // GDEM029T94  128x296, SSD1680, (FPC-7519 rev.b), Waveshare 2.9" V2 variant
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_BS // DEPG0290BS  128x296, SSD1680, (FPC-7519 rev.b)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_M06 // GDEW029M06  128x296, UC8151D, (WFT0290CZ10)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_GDEY029T94 // GDEY029T94 128x296, SSD1680, (FPC-A005 20.06.15)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_GDEY029T71H // GDEY029T71H 168x384, SSD1685, (FPC-H004 22.03.24)

compare the inking on the flexible connector of the panel with the inkings mentioned in (..)

Most likely these are for your panel

//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T94_V2 // GDEM029T94  128x296, SSD1680, (FPC-7519 rev.b), Waveshare 2.9" V2 variant
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_BS // DEPG0290BS  128x296, SSD1680, (FPC-7519 rev.b)

they are identical, from the symptoms you mention.
But from the picture you have a panel from Good Display with wavetable for differential refresh in OTP.

Hi @PaulRB , yes, you found the reason!

A value printed in the page loop should not change inside the loop.

A small display panel with ESP32 should not need paged display, but is forced here with

which would be for Arduino UNO, e.g.

Thanks! That makes sense, I'll try that tomorrow as well as a different panel definition (after checking the flex print). Thanks to @PaulRB too!

Yes, actually that part of the example code is for an Arduino board. So for ESP32 I can just remove that line and maybe also thís one:

#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))

Is the differential refresh something I need to take into account?

Not with your display.
You selected the correct display driver for your panel. My guess was wrong.

Waveshare (and some other sellers) use a different panel that doesn't have the waveform table for differential refresh in the controller's OTP, but need the driver code to load that into controller registers.
Unfortunately, there are 3 versions, 2 different, with the same inking.

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