GxEPD2_PP : Particle Display Library for SPI E-Paper Displays

Hi Norfeldt, I think you misunderstood my post.

An example is there for users to learn from and adapt to their needs.
I thought you could easily find out if there exists something similar to WiFiClient for Particle, or get help for this in this forum. I do not decline to help you, but you could start with searching on Particle.

GxEPD2_WiFi_Example

Jean-Marc

I have started a topic in this forum to get help for me to help:

2 Likes

There are numerous httpclients in the library and now httpsclients so strike requirement 1.

I have done a HTTP download to an SD card of a .bmp file but never got around to getting it to work for HTTPS.

It should be possible to combine the GxEPD2_WiFi_Example (where all the hard work in processing the .bmp format to write to the EPD has been done by Jean-Marc) with the httpsclient to get something that can would on the Particle platform.

Version 1.1.0+

  • added GxEPD2_PP_WiFi_Example, for bitmap download from web
  • only download from http: works, would need help for https:
  • only on GitHub, to avoid the need to increase the version for publish
  • this is preliminary!

Your example code has been a big help for me and I have used it to print the quotations with different colors.

It's just that this example is over 1300 lines of code and I'm not so good at Arduino code at this level - I'm much stronger with JavaScript.

I thought that it would be too big of a question to ask for help with this example on the community - since it would essentially be "can you help me to code this for me?".

I don’t know your exact requirements, but maybe you just need the function showBitmapFrom_HTTP() from the GxEPD2_PP_WiFi_Example to start with.

You are right, that seems like a good start.

I was thinking of using Firebase storage to host the .bmp files (and Firebase functions to do the conversion from .jpg to .bmp via JIMP) - that would use HTTPS.

But just to get some experience your example would be an excellent start.

Has anybody here used this version of the Waveshare display?

I’m wondering if the library will drive this display or if it’s incompatible?

Yes, it is supported. I think I even tested it with GxEPD2_PP.
Note that this e-paper display has an unpleasant long refresh time of about 15 seconds.

Thanks for mentioning the long refresh time.

Have you tested the highlighted version of the 4.2 inch version that has 1 Second Partial Refresh times?

I’m looking for something bigger than 4 inches that has quick partial refresh times for a AD display.

The B & W 7.5 inch display looks good with 4.3 second refresh times, just trying to keep the flashing down so it’s causing anybody to have Epilepsy.

Any advice?

Ok, this is the actual table from GxEPD2. Note that GxEPD2_PP lags behind GxEPD2, as well as the GxEPD2 version published for Particle.

GDEW042T2 is the largest SPI e-paper with differential partial update (without flashing).
Note that the wavetable for partial update of this e-paper is currently under question, see
https://forum.arduino.cc/index.php?topic=487007.msg4244907#msg4244907

GDEW075T8 has no differential update, means it flashes during the 4.3s refresh.
There is a new 7.5" e-paper announced, GDEW075T7 b/w 800x480, with a controller that can do differential update, but no available waveform table for differential update afaik.

1 Like

@ZinggJM I see @manu84 has got the Partial update working on the 4.2 inch display which you have.

Is there any way you could share a video showing what the 4 inch display looks like when doing partial updates vs full updates using your enhanced library? I’m trying to get a good idea of what is possible before heading down the eInk road.

I’m currently using Sharp Memory LCD’s and they make a 4.4 inch version but the resolution of 320x240 is lower then I’m wanting ideally so the eInk and it’s larger sizes and more pixels are attractive in that respect.

Pictured is a 2.7 inch Sharp Memory LCD with 400x240 pixels.

Sorry, I spend a lot of time answering posts. I am willing to add some pictures sometimes. But taking videos is asking too much. BTW there are many e-paper videos on YouTube, and certainly some with the 4.2". Or you could search for G6EJD, he uses my library GxEPD and produces videos.

1 Like

Yea no problem, figured it wouldn’t hurt to ask. Thanks for pointing me in the right direction.

So officially until the new 7.5inch screen is released there is no way to get a refresh quicker than 14 seconds right?

