Waveshare e-paper displays with SPI

@jerdavismn,

I can't help you, as I don't have this display.

The class GxEPD2_290_T94 uses the OTP waveform tables in the SSD1680 controller for both full refresh and partial refresh. These OTP waveforms are programmed by the manufacturer for the specific panel used. You can take a look at the Good Display demo for the GDEM0266T90, to see if they also use OTP for differential refresh, or program the waveform table to registers. Or if they don't use differential refresh at all.

I don't want to spend time on a display I don't have.

Jean-Marc

Added: you could enable diagnostic output of the library.

I was able to get diagnostic mode on. I have not had much luck deciphering differences between the sample code from Good Displays and what's built in.

Pulling from another example you helped with I tried adding a command that did a full write before the one that did partial updates. Here's the updated sketch.

#define ENABLE_GxEPD2_GFX 0
#include <GxEPD2_BW.h>
#include <U8g2_for_Adafruit_GFX.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

#define MAX_DISPLAY_BUFFER_SIZE 800 
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_266_T90, GxEPD2_266_T90::HEIGHT> display(GxEPD2_266_T90(/*CS=D8*/ 15, /*DC=D3*/ 4, /*RST=D4*/ 2, /*BUSY=D2*/ 5)); // GDEM0266T90

U8G2_FOR_ADAFRUIT_GFX u8g2Fonts;

const char* ssid     = "...";
const char* password = "...";

void setup()
{
  Serial.begin(115200);
  if (!WiFi.getAutoConnect() || ( WiFi.getMode() != WIFI_STA) || ((WiFi.SSID() != ssid) && String(ssid) != "........"))
  {
    WiFi.mode(WIFI_STA); // switch off AP
    WiFi.begin(ssid, password);
    delay(1000);
  }

  display.init(115200);
  u8g2Fonts.begin(display); // connect u8g2 procedures to Adafruit GFX
}

void loop()
{
  displayBoot();
  delay(2000);
  displayValues();
  delay(300);  
}

void displayBoot()
{
  display.setFullWindow();
  display.setRotation(1); // 0--> No rotation ,  1--> rotate 90 deg
  uint16_t bg = GxEPD_WHITE;
  uint16_t fg = GxEPD_BLACK;
  u8g2Fonts.setFontMode(1);                 // use u8g2 transparent mode (this is default)
  u8g2Fonts.setFontDirection(0);            // left to right (this is default)
  u8g2Fonts.setForegroundColor(fg);         // apply Adafruit GFX color
  u8g2Fonts.setBackgroundColor(bg);         // apply Adafruit GFX color
  u8g2Fonts.setFont(u8g2_font_logisoso20_tf); //u8g2_font_logisoso32_tn--->numbers only to save memory ; u8g2_font_logisoso32_tr , u8g2_font_logisoso32_tf -->numbers&letters
  uint16_t x = 50;  // ((display.width() - tbw) / 2) - tbx;
  uint16_t y = 122; // ((display.height() - tbh) / 2) - tby;
  

  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    u8g2Fonts.setCursor(10,70);
    u8g2Fonts.print("Depth display starting...");
  }
  while (display.nextPage());
}

