Waveshare e-paper displays with SPI

Hallo Together,

maybe you can help me with my problem regarding the displaying of my waveshare epaper 213inc colour.

epaper: epaper 213c

connecting module: E-paper_Driver_Hat

I thinks its pretty basic but I tried for a long time now and I am not sure whats the problem.

I use an arduino micro to connect over the epaper Driver Hat to the epaper 213c.

My wiring: VCC > 3,3V, GND > GND, DIN > D11, CLK > D13, CS > D10, DC > D8, RST > D9, BUSY > D7

Also I use an simple example code (from Zingg) just to print Hello world. There is no problem with uploading it to the arduino but the display just doesnt show anything. (Also installed the libraries eg. GxEPD2, and adafruit GFX Library)

Here the code.

// 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"
#define GxEPD2_DRIVER_CLASS GxEPD2_213c
// 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_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4)); // GDEH0154D67
GxEPD2_3C<GxEPD2_213c, MAX_HEIGHT_3C(GxEPD2_213c)> display(GxEPD2_213c(/*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // GDEW0213Z16
void setup()
const char HelloWorld[] = "Hello World!";
void helloWorld()
  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.setCursor(x, y);
  while (display.nextPage());
void loop() {};

Is there maybe a problem with the 5V output maybe on the I/O to the epaper driver hat? I thought that the module can handle it but i am not sure.

Thanks in advance!

@stfischer, Hi Samuel, welcome to the forum!

Thank you for providing links to your devices. Makes it easier for me and for other readers.

The e-paper HAT should work fine with 5V IO signals. It has level converters.
See New Output (waveshare.com)

But the HAT also has the “clever” reset circuit, which switches off power to the the rest of the board, including level converter, and to the e-paper panel. This may be the reason for your display not working. From README.md important notes:

- note that Waveshare bords with "clever" reset circuit may need shortened reset pulse
- use `init(115200, true, 2, false)` for Waveshare boards with "clever" reset circuit

With the first parameter you also get diagnostic output to Serial. Observe it in Serial Monitor and report results (in a code window).

Please also report the inking on the flex connector of the panel. Maybe I can find out if it is a different panel.


Addition: for use with 5V processor, you should supply 5V to the VCC pin of the white connector.

Hello, I recently bought a 4,2-inch e ink display to use with an esp32. Until now I have used the original gxepd library when playing around with it however I feel like I should try to move to gxepd2 instead. However, my problem is that I don’t really understand the display.firstPage(); and display.nextPage() part of the example codes. Looking at the example code there is this part

  // comment out next line to have no or minimal Adafruit_GFX code
    // comment out next line to have no or minimal Adafruit_GFX code
    display.print("Hello World!");
  while (display.nextPage());

What happens when I run the display.firstpage() command? I have tried to look it up and from my understanding, this is done due to some Arduino boards not having enough ram. But from my understanding I haven’t told the screen to write anything before calling that command so how could it save ram?

I personally seem to find the way the original gxepd handled things easier to understand with the display.eraseDisplay() and display.drawPaged commands. Since I am using an esp32 and memory shouldn’t be an issue is there a way to have the new library behave like the old without having to do all the “while do” stuff? I shouldn’t need to care about the buffer for a 400x300 4,2 inch screen when using an esp32 right?

Please start by reading the GxEPD2/README.md at master · ZinggJM/GxEPD2 · GitHub.

Then you might take a look at the example GxEPD2/GxEPD2_NotPagedExample.ino at master · ZinggJM/GxEPD2 · GitHub

I’m using ESP32 (LilyGo) with epaper display and external DAC (PCM5102A).
Display is driven by GxEPD lib, sound by ESP32-audioI2S lib.
I get no sound while calling display update.
Same time when I call display update I get text over text issue (previously displayed text is not cleared).
Anyone has same issue or/and solution for it?

Oh, that was a surprisingly fast reply, thank you! Do you think that should/need to use paged drawing on an esp32 or esp8266 or is display.display(false); enough?

Also, I saw that you were talking to someone else a few posts above about his board having a special reset circuit. I also have a 4,2-inch Waveshare screen with spi as the guy you talked with. How do I know if my screen has this special reset circuit? Will it just not work, is there a specific version of the screen or is there a specific component on the screen I should look for?

If you use the constructor with full height for page_height, the compiler will complain if it doesn’t fit in ram.

The actual version will have the “clever” reset circuit. Take a look at the schematics.

Awesome, thank you!

Hi Jean Marc, have ESP32 dev board and waveshare 1,54 200x200 epaper.
In Arduino 1.8.13 cannot compile the minimum example from your library, got these error message
C:\Users\VR\CloudStation\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp: In member function ‘void Adafruit_SPIDevice::transfer(uint8_t*, size_t)’:
C:\Users\VR\CloudStation\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:133:31: error: no matching function for call to ‘SPIClass::transfer(uint8_t*&, size_t&)’
_spi->transfer(buffer, len);
In file included from C:\Users\VR\CloudStation\Arduino\libraries\Adafruit_BusIO/Adafruit_SPIDevice.h:1:0,
from C:\Users\VR\CloudStation\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:1:
C:\Users\VR\CloudStation\Arduino\hardware\espressif\esp32\libraries\SPI\src/SPI.h:67:13: note: candidate: uint8_t SPIClass::transfer(uint8_t)
uint8_t transfer(uint8_t data);
C:\Users\VR\CloudStation\Arduino\hardware\espressif\esp32\libraries\SPI\src/SPI.h:67:13: note: candidate expects 1 argument, 2 provided
exit status 1
Nastala chyba při kompilaci u desky ESP32 Dev Module.

All libraries are up to date… any advice?
Thank you

@VasekR, Hi, welcome to the forum! I hope you already read How to get the best out of this forum.

All libraries are up to date… any advice?

No, not really. I avoided to update dependent libraries when updating Adafruit_GFX recently.
Maybe that is why I still can compile. Adafruit_GFX updates and dependencies are a nightmare.


Version 1.3.2 of library GxEPD2 is available, install with Library Manager.

  • added support for GDEW0213T5D 104x212 b/w e-paper panel
  • added support for GDEW029T5D 128x296 b/w e-paper panel
  • added support for GDEW0213Z19 104x212 b/w/r e-paper panel
  • added support for GDEW029Z13 128x296 b/w/r e-paper panel
  • both GDEW0213Z19 and GDEW029Z13 support only full screen refresh (controller issue)


Hello, I have been playing around with your library and so far I have to say that you have done an excellent job!

However in my project I want to display some large numbers on the screen. I am currently using one of the 24pt fonts included with the library and since it’s to small I also added the setTextSize(2) function which makes my text rougly the size I want. However when doubling the 24pt font it makes the text very blocky. I assume that the library doesn’t have a function to smooth the text so I guess I need a larger font. Do you know if there is a font available larger than 24 pt? Preferebly a 48pt freeSans font. Thanks!

I would like to answer without going to spend much time searching. But with the new forum my saved links don’t work anymore, or not exactly. So I only can tell you what to look for:

You can create your own fonts using the squix font converter.

You can use fonts from U8G2. GxEPD2 has an example for this.

Thank you. I actually managed to solve it myself. I don’t know if you have heard about it but I found an awesome online tool called truetype2gfx https://rop.nl/truetype2gfx/

What it does is lets you choose a font either FreeSans, FreeSerif or FreeMono (you can also upload your own). Then you set the font size you want and then it automatically creates a .h adafruit gfx font file that you can then download and use with your library.

Version 3.1.1 of library GxEPD is available, install with Library Manager.

  • added support for GDEM029T94 2.9" b/w, actual Waveshare 2.9" b/w
  • updated example GxEPD_WiFi_Example, for actual GitHub certificate

This panel has been reported to be used on the actual Waveshare 2.9" b/w board.
But I don't have this Waveshare board, so I can't check and test with.


BTW: forum, please accept that I update both of my main topics with this information!

Version 1.3.3 of library GxEPD2 is available, install with Library Manager.

  • added b/w differential refresh method to GDEW0213Z19
  • added b/w differential refresh method to GDEW029Z13
  • up to 100 b/w fast refreshes have been possible (resulting in slightly reddish background)
  • added experimental example GxEPD2x_MixedTest for proof of concept
  • GxEPD2x_MixedTest needs enough RAM for 2 GFXCanvas1 objects
  • general 3-color mixed refresh in GxEPD2 is in evaluation, for capable panels

I did not believe b/w fast partial update (differential refresh) would be possible for 3-color displays.

But the donator of these two panels, John Hawley, provided this link:

and the demo code he obtained from Good Display.

So I learned these e-paper displays can do new tricks, and I started to add them to GxEPD2.

Thanks John!


Hello Jean-Marc,

I had the same problem as @vanilla_chief and @allllo with my display. After accidentally destroying the screen of my old display, I ordered a new display and as mentioned it is "V2". By changing to the other line (GxEPD2_BW<GxEPD2_290_T94, MAX_HEIGHT(GxEPD2_290_T94)> display(GxEPD2_290_T94(/CS=53/ SS, /DC=/ 8, /RST=/ 9, /BUSY=/ 7)); // GDEM029T94) the display works, but my current problem is by normal updating the display. At the beginning, the display is quite dim, but recovers to a readable level after a few seconds. This was never the case with my old display, is there a tip how I can solve this weird behaviour?

I know that the change to GDEM029T94 from GDEH029A1 is only temporary:

Thanks in advance.


did you replace the Waveshare board, or the panel on the Waveshare board?

I know that the change to GDEM029T94 from GDEH029A1 is only temporary:

I don't know what you mean by this.
Ok, I know that any board from Waveshare will be changed over time!

I have exchanged the complete Waveshare board, only the plug included in the delivery is used again from my old display.

I was referring to the statement that there may be an adaptation for this type of display in the future.

I have no idea. My panel connected to the DESPI-C02 doesn't show this effect.
I don't have that Waveshare board.
It may be caused by the LDO or by the level converter, or by the "clever" reset circuit.

You could report the processor you use and the voltage you supply to the board on VCC,