ESP32 and Waveshare e-Paper: Busy Timeout Issue

Hello everyone,

I'm trying to use a 4.2" Waveshare e-Paper display (SKU: 13353) with my ESP32 WROVER board, but I'm running into an issue where I keep getting "Busy Timeout!" messages. Here’s the error log:

Busy Timeout!
_PowerOn : 10001037
Busy Timeout!
_Update_Full : 10000036
Busy Timeout!
_PowerOff : 10000036
Display updated!

Details:

  • Board: ESP32 WROVER
  • Library: GxEPD2 (version 1.5.9)
  • Connections: (List all the pin connections here)
  • Power Source: (Describe if you’re using USB or external power)

What I’ve Tried:

  • Verified wiring
  • Increased busy timeout to 20 seconds
  • Checked the power supply

Here’s my code:

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

// Pin assignments for ESP32 WROVER
#define GxEPD2_CS 5
#define GxEPD2_DC 17
#define GxEPD2_RST 16
#define GxEPD2_BUSY 4

// Display class for 4.2" b/w display
GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(GxEPD2_CS, GxEPD2_DC, GxEPD2_RST, GxEPD2_BUSY));

void setup() {
Serial.begin(115200);
Serial.println("Initializing display...");
display.init(115200, true, 2, false);
delay(500);

display.setRotation(1);
Serial.println("Clearing screen...");
display.fillScreen(GxEPD_WHITE);

Serial.println("Setting text...");
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setCursor(10, 50);
display.println("Hello World");

Serial.println("Sending buffer to display...");
display.display();
Serial.println("Display updated!");
}

void loop() {

}

Any help or suggestions would be greatly appreciated. Thank you!

I moved your topic to a more appropriate forum category @krupa_k .

The Nano ESP32 category you chose is only used for discussions directly related to the Arduino Nano ESP32 board.

In the future, please take the time to pick the forum category that best suits the subject of your question. There is an "About the _____ category" topic at the top of each category that explains its purpose.

Thanks in advance for your cooperation.

Hi @krupa_k , welcome to the forum!

You selected a driver class for a display panel that is no longer available.

I don't have the actual Waveshare 4.2" b/w display. Therefore I don't know if it is supported by GxEPD2.

I just checked the V2 version of the Waveshare example ("library") : epd4in2_V2.cpp.
It is for a SSD type of controller and has a waveform table (line 612) to program to registers.
This could mean it doesn't have the waveform programmed into OTP, like panels from Good Display. Which means I don't know if it may work with any driver class of GxEPD2.

But you can take a look at GxEPD2_display_selection_new_style.h and try all driver classes for SSD controllers:

//#define GxEPD2_DRIVER_CLASS GxEPD2_420     // GDEW042T2   400x300, UC8176 (IL0398), (WFT042CZ15)
//#define GxEPD2_DRIVER_CLASS GxEPD2_420_M01 // GDEW042M01  400x300, UC8176 (IL0398), (WFT042CZ15)
//#define GxEPD2_DRIVER_CLASS GxEPD2_420_GDEY042T81 // GDEY042T81 400x300, SSD1683 (no inking)
//#define GxEPD2_DRIVER_CLASS GxEPD2_420_GYE042A87  // GYE042A87, 400x300, SSD1683 (HINK-E042-A07-FPC-A1)
//#define GxEPD2_DRIVER_CLASS GxEPD2_420_SE0420NQ04 // SE0420NQ04, 400x300, UC8276C (OPM042A2_V1.0)

or from GxEPD2_display_selection.h

//GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEW042T2 400x300, UC8176 (IL0398)
//GxEPD2_BW<GxEPD2_420_M01, GxEPD2_420_M01::HEIGHT> display(GxEPD2_420_M01(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEW042M01 400x300, UC8176 (IL0398)
//GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> display(GxEPD2_420_GDEY042T81(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEY042T81, 400x300, SSD1683 (no inking)
//GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> display(GxEPD2_420_GYE042A87(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GYE042A87, 400x300, SSD1683 (HINK-E042-A07-FPC-A1)
//GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> display(GxEPD2_420_SE0420NQ04(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // SE0420NQ04, 400x300, UC8276C (OPM042A2_V1.0)

also compare the inking on the flexible connector, if visible. And report it.

You should update GxEPD2 to version 1.6.0 before trying.

Of course, I am interested of the results. If needed, I might buy one of their current version, or ask for a free sample.
-jz-