Thanks for your work on the library for these displays!

So I’ve been playing around with this library for a couple of days now, and am sufficiently stumped as to how to get it to do what I want.

Goals:

  • Display Full screen Images
  • Display different sized text in the same update
  • Show some text inverted in a configurable sized section with ā€œnormalā€ text
  • Completely clear the display
  • Full buffer drawing

This is what I have now, using the 2.9" Waveshare display. Any help would be greatly appreciated.

#include <Adafruit_GFX_RK.h>
#include <GxEPD2_PP.h>

// base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code
// enable or disable GxEPD2_GFX base class
#define ENABLE_GxEPD2_GFX 0

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <FreeMonoBold9pt7b.h>
#include <FreeMono12pt7b.h>
// #include "imagedata.h"

#include <GxEPD2_BW.h>
#include <GxEPD2_3C.h>

GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=A2*/ SS, /*DC=*/ A1, /*RST=*/ A0, /*BUSY=*/ A4));
// GxEPD2_BW<GxEPD2_290_T5, GxEPD2_290_T5::HEIGHT> display(GxEPD2_290_T5(/*CS=A2*/ SS, /*DC=*/ A1, /*RST=*/ A0, /*BUSY=*/ A4)); // GDEW029T5

#include "bitmaps/Bitmaps128x296.h" // 2.9"  b/w

const char HelloWorld[] = "Hello World!";
const char HelloArduino[] = "Hello Arduino!";
const char HelloEpaper[] = "Hello E-Paper!";

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("setup");
  delay(100);
  display.init(115200);
  display.clearScreen();
  display.writeScreenBuffer();
  delay(1000);
  drawBitmaps128x296();
  drawBitmaps128x296();
  display.clearScreen();
  display.writeScreenBuffer();
  delay(1000);
}

void loop()
{
  //Serial.println("helloArduino");
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  int16_t tbx, tby; uint16_t tbw, tbh;
  // align with centered HelloWorld
  display.getTextBounds(HelloWorld, 0, 0, &tbx, &tby, &tbw, &tbh);
  uint16_t x = ((display.width() - tbw) / 2) - tbx;
  // height might be different
  display.getTextBounds(HelloArduino, 0, 0, &tbx, &tby, &tbw, &tbh);
  uint16_t y = ((display.height() / 4) - tbh / 2) - tby; // y is base line!
  // make the window big enough to cover (overwrite) descenders of previous text
  uint16_t wh = FreeMonoBold9pt7b.yAdvance;
  uint16_t wy = (display.height() / 4) - wh / 2;
  display.setFullWindow();
  // display.setPartialWindow(8, wy, display.width(), wh);
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    //display.drawRect(x, y - tbh, tbw, tbh, GxEPD_BLACK);
    display.setCursor(x, y);
    display.print(HelloArduino);
    display.setCursor(x - 40 , y + 80);
    display.print(HelloEpaper);
    display.setFont(&FreeMono12pt7b);
    display.setCursor(x + 40 , y + 60);
    display.print(HelloWorld);
  }
  while (display.nextPage());
  delay(5000);
  display.setFullWindow();
  display.fillScreen(GxEPD_WHITE);
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    //display.drawRect(x, y - tbh, tbw, tbh, GxEPD_BLACK);
    display.setCursor(x, y + 20);
    display.print(HelloWorld);
  }
  while (display.nextPage());
  delay(5000);
}

void drawBitmaps128x296()
{
  const unsigned char* bitmaps[] =
  {
    Bitmap128x296_1, logo128x296, first128x296, second128x296, third128x296
  };
  bool m = display.mirror(true);
  for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  {
    display.firstPage();
    do
    {
      display.fillScreen(GxEPD_WHITE);
      display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
    }
    while (display.nextPage());
    delay(2000);
  }
  display.mirror(m);
}

Display different sized text in the same update

You need to #include all fonts you want to use, and use display.setFont() to select the active font.

Show some text inverted in a configurable sized section with ā€œnormalā€ text