void displayValues()
{
  int depth;
  int speed;
  
  if (WiFi.status() == WL_CONNECTED)
  {
    HTTPClient http;
    http.begin("http://192.168.0.127:1880/data/boat.json");
    int httpCode = http.GET();

    if (httpCode > 0)
    {
      const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 370;
      DynamicJsonDocument doc(bufferSize);
      deserializeJson(doc, http.getString());
 
      depth = atoi(doc["depth"]); 
      speed = atoi(doc["speed"]); 
 
      Serial.print("Depth:");
      Serial.println(depth);
      Serial.print("Speed:");
      Serial.println(speed);
    }
    delay(300);
  }
  
  display.setRotation(1); // 0--> No rotation ,  1--> rotate 90 deg
  uint16_t bg = GxEPD_WHITE;
  uint16_t fg = GxEPD_BLACK;
  u8g2Fonts.setFontMode(1);                 // use u8g2 transparent mode (this is default)
  u8g2Fonts.setFontDirection(0);            // left to right (this is default)
  u8g2Fonts.setForegroundColor(fg);         // apply Adafruit GFX color
  u8g2Fonts.setBackgroundColor(bg);         // apply Adafruit GFX color
  u8g2Fonts.setFont(u8g2_font_logisoso92_tn); //u8g2_font_logisoso32_tn--->numbers only to save memory ; u8g2_font_logisoso32_tr , u8g2_font_logisoso32_tf -->numbers&letters
  //Serial.println(display.hasFastPartialUpdate());
  int16_t tbx, tby; uint16_t tbw, tbh;
  uint16_t x = ((display.width() - tbw) / 2) - tbx;
  uint16_t y = ((display.height() - tbh) / 2) - tby;
  
  // Display A0 value
  //#define width u8g2Fonts.getUTF8Width("20")
  //#define display_width  (180 - width)
  display.setPartialWindow(10, 10, 296, 152); //this sets a window for the partial update, so the values can update without refreshing the entire screen.
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    u8g2Fonts.setCursor(x,y);
    u8g2Fonts.print(depth);
    u8g2Fonts.setFont(u8g2_font_logisoso20_tf);
    u8g2Fonts.setCursor(200,90);
    u8g2Fonts.println("depth");
    u8g2Fonts.setCursor(200,y);
    u8g2Fonts.println("feet");
  }
  while (display.nextPage());
}

Here is the diagnostic output.

connected with magrathea, channel 8
dhcp client start...
_PowerOn : 94564
ip:192.168.0.42,mask:255.255.255.0,gw:192.168.0.1
_Update_Full : 3288232
_PowerOff : 140808
:ref 1
:wr 183 0
:wrc 183 183 0
:ack 183
:rn 293
:c0 1, 293
Depth:20
Speed:7
:close
:ur 1
:dsrcv 0
:del
_PowerOn : 95101
_Update_Part : 94555
pm open,type:2 0
_Update_Full : 3288312
_PowerOff : 139983
:ref 1
:wr 183 0
:wrc 183 183 0
:ack 183
:rn 293
:c0 1, 293
Depth:12
Speed:7
:close
:ur 1
:dsrcv 0
:del
_PowerOn : 94736
_Update_Part : 94351
_Update_Full : 3287927
_PowerOff : 140724
:ref 1
:wr 183 0
:wrc 183 183 0
:ack 183
:rn 292
:c0 1, 292
Depth:5
Speed:8
:close
:ur 1
:dsrcv 0
:del
_PowerOn : 94843
_Update_Part : 94566
_Update_Full : 3287834
_PowerOff : 140112

Is there a process to get you a display if that would aid in having this supported? Is that an option?

Yes, you could tell me in a personal message your intention to donate that display, then I will answer with my address.

Thank you for the information. Your partial update times are way too short, e.g. _Update_Part : 94555
It should be about or higher than the one for GDEM029T94, see in GxEPD2_290_T94.h:

    static const uint16_t full_refresh_time = 3200; // ms, e.g. 3154996us
    static const uint16_t partial_refresh_time = 500; // ms, e.g. 458231us

Either the controller in your panel doesn't have waveform tables for differential refresh, or it detected no difference. It may have a second set of waveform tables for something else, e.g. grey levels.

Explanation: the controller SSD1680 has one bit to select between two refresh modes, selecting one of two wavetable sets, afaik.

I assume you checked your output works with setFullWindow().

Please also check with the example GxEPD2_Example.ino. Does partial update work with this?

Jean-Marc

Thanks for the hint. Let me share my experience with this issue:

I was struggling with the 7.5inch display and waveshare e-paper hat for days! I was totally mental from this as the hat worked fine with 2.9inch displays but refused to work with the 7.5inch one. So my wiring was fine but it didn't work. On the other hand the 7.5inch display worked fine with the waveshare example library so it was really confusing.