Thank you for your response. I followed your suggestions and tested different driver classes:

  1. Driver Class 1 (GxEPD2_420_GDEY042T81) and Driver Class 3 (GxEPD2_420_GYE042A87) no longer show the "Busy Timeout!" message. However, the display still does not respond or show any content.
  2. I have ensured that all connections are correct, verified the wiring, and checked the power supply. Additionally, I increased the busy timeout and added delays as you suggested, but still no visible output on the screen.

Here’s what I have tried:

  1. Increased the initialization delay and added power cycling in the code.
  2. Tested multiple driver classes from the list you provided, with driver classes 1 and 3 showing partial success (no busy timeouts) but no display output.

Serial Output Log:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4832
load:0x40078000,len:16460
load:0x40080400,len:4
load:0x40080404,len:3504
entry 0x400805cc
Initializing display...
Clearing screen...
Setting text...
Sending buffer to display...
_Update_Full : 7
_Update_Full : 1
Display updated!

This is the output I see in the serial monitor upon boot. The ESP32 seems to be initialized correctly, and the code runs without any errors, but there’s still no response on the e-Paper display.

If you have any further recommendations or insights, please let me know. I'd be happy to test them and share the results. Thank you for your assistance!

I assume you bought your display from Waveshare, and recently, so it is the actual version.

Does your Waveshare board have 9 connections?

Did you connect both VCC and PWR to 3.3V?
PWR is a control line that switches off VCC to the board when inactive.

