Waveshare e-paper displays with SPI

E Ink │ We Make Surfaces Smarter.

I would expect you can find out more about them. Maybe also in wikipedia.

I got the impression they sell rather expensive development systems for their e-paper displays.
Big companies like e-Book Reader manufacturers can afford it. And with the development systems your surely can get software examples.

Hi everyone,

I’m trying to use the GxEPD2 library for my project (arduino MEGA and a 1.54 b/w e-ink display), but the display show me only half of the image because of the memory. I'm already using the PROGMEM, but I really don't understand how to use the paged drawing.

Could someone help me? I would really appreciate it!

Thx, Alessio.

From https://forum.arduino.cc/t/e-paper-display-not-showing-entire-image/946809/3:

Hi,
thx for your answer!
I was trying to use GxEPD2, but when I run the GxEPD2_Example with the right wires and selecting the right e-paper, the only thing I see is a black border and the old image together.

So you have some progress?

Please explain what you don't understand with using paged drawing.
Take a look at the examples, that's what they are for.

Or you could post your code you tried, in a code window, please.

I could, but I don't want to. I currently have no time to spare for extended support.

Reading from the controller of these e-papers means reading through DIN pin.
In general you need SW SPI to do this. See GxEPD2/extras/sw_spi at master · ZinggJM/GxEPD2 · GitHub.
You need to consult the controller specs for the commands to read, and for the details about the OTP data. I have no time to help you with this.

Jean-Marc

Hi,

sorry for the long time for an answer, but I haven't had good days...

This is the code with which happen what I described days ago.

#include <Adafruit_GrayOLED.h>
#include <gfxfont.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>

// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51

// include library, include base class, make path known
#include <GxEPD.h>

// select the display class to use, only one
#include <GxGDEP015OC1/GxGDEP015OC1.h>    // 1.54" b/w

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeSansOblique9pt7b.h>
#include "Image.c"

#include GxEPD_BitmapExamples

#if defined(ARDUINO_AVR_MEGA2560)

// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\mega\pins_arduino.h

// select one, depending on your CS connection
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
//GxIO_Class io(SPI, /*CS=*/ 10, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9, CS on 10 (for CS same as on UNO, for SPI on ICSP use)

GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7

#else

// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h

GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7

#endif


//#define DEMO_DELAY 3*60 // seconds
//#define DEMO_DELAY 1*60 // seconds
#define DEMO_DELAY 5

///extern uint8_t image[];

void setup(void)
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("setup");
  display.init(115200); // enable diagnostic output on Serial
  Serial.println("setup done");
}

void loop()
{
  drawBitmap(0, -50,image, 200, 200, GxEPD_BLACK);
  display.update();
  delay(500);
}