Changing the reset time duration didn't help but as I was messing around with the PCB I tried to bypass the 3.3V regulator on the HAT (short pin 1 and 5 on the 5pin little sucker...). And it worked! I feel stupid for not discovering this sooner but I didn't suspect this as the 2.9inch display worked fine....

It also started working in ESPhome integration for Home assistant

Hi,

I am trying to use 1.54 Inch epaper display with SPI connection.

I have a couple of questions.
Is the reset and _Busy pins mandatory to get to use the display?

I have the port of SPI with Vcc GND MOSI MISO CS CLK.
Is this sufficient ?

I understand that RST and BUSY needs to be connected as GPIOs. But is it possible to use the display without these pins?

I am using a Kinetis K10 controller and established the connectiion using SPI.
Regardless of the Command or the data that I send, I am getting only noise dots on the screen.

The SPI transfer is sucessfully completed for every command and data but I am not able to clear the screen at all.

@viveknaththulasi, Hi,

welcome to the forum! Please read How to get the best out of this forum, if you haven't done yet.

I am used to get riddles as questions by first time posters. Sometimes I can guess, but I can't guess all.

From your picture I know what e-paper you use, but it would help all readers if you post a link.

You tell that you send commands and data to the display, but you don't tell what you send.
Do you use a library, and if yes, which library? Else it comes as no surprise you only get garbage.

Did your display refresh, e.g. flicker and update the noise display?

Jean-Marc

You can do without RST (pull-up high), as long as you don't use deep sleep of the display.
You can do without BUSY, if you wait long enough for commands such as refresh or power-on to terminate.

Hi @ZinggJM ,

Sorry for giving abstract infomation at first.

1.54inch e-Paper V2 version : https://www.waveshare.com/wiki/1.54inch_e-Paper_Module

I modified this library for my needs : e-Paper/EPD_1in54_V2.c at master · waveshare/e-Paper · GitHub

I am trying to initialize and clear the screen for displaying further useful information.
Attached the steps

Steps;

	_txBuffer[0] = 0x12;//SWRESET
	stat = EpdSend(_txBuffer,0,1);

	_txBuffer[0] = 0x01;//Driver output control
	stat = EpdSend(_txBuffer,0,1);

	_txBuffer[0] = 0xc7;
	_txBuffer[1] = 0x00;
	_txBuffer[2] = 0x00;
	stat = EpdSend(_txBuffer,1,3);

	_txBuffer[0] = 0x11;//Data entry sequence setting
	stat = EpdSend(_txBuffer,0,1);

	_txBuffer[0] = 0x00;
	_txBuffer[1] = 0x01;
	stat = EpdSend(_txBuffer,0,2);

	_txBuffer[0] = 0x01;
	_txBuffer[1] = 0x00;
	_txBuffer[2] = 0x00;
	stat = EpdSend(_txBuffer,1,3);

//
	_txBuffer[0] = 0x44;//set RAM-X address start/end Position
	stat = EpdSend(_txBuffer,0,1);

	_txBuffer[0] = 0x00;
	_txBuffer[1] = 0x18;
	stat = EpdSend(_txBuffer,1,2);

	_txBuffer[0] = 0x45;//set RAM-Y address start/end Position
	stat = EpdSend(_txBuffer,0,1);

	_txBuffer[0] = 0xc7;
	_txBuffer[1] = 0x00;
	_txBuffer[2] = 0x00;
	_txBuffer[3] = 0x00;
	stat = EpdSend(_txBuffer,1,4);

	_txBuffer[0] = 0x3C;//Detect temperature
	stat = EpdSend(_txBuffer,0,1);


	_txBuffer[0] = 0x01;
	stat = EpdSend(_txBuffer,1,1);

	_txBuffer[0] = 0x18;//Border Waveform
	stat = EpdSend(_txBuffer,0,1);


	_txBuffer[0] = 0x80;
	stat = EpdSend(_txBuffer,1,1);