Draw a black rectangle, and write the text over it with GxEPD_WHITE.

Full buffer drawing

Read the README.MD
GxEPD2 has an example: https://github.com/ZinggJM/GxEPD2/tree/master/examples/GxEPD2_NotPagedExample

It looks like using the full buffer has solved my issue with images, and the alternating displays in my loop(). The formatting of the README makes it harder to understand what I needed to do, since bullet points are breaking up sentences and interrupting the flow.

The only thing I still can’t figure out is how to completely clear the display.
This sequence displays the second last image shown at startup, then goes through the bitmap list and my custom logo, then completely clears the display before going into the main loop().

void setup()
{
  Serial.begin(115200);
  delay(100);
  display.init(115200);
  // display.setFullWindow();
  // display.clearScreen();
  display.fillScreen(GxEPD_WHITE);
  display.display(false);
  // display.fillScreen(GxEPD_WHITE);
  // display.display(false);
  delay(5000);
  drawBitmaps128x296();
  drawlogo();
  display.fillScreen(GxEPD_WHITE);
  display.display(false);
  delay(5000);
}

Why isn’t the display blank for 5 seconds before going into drawBitmaps(), but it is after draw logo?

I wouldn’t expect this with display.display(false); maybe with display.display(true);

Unfortunately it takes time for me to make a system ready for testing with Particle. I only have a system ready for tests with Arduino. So I may test and answer in 2 to 3 days maybe.

1 Like

I confirm that this doesn’t work with neither the published version of this library, nor the version on GitHub.

The library lags behind the GxEPD2 library for Arduino.

from README.MD of GxEPD2_PP:

Version 1.1.0

  • corresponds to GxEPD2 Version 1.1.6
  • added support for GDEH0213B72 2.13" b/w, replacement for GDE0213B1

from README.MD of GxEPD2:

Version 1.1.8

  • fix for incomplete download in GxEPD2_WiFi_Example
  • added missing method displayWindow() to GxEPD2_GFX base class
  • fix and clean up of initial refresh for panels with differential update
  • initial refresh needs to be full update, not ā€œfast partial updateā€, for these panels,
  • as the screen content may differ from the ā€œprevious bufferā€ content.
  • add clean of controller buffer(s) on initial write to controller, for partial update.

Version 1.1.7

  • enhanced support for full buffered, non-paged use, for processors with enough RAM
  • use void display(bool partial_update_mode = false); corresponds to update() in GxEPD
  • use added void displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
  • use added writeImagePart(…), drawImagePart(…), used by displayWindow()
  • added example GxEPD2_NotPagedExample.ino
  • several fixes, e.g. parameter range check in setPartialWindow()

The version of GxEPD2 published for Particle also does not have these fixes.

I will update the versions for Particle, but don’t know yet when I have time for this.
Updating the versions is not the problem, but testing takes time.

Don’t use display.display() with this version, for e-papers with ā€œfast partial updateā€.
Use at least one full update before using partial update (like in the example).
Use a partial update to full screen equal to the initial full update, before using partial updates.

Sorry for the inconvenience, my Arduino libraries are more important for me and for most users.

Note that the GxEPD2 version on GitHub can be used with Particle as private library (untested for Particle). The examples for Particle are in directory ā€œextrasā€.

Perhaps I’m misunderstanding the example; but when I copied the Hello World code over into my project, and condensed it down to what I believe I needed, I’m still getting a similar problem. This time I still get the second last image shown instead of a blank screen, and I also get another 5 seconds of the last image shown before going into drawbitmaps().

void setup()
{
  Serial.begin(115200);
  delay(100);
  display.init(115200);
  display.setFullWindow();
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
  }
  while (display.nextPage());
  delay(2000);
  drawBitmaps128x296();
  drawlogo();
  display.fillScreen(GxEPD_WHITE);
  display.display();
  delay(2000);
  fontDemo();
}

I confirm this also, but I have no idea why. I have checked that the example works, so this should work also. I have currently no time to investigate further.