void drawBitmap(int16_t x, int16_t y,
 const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {

  int16_t i, j, byteWidth = (w + 7) / 8;
  uint8_t byte;

  for(j=0; j<h; j++) {
    for(i=0; i<w; i++) {
      if(i & 7) byte <<= 1;
      else      byte   = pgm_read_byte(bitmap + j * byteWidth + i / 8);
      if(byte & 0x80) display.drawPixel(x+i, y+j, color);
    }
  }
}

and this is what I see in my display:

I tried using the examples provided with the library GxEPD2, but even if I'm using the correct wire connection, nothing happen on my screen and the only thing I see is the previous image with a black border like this:

My questions are: in draw() function I have to write the code of the image? Or, if it's possibile, can I store the image in display memory?

I'm using a wave share 1.54" b/w GDEH0154D67 with an Arduino MEGA2560

Thanks,
Alessio

Hello Alessio,

These days are disturbing and difficult, for me also.
But here we are dealing with technical questions and issues.
So I try to give my best to help you with your e-paper display.

In GxEPD paged drawing to cope with processors with limited memory was added later. There are separate examples for using paged drawing. And the driver classes do not distinguish between Arduino UNO and MEGA, that have different amount of RAM available. See also GxEPD/README.md at master · ZinggJM/GxEPD · GitHub.

In GxEPD2 paged drawing is part of the design, available per default. See also GxEPD2/README.md at master · ZinggJM/GxEPD2 · GitHub.

For new users and/or new projects I recommend to use GxEPD2.
I do not know why GxEPD2 did not work for you.
Your Waveshare board most likely has the "clever" reset circuit. Therefore you would need to use the init() method with the shortened reset time.
I recommend you use GxEPD2_Example to start with.
Make sure your wiring and your constructor parameters are equal.
For help with problems, please post diagnostic output in a code window, using the </>-icon.

Good Luck!

Jean-Marc

@ZinggJM ,
Dear Jean Marc,

I am a new beginner of e-paper. I got a Waveshare 5.65 7 colors screen with their ESP32 drive board and run your GxEPD2 example successfully. But I found the color bitmap and text could not be displayed on the screen at the same time.
I would like to know if there is any method to do this in GxEPD2 library? Just like the picture below.

Thanks a lot!

Vincent

@weishiqi, Hi, welcome to the forum.

I tried to decide if I provide a quick answer to your question, or to contemplate and answer later.

I decided to start with a quick answer, and maybe add more later.

The controller of this display does not provide partial window addressing, as far as known.
This means the whole display content must be sent to the controller memory in one go.
But even a ESP32 processor does not have enough RAM for a full buffer of a 7-color picture.
Therefore GxEPD2 needs to use paged drawing for this display even with ESP32.
The ESP32 Wrover has more RAM, but its RAM can't be used as a continuous address space, afaik.

So, for now I do not have a solution for this.
A RP2040 or some other processors with lots of RAM might be an option.

Jean-Marc

Added: on second thought this could be done using paged drawing through the graphics buffer of GxEPD2 for both, the picture and the text. But neither Adafruit_GFX nor GxEPD2 provide a method to draw 7-color bitmaps to the buffer so far, sorry.

@weishiqi
Dear Vincent

It is possible with an ESP32 (in my case an ESP32 WROOM), but (probably) not with the mentioned epaper libraries. The attached sample shows a picture which was generated in RAM and then diplayed. I'm just in the process of programming this, so I wouldn't want to share the code yet.

@Alessio03:
If you only want to display an existing picture: Just store it with your program in the Flash Memory, and transfer it to the epaper RAM. The Waveshare examples (go to the Waveshare WIKI!!) show how it's done - it is actually very simple. You might also want to study the original Good Display samples to learn how to program the devices.
[BTW: I'd recommend to only #include librarier you actually need in your program, so e.g. not OLED for epaper :grin:]

C.P.

@ZinggJM

I'm new to the e-paper world, and I'm having some real trouble getting these to work with either an arduino mega or arduino nano. I've tried multiple e-paper displays. (4.2", 2.9" v2, and a 2.7" HAT)

Wiring is as follows for nano:
BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11, GND -> GND , VCC -> 3.3v

and this for mega:
BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51, GND -> GND , VCC -> 3.3v

Uncommented line for the 2.9":
GxEPD2_BW<GxEPD2_290_T94_V2, MAX_HEIGHT(GxEPD2_290_T94_V2)> display(GxEPD2_290_T94_V2(/CS=/ SS, /DC=/ 8, /RST=/ 9, /BUSY=/ 7)); // GDEM029T94, Waveshare 2.9" V2 variant

This is what I get when I connect straight to the arduino to the display with said wiring and the GXEPD2 example loaded:

It will refresh the screen, but it will always display something like this. This is the case with all 3 displays....

What am I do wrong?!?! I'm getting very frustrated with this thing.

I've tried using a logic level converter ( TXS0108E) even though a believe all these displays are 5v tolorant, but got nothing to display on the screen at all.

here are the links to all my displays:
2.7" v2

4.2"

2.7" HAT

@rewpope
Have you commented out lines, where bitmaps are defined?
Maybe you have commented out too many of them, and no picture data is transferred to the device.
C.P.

@rpiloverbd, Hi, welcome to the forum!

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

I try to understand which boards and panels you have. This would be much easier if you provide links to the devices you bought, or to the devices on the waveshare website.

Your picture looks horrible! It shows random content from the controller memory.

This tells me that SPI communication with the controller works, but data might have been transferred while the controller is BUSY. Check your BUSY line connection.

You could provide diagnostic output from GxEPD2, copy from Serial Monitor. Use a code window, please, </> command.

Your waveshare boards most likely have the "clever" reset circuit to switch off power completely. Use the init() method with shortened reset time, to allow proper reset of the e-paper controller.

Jean-Marc

Added: sorry, now I noticed the links you provided. But with shops on amazon or e-bay it is hard to match the displays to the corresponding panels from Good Display. Or they might even be from a different manufacturer.

@clueless_programmer
First off, thank you for the quick reply.

I have commented out much of the bitmap define lines that are not the display I'm using, but I have also tried it without commenting out any of them on the arduino mega (as the nano does not have enough space.) and I get the same result...

Everybody is looking forward to seeing the output GxEPD2 gives you on the serial monitor (follow Jean-Marcs recommendation) :grin:

yes, we would need some clues! :smiley:

@ZinggJM
busy wire seems to be fine.

Not sure how to do this.

Here is what is on my serial monitor when I run GxEPD2_Example sketch with the 2.9" V2 display:

setup
_PowerOn : 12
_Update_Full : 8
_PowerOff : 12
_PowerOn : 12
_Update_Part : 8
_Update_Part : 1036
_Update_Part : 12
_Update_Full : 1028
_PowerOff : 12
_PowerOn : 12
_Update_Full : 1028
_PowerOff : 1036
_PowerOn : 8
_Update_Part : 12
_Update_Part : 1024
_Update_Part : 1024
_Update_Part : 12
_Update_Part : 12
_Update_Part : 12
_Update_Part : 1024
_Update_Part : 1028
_Update_Part : 12
_Update_Part : 1024
_Update_Part : 8
_Update_Part : 12
_Update_Part : 12
_Update_Part : 2056
_Update_Part : 1040

@ZinggJM
Dear Jean Marc,
Thank you for your quick response!
I'll try something else if there is no suitable mothed right now. And any progress I'll let you konw.

@clueless_programmer
GxEPD2 supports to display single color bitmaps and text on e-paper at the same time, but not multicolor pictures. Thanks for your help anyway.

Thank you!

I have removed the remaining content of my post. It was politically explicit. Not appropriate for this technical forum. Sorry.

Jean-Marc

@rewpope
I hope Jean-Marc doesn't mind, but I'd like to pick something up he has mentioned already: The reset pulse length.
Actually by chance I had a similar nasty picture on my 1.54 inch display this evening, while teaching my daughter how to program a SW SPI by an e-paper example: It finally turned out that we had missed to wait for the busy signal from the epaper to be released after the hardware reset! Everything else worked like a charm (we checked with a logic analyzer), but the e-paper had just not been ready for all upcoming commands and data and displayed rubbish.

So, as Jean-Marc mentioned, you definitely should play with the very first e-paper-step in the program, which is this reset. As per standard. Jean-Marc has programmed it as a 10 ms pulse, which is too long for some boards. Therefore, he has added lines for alternatives and commented them out.

You'll find them in the setup() part of your Arduino program. They look like this:

  display.init(115200); // default 10ms reset pulse, e.g. for bare panels with DESPI-C02
  //display.init(115200, true, 2, false); // USE THIS for Waveshare boards with "clever" reset circuit, 2ms reset pulse
  //display.init(115200, true, 10, false, SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0)); // extended init method with SPI channel and/or settings selection

What Jean-Marc proposed, is to change it into that (simply change the "//"s):

  //display.init(115200); // default 10ms reset pulse, e.g. for bare panels with DESPI-C02
  display.init(115200, true, 2, false); // USE THIS for Waveshare boards with "clever" reset circuit, 2ms reset pulse
  //display.init(115200, true, 10, false, SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0)); // extended init method with SPI channel and/or settings selection

If this doesn't work either, you may try a "1" instead of the "2" to shorten the pulse further.

Please let us know, if you have any nice results!! :grin:

C.P.

@clueless_programmer
Appriciate the help, I tried changing the pules time to the one you suggsted, but had no luck still. I also changed the 2 to a 1 and still nothing different.

I'm about to switch to a lame LCD display for my project. This is just so frustrating.