EpdSend function	
status_t EPaperDisplay::EpdSend(uint8_t *bytes, uint8_t dataOrCmd,uint8_t datalength) {
	status_t stat;

	GPIO_ClearPinsOutput(BOARD_INITPINS_DSPI0_CS_GPIO, BOARD_INITPINS_DSPI0_CS_GPIO_PIN_MASK);
	if(dataOrCmd == 0)//cmd
		GPIO_ClearPinsOutput(BOARD_INITPINS_DSPI0_DC_GPIO, BOARD_INITPINS_DSPI0_DC_GPIO_PIN_MASK);
	else//data
		GPIO_SetPinsOutput(BOARD_INITPINS_DSPI0_DC_GPIO, BOARD_INITPINS_DSPI0_DC_GPIO_PIN_MASK);

	stat = _spi0_instance.TransferData(bytes, datalength);

	GPIO_SetPinsOutput(BOARD_INITPINS_DSPI0_CS_GPIO, BOARD_INITPINS_DSPI0_CS_GPIO_PIN_MASK);
vTaskDelay(pdMS_TO_TICKS(2));

	return stat;
}

What would be the Ideal time to wait between each command?

I am getting different noise each time I send the signal.
Also I get a blink of black border on the Screen on every execution.
After all the steps mentioned in the list, I clear and display the screen.
Baudrate of SPI : 600K

You can find some measured BUSY times here: GxEPD2_154_D67.h.

10ms after SW reset, according to specs.

You didn't answer about refresh, and I don't see any refresh command in your code snippet.
I don't intend to analyze your code, sorry.

I am getting different noise each time I send the signal.
Also I get a blink of black border on the Screen on every execution.
After all the steps mentioned in the list, I clear and display the screen.
Baudrate of SPI : 600K

Aha, didn't notice this addition.

Version 1.3.4 of library GxEPD2 is available, install or update with Library Manager.

  • added support for GDEH116T91 960x640 b/w e-paper panel
  • GDEH116T91 has only full screen refresh, no wavetable for differential refresh yet
  • added support for processor Arduino Nano RP2040 Connect to the examples
  • added general fast b/w refresh for capable 3-color displays GDEW0213Z19, GDEW029Z13
  • added example GxEPD2x_FastBlackWhiteOnColor.ino for GDEW0213Z19, GDEW029Z13
  • evaluation of other fast b/w capable 3-color panels may follow

Jean-Marc

Added: support for GDEH116T91 is thanks to the panel donated by @frightanic.

Hi @ZinggJM
Thank you for your library and effortless support. I bought a 7.5 inch B/W HD ePaper from Waveshare, which is not supported at this moment. Do you think there is any workaround how to use this display with current GxEPD2 library or I have to wait until will be fully supported?

@panEarth, Hi, welcome back!

You need to find out which controller your panel uses, e.g. on the Good Display website.
Then look if there is a b/w panel supported with the same controller (there is one!).
There is a good chance you just need to change the WIDTH and HEIGHT in the header of the driver class for this panel.

Fortunately I added controller names recently to this file: GxEPD2/GxEPD2_display_selection_new_style.h at master · ZinggJM/GxEPD2 · GitHub.

BTW: hint: b/w and b/w/r panels of same dimension quite often use the same controller.

Good Luck!

Jean-Marc

Hi Jean-Marc, thanks for your work on the library! I've been working on a 7.5" v2 board (750_T7). It works fine on a Raspberry Pi, so I know the wiring is ok and the controller functional.

[edit] Also got the good-display example code working now on a 'Arduino 33 Sense' board:

#include"Ap_29demo.h"
//IO settings
int BUSY_Pin = 8; 
int RES_Pin = 9; 
int DC_Pin = 10; 
int CS_Pin = 7; 
int SCK_Pin = 13; 
int SDI_Pin = 11; 

#define EPD_W21_MOSI_0  digitalWrite(SDI_Pin,LOW)
#define EPD_W21_MOSI_1  digitalWrite(SDI_Pin,HIGH) 

#define EPD_W21_CLK_0 digitalWrite(SCK_Pin,LOW) 
#define EPD_W21_CLK_1 digitalWrite(SCK_Pin,HIGH)