(I am surprised that some users don't ask themselves what this "spare" line is good for.)

Please post your actual complete code, in a code window please.

Please post your connections, pin-to-pin.

Please post a picture of the backside of your display, if forum rules allow it already.
-jz-

Thank you for the response. I appreciate it.

No pin marked PWR, just VCC which is connected to 3.3v.

4.2inch e-Paper Module
400x300 Pixels Rev2.2

pinouts on the header (in order from top to bottom of the back of the board):

BUSY
RST
DC
CS
CLK
DIN
GND
VCC

The picture of a backside display.

The complete code is as below:

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

// Pin assignments
#define GxEPD2_CS 5
#define GxEPD2_DC 17
#define GxEPD2_RST 16
#define GxEPD2_BUSY 4
#define GxEPD2_CLK 18
#define GxEPD2_DIN 23

// Drivers
GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> display(GxEPD2_420_GDEY042T81(GxEPD2_CS, GxEPD2_DC, GxEPD2_RST, GxEPD2_BUSY));
//GxEPD2_BW<GxEPD2_420_M01, GxEPD2_420_M01::HEIGHT> display(GxEPD2_420_M01(GxEPD2_CS, GxEPD2_DC, GxEPD2_RST, GxEPD2_BUSY));
//GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> display(GxEPD2_420_GYE042A87(GxEPD2_CS, GxEPD2_DC, GxEPD2_RST, GxEPD2_BUSY));
//GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> display(GxEPD2_420_SE0420NQ04(GxEPD2_CS, GxEPD2_DC, GxEPD2_RST, GxEPD2_BUSY));

void setup() {
Serial.begin(115200);
Serial.println("Initializing display...");

display.init(115200, true, 2, false);
delay(500);

display.setRotation(1);
Serial.println("Clearing screen...");
display.fillScreen(GxEPD_WHITE);

Serial.println("Setting text...");
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setCursor(10, 50);
display.println("Hello World");

Serial.println("Sending buffer to display...");
display.display();
Serial.println("Display updated!");
}

void loop() {
}

Thank you for your patience and help!

This is obviously not a current official board from Waveshare. And I can't help you with it.
The official 4.2" board from Waveshare also doesn't have the PWR pin.
Some other boards now have it. Sorry.

The BUSY active level is different for SSD controllers and UltraChip controllers.
This explains your different result with the different driver classes.

You need to check your display with all demo versions from the Waveshare "library" https://github.com/waveshareteam/e-Paper for their 4.2" b/w displays. Note that Waveshare and GxEPD2 may use different pins.
-jz-

I understand your point.

Thank you for the information regarding the BUSY active level differences between SSD and UltraChip controllers. This aligns with the varying results I’ve seen when testing different driver classes (GxEPD2_420_GDEY042T81 vs. GxEPD2_420), where the behavior changes, but the display still doesn't respond correctly.

Could you please guide me on which display I should use that is known to work reliably with the ESP32 WROVER and the GxEPD2 library? Your recommendation would be invaluable to avoid further compatibility issues.

Thank you again for your assistance and guidance!

The error was my first answer to this topic.

I jumped on the first obvious cause of your issue, without making sure I get all relevant information. I should have pointed you to this topic first:

Please read How to get the best out of this forum.

I don't have the actual Waveshare 4.2" b/w display. Therefore I don't know if it is supported by GxEPD2.

also compare the inking on the flexible connector, if visible. And report it.

I still don't know the inking your panel has, or if it is hidden.

I might buy one of their current version

I will do that, because this is one of most often used panel size, and the one that caused the most issues reported.
But even if I buy one, I can only be sure for a short time. And users still may buy variants from other vendors. Boards with the Waveshare brand logo are known to possibly be copies or fakes, or surplus not intended to get sold. And Waveshare doesn't publish the origin of the panels used, nor the controller and its OTP status.

But the BUSY times you report point to a different or addidional issue: the SPI communication most likely doesn't work.

A clear pin-to-pin wiring list would have been helpful.

Did you check continuity of your wiring, with an ohm-meter? I had one cable from Waveshare with a bad DuPont connector.

And I should have asked which board have you selected to compile for.
To compare if the board uses the default SPI pins you wired to.

Without knowing what you want to use an e-paper display for, I can't give a recommendation.
If you buy panels from an official Good Display shop, you know the panel name, and you can check if it is supported by GxEPD2.
-jz-

Thank you for taking the time to provide such detailed insights and suggestions. I genuinely appreciate your honesty regarding the initial assessment and follow-up clarification. Here’s how I plan to address the points you raised:

  1. Forum Guidelines: I will review "How to get the best out of this forum" to ensure I provide all relevant details in future discussions.

  2. Display Details: The inking on the flexible connector isn’t visible or may be hidden. I’ll investigate further if needed.

  3. SPI Communication: I will verify the following:
    • Pin-to-pin wiring matches the documentation.
    • Continuity of connections using an ohm-meter to rule out faulty connectors.

  4. I'm using ESP32 WROVER board and Arduino IDE.

  5. Display Purpose: I’m using the display for classroom notifications, such as showing the key pressed on a keypad for interactive applications like quizzes and simple calculators. The e-paper display was chosen for its low power consumption and excellent visibility. Reliable recommendations for a display suited to this use case would be greatly appreciated.

  6. Purchasing Advice: Thank you for the tip about panels from Good Display, as they offer known compatibility with GxEPD2. I now understand that some Waveshare-branded boards may be fakes, surplus, or otherwise unsuitable, potentially causing compatibility issues.

Thank you again for your patience and valuable insights. If you purchase the current version of this panel and have additional recommendations or findings, I would be grateful to hear them!

Ok, selecting this board uses the standard ESP32 HW SPI pins.

I have ordered the display from Waveshare. It should arrive in about 2 weeks.
I am very curious about the panel it uses. I will report, and add a matched driver class if needed.
-jz-

That sounds great! It’s exciting that the Waveshare display is on its way—I hope it arrives on time. Let me know once you’ve had a chance to test it. I’m looking forward to hearing about the progress!

Thank you so much for your time and assistance.

Hi again, @krupa_k

My 4.2" b/w display from Waveshare has arrived. It works perfectly.
The panel on the display board is a GDEY042T81.
I tested it with GxEPD2_Example on a Wemos LOLIN32 V1.0.0 which has an ESP-WROOM-32 SOC on board, using my suggested wiring for it:

// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V

selected this driver class:

#define GxEPD2_DRIVER_CLASS GxEPD2_420_GDEY042T81 // GDEY042T81 400x300, SSD1683 (no inking)

and this (default) constructor at line 218:

GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // my suggested wiring and proto board

EPD_CS is from line 126:

// SS is usually used for CS. define here for easy change
#ifndef EPD_CS
#define EPD_CS SS
#endif

All tests of the example worked fine, and provided this diagnostic output on Serial Monitor:

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4604
ho 0 tail 12 room 4
load:0x40078000,len:15488
load:0x40080400,len:4
load:0x40080404,len:3180
entry 0x400805b8

setup
_Update_Full : 1713999
_Update_Full : 1714001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Full : 1713001
_Update_Full : 1714001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 359999
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Full : 1713999
_Update_Full : 1714001
_Update_Full : 1713999
_Update_Full : 1714001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_Update_Part : 360001
_PowerOff : 81001
_Update_Full : 1714001
_Update_Full : 1714001
_Update_Full : 1714001
setup done

I don't know why your display doesn't work for you.
I suggest you check your wiring once more, and read all posts of this topic again.

Maybe you need to order a new display from Waveshare, from an official shop or website.
-jz-