#define EPD_W21_CS_0 digitalWrite(CS_Pin,LOW)
#define EPD_W21_CS_1 digitalWrite(CS_Pin,HIGH)

#define EPD_W21_DC_0  digitalWrite(DC_Pin,LOW)
#define EPD_W21_DC_1  digitalWrite(DC_Pin,HIGH)
#define EPD_W21_RST_0 digitalWrite(RES_Pin,LOW)
#define EPD_W21_RST_1 digitalWrite(RES_Pin,HIGH)
#define isEPD_W21_BUSY digitalRead(BUSY_Pin)
////////FUNCTION//////
void driver_delay_us(unsigned int xus);
void driver_delay_xms(unsigned long xms);
void DELAY_S(unsigned int delaytime);     
void SPI_Delay(unsigned char xrate);
void SPI_Write(unsigned char value);
void EPD_W21_WriteDATA(unsigned char command);
void EPD_W21_WriteCMD(unsigned char command);
//EPD
void EPD_W21_Init(void);
void EPD_init(void);
void PIC_display1(void);
void EPD_sleep(void);
void EPD_refresh(void);
void lcd_chkstatus(void);
void PIC_display_Clean(void);
unsigned char HRES,VRES_byte1,VRES_byte2;

void setup() {
   pinMode(BUSY_Pin, INPUT); 
   pinMode(RES_Pin, OUTPUT);  
   pinMode(DC_Pin, OUTPUT);    
   pinMode(CS_Pin, OUTPUT);    
   pinMode(SCK_Pin, OUTPUT);    
   pinMode(SDI_Pin, OUTPUT);    
}


//Tips//
/*When the electronic paper is refreshed in full screen, the picture flicker is a normal phenomenon, and the main function is to clear the display afterimage in the previous picture.
  When the local refresh is performed, the screen does not flash.*/
/*When you need to transplant the driver, you only need to change the corresponding IO. The BUSY pin is the input mode and the others are the output mode. */


void loop() {
  while(1)
  {
    //PICTURE1
    EPD_init(); //EPD init
    PIC_display1();
    EPD_refresh();//EPD_refresh   
    EPD_sleep();//EPD_sleep,Sleep instruction is necessary, please do not delete!!!
    delay(5000);
    
    //PICTURE Clean
     EPD_init(); //EPD init
    PIC_display_Clean();
    EPD_refresh();//EPD_refresh   
    EPD_sleep();//EPD_sleep,Sleep instruction is necessary, please do not delete!!!
    while(1);

  }
}




///////////////////EXTERNAL FUNCTION////////////////////////////////////////////////////////////////////////
/////////////////////delay//////////////////////////////////////
void driver_delay_us(unsigned int xus)  //1us
{
  for(;xus>1;xus--);
}
void driver_delay_xms(unsigned long xms) //1ms
{  
    unsigned long i = 0 , j=0;

    for(j=0;j<xms;j++)
  {
        for(i=0; i<256; i++);
    }
}
void DELAY_S(unsigned int delaytime)     
{
  int i,j,k;
  for(i=0;i<delaytime;i++)
  {
    for(j=0;j<4000;j++)           
    {
      for(k=0;k<222;k++);
                
    }
  }
}
//////////////////////SPI///////////////////////////////////
void SPI_Delay(unsigned char xrate)
{
  unsigned char i;
  while(xrate)
  {
    for(i=0;i<2;i++);
    xrate--;
  }
}


void SPI_Write(unsigned char value)                                    
{                                                           
    unsigned char i;  
   SPI_Delay(1);
    for(i=0; i<8; i++)   
    {
        EPD_W21_CLK_0;
       SPI_Delay(1);
       if(value & 0x80)
          EPD_W21_MOSI_1;
        else
          EPD_W21_MOSI_0;   
        value = (value << 1); 
       SPI_Delay(1);
       driver_delay_us(1);
        EPD_W21_CLK_1; 
        SPI_Delay(1);
    }
}

void EPD_W21_WriteCMD(unsigned char command)
{
  SPI_Delay(1);
  EPD_W21_CS_0;                   
  EPD_W21_DC_0;   // command write
  SPI_Write(command);
  EPD_W21_CS_1;
}
void EPD_W21_WriteDATA(unsigned char command)
{
  SPI_Delay(1);
  EPD_W21_CS_0;                   
  EPD_W21_DC_1;   // command write
  SPI_Write(command);
  EPD_W21_CS_1;
}



/////////////////EPD settings Functions/////////////////////
void EPD_W21_Init(void)
{
  EPD_W21_RST_0;    // Module reset
  driver_delay_xms(1000);//At least 10ms delay 
  EPD_W21_RST_1;
  driver_delay_xms(1000);//At least 10ms delay 
  
}
void EPD_init(void)
{
    unsigned char HRES_byte1=0x03;      //800
    unsigned char HRES_byte2=0x20;
    unsigned char VRES_byte1=0x01;      //480
    unsigned char  VRES_byte2=0xE0;
  
    EPD_W21_Init(); //Electronic paper IC reset

    EPD_W21_WriteCMD(0x01);     //POWER SETTING
    EPD_W21_WriteDATA (0x07);
    EPD_W21_WriteDATA (0x07);    //VGH=20V,VGL=-20V
    EPD_W21_WriteDATA (0x3f);   //VDH=15V
    EPD_W21_WriteDATA (0x3f);   //VDL=-15V

    EPD_W21_WriteCMD(0x04);  //Power on
    lcd_chkstatus();        //waiting for the electronic paper IC to release the idle signal
  
    EPD_W21_WriteCMD(0X00);     //PANNEL SETTING
    EPD_W21_WriteDATA(0x1F);   //KW-3f   KWR-2F BWROTP 0f BWOTP 1f

    EPD_W21_WriteCMD(0x61);         //tres      
    EPD_W21_WriteDATA (HRES_byte1);   //source 800
    EPD_W21_WriteDATA (HRES_byte2);
    EPD_W21_WriteDATA (VRES_byte1);   //gate 480
    EPD_W21_WriteDATA (VRES_byte2);
  
    EPD_W21_WriteCMD(0X15);   
    EPD_W21_WriteDATA(0x00);    

    EPD_W21_WriteCMD(0X50);     //VCOM AND DATA INTERVAL SETTING
    EPD_W21_WriteDATA(0x10);
    EPD_W21_WriteDATA(0x07);

    EPD_W21_WriteCMD(0X60);     //TCON SETTING
    EPD_W21_WriteDATA(0x22);
}
void EPD_refresh(void)
{
    EPD_W21_WriteCMD(0x12);     //DISPLAY REFRESH   
    driver_delay_xms(100);          //!!!The delay here is necessary, 200uS at least!!!     
    lcd_chkstatus();
} 
void EPD_sleep(void)
{ 
    EPD_W21_WriteCMD(0X02);   //power off
    lcd_chkstatus();
  
}


void PIC_display1(void)
{
    unsigned int i;
    EPD_W21_WriteCMD(0x10);        //Transfer old data
    for(i=0;i<48000;i++)      
    EPD_W21_WriteDATA(0xff); 
  
    EPD_W21_WriteCMD(0x13);        //Transfer new data
    for(i=0;i<20000;i++)      
     EPD_W21_WriteDATA(pgm_read_byte(&gImage_1[i]));
    for(i=0;i<48000-20000;i++)      
     EPD_W21_WriteDATA(0x00); 
     

}

void PIC_display_Clean(void)
{
    unsigned int i;
    EPD_W21_WriteCMD(0x10);        //Transfer old data
    for(i=0;i<48000;i++)       
  {
    EPD_W21_WriteDATA(0xff);
  }
  
    EPD_W21_WriteCMD(0x13);        //Transfer new data    
    for(i=0;i<48000;i++)       
  {
    EPD_W21_WriteDATA(0x00);
  }
}
void lcd_chkstatus(void)
{
  unsigned char busy;
  do
  {
    EPD_W21_WriteCMD(0x71);
    busy = isEPD_W21_BUSY;
    busy =!(busy & 0x01);        
  }
  while(busy);   
  driver_delay_xms(200);                       
}

[edit2]

Nevermind - took longer than I'll admit to, but this finally worked. Might actually have to go back to the ESP32 Huzzah and try that one again too.

// GxEPD2_HelloWorld.ino by Jean-Marc Zingg

// see GxEPD2_wiring_examples.h for wiring suggestions and examples
// if you use a different wiring, you need to adapt the constructor parameters!

// uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX
//#include <GFX.h>

#include <GxEPD2_BW.h>
#include <GxEPD2_3C.h>
#include <Fonts/FreeMonoBold9pt7b.h>

// select the display class and display driver class in the following file (new style):
// #include "GxEPD2_display_selection_new_style.h"

// or select the display constructor line in one of the following files (old style):
//#include "GxEPD2_display_selection.h"
//#include "GxEPD2_display_selection_added.h"

// alternately you can copy the constructor from GxEPD2_display_selection.h or GxEPD2_display_selection_added.h to here
// e.g. for Wemos D1 mini:
GxEPD2_BW<GxEPD2_750_T7, GxEPD2_750_T7::HEIGHT> display(GxEPD2_750_T7(/*CS=D10*/ 7, /*DC=D10*/ 10, /*RST=D9*/ 9, /*BUSY=D7*/ 8)); // GDEH0154D67

void setup()
{
  display.init();
  helloWorld();
  display.hibernate();
}

const char HelloWorld[] = "Hello World!";

void helloWorld()
{
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  int16_t tbx, tby; uint16_t tbw, tbh;
  display.getTextBounds(HelloWorld, 0, 0, &tbx, &tby, &tbw, &tbh);
  // center the bounding box by transposition of the origin:
  uint16_t x = ((display.width() - tbw) / 2) - tbx;
  uint16_t y = ((display.height() - tbh) / 2) - tby;
  display.setFullWindow();
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    display.setCursor(x, y);
    display.print(HelloWorld);
  }
  while (display.nextPage());
}

void loop() {};

Hi,
I have a Waveshare E-Paper 2.7" B&W with Waveshare Esp32 board.
In my code used (GxEPD2) i have a initialise e-paper display function but its looks that if a fill all screen with white the screen won't clean from old text.
@ZinggJM any idea why ?

void initDisplay() {
  display.init(115200);
  SPI.end();
  SPI.begin(13, 12, 14, 15);
  display.setFullWindow();
  display.firstPage();
  display.fillScreen(GxEPD_WHITE);
  display.fillScreen(GxEPD_WHITE);
  display.setPartialWindow(0, 0, display.width(), display.height());
  display.fillScreen(GxEPD_WHITE);
}

@rt400,

Why don't you check with one of the examples, and then compare with your code?
Hint: missing e.g. do {...} while(display.nextPage());

this is from the example in github but i change lines to make the screen clean before display the data. in other func i have do {...} while(display.nextPage())...
also this initDisplay() run on setup() . all i want that on device boot he clean all the screen from old text.

"Beratungsresistent". I can't help users that are resistant to advice.
You might take a look at header files. They contain some comments. Might be insufficient for you.

@ZinggJM I'll admit that I'm fairly new to the Arduino platform, but where do you read out the 'board information' (e.g. the value that you compare to the ESP32 / ESP8266 etc if statements)? I'd be curious to see what my board actually reports back there.

@madewhatnow, Hi,

I once asked in a topic for this information. There is a rule for ARDUINO_ARCH_xxx, based on the directory the platform is in. And some other rules, I forgot about. Maybe I find and add the topic link later.

But in practice I use brute force: I enable verbose for compilation in preferences, and then look at the compilation output.

Jean-Marc

There was a recent request for Arduino to provide documentation about this sort of thing. I shared my current thoughts on the matter along with some links to related resources and requests in a reply there:

Thanks to both of you!