Can good display 7.5 b/w/r change image at runtime?

Hi All,

I have a project to get data of meeting room reservation from reserve server to display on good display 7.5 b/w/r with ESP32. I used GxGDEW075Z09 and HTTPClient library in my sketch.

Then I tried demo "GxEPD_SPI_TestExample" and it work fine. But the image in this example is static, and I want to change the image at runtime with data from server (converted into 0x format).

I tried to used HTTPClient to read data from server but it too large and crashed at runtime. This is a part of my sketch.

 String ipAddr = "http://192.168.43.78";
  String fileIot = "/iot/CO-101.iot";

  HTTPClient http;
  http.begin(ipAddr + fileIot);
  int httpCode = http.GET();

  if (httpCode > 0) {
    if (httpCode == HTTP_CODE_OK) {
      int len = http.getSize();
      int buffSize = 1;
      unsigned char image[61448];  //file size is 61448

      WiFiClient * stream = http.getStreamPtr();
      while (http.connected() && (len > 0 || len == -1)) {
        size_t size = stream->available();
        if (size) {
          int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));  //error here
          image[countLoop++] = buff[0];

          if (len > 0) {
            len -= c;
          }
        }
        delay(1);
      }
      display.init();
      clear_screen();
      Serial.println("image");
      display.drawBitmap(image, sizeof(image));
  }

Please suggest what I should do. Thank you.

Hi kaijang14,

Yes, the display can do that. But how to do it with GxEPD is not obvious. An example is still missing.

The drawBitmap method you use reads the static data from code space, on AVR, ESP8266 and ESP32.
That's the reason your program crashes.

You need to use a drawBitmap method from Adafruit_GFX to write your buffer to the buffer of the display class, and then call update().

display.drawBitmap(0, 0, image, GxGDEW075Z09_WIDTH, GxGDEW075Z09_height, GxEPD_BLACK);
display.update();

(I didn't check, you may need to look it up in Adafruit_GFX.h)

This may work, or not, as single pixels are drawn in the display class buffer, which takes time. On ESP32 it could cause watchdog time exception.
You can do it in pieces, use a buffer of multiple lines size to make target x,y calculation easy. And call yield() or delay(1) after each drawBitmap.

Comes time, come more examples for GxEPD and GxEPD2, hopefully.

Jean-Marc

GxEPD2_32 has methods to draw bitmaps from buffer directly to controller memory.

Hi, ZinggJM

Thank you for your reply.

I downloaded the GxEPD2 and run sketch GxEPD2_32_Example. In setup() I deleted all code of display font method except drawBitmaps().

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

  drawBitmaps();

  Serial.println("setup done");
}

When sketch run to display.firstPage(); line in drawBitmaps640x384() method.
It display "Busy Timeout! _PowerOn : 10000xxx" for 5-6 times, finally end of method with no anything change on the display.

#ifdef _GxBitmaps640x384_H_
void drawBitmaps640x384()
{
  const unsigned char* bitmaps[] =
  {
    Bitmap640x384_1, Bitmap640x384_2
  };
  if (display.panel() == GxEPD2::GDEW075T8)
  {
    for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
    {
      Serial.println("first page");
      display.firstPage();
      Serial.println("done first page");
      do
      {
        display.fillScreen(GxEPD_WHITE);
        display.drawInvertedBitmap(0, 0, bitmaps[i], display.width(), display.height(), GxEPD_BLACK);
      }
      while (display.nextPage());
      delay(2000);
    }
  }
}
#endif
OUTPUT

setup
first page
Busy Timeout!
_PowerOn : 10000674
done first page
Busy Timeout!
_Update_Full : 10000943
Busy Timeout!
_PowerOff : 10001004
first page
Busy Timeout!
_PowerOn : 10000733
done first page
Busy Timeout!
_Update_Full : 10000450
Busy Timeout!
_PowerOff : 10001004
setup done

Next step, I try to check out Adafruit_GFX library as your suggest. Thank you

There is something wrong if you get Busy Timeout. Do you use the suggested wiring? Else you need to change the values in the constructor for your display.

Adafruit_GFX is in Arduino/libraries, else the example would not compile.

You need to select the 3-color display GDEW075Z09 according your first post.

GxEPD2_32_3C display(GxEPD2::GDEW075Z09,  /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4);

In this part of the example you can find direct drawing to controller buffer and/or screen:

#ifdef _GxBitmaps200x200_H_
void drawBitmaps200x200()
{
  const unsigned char* bitmaps[] =
  {
    logo200x200, first200x200, second200x200, third200x200, fourth200x200, fifth200x200, sixth200x200, senventh200x200, eighth200x200
  };
  if (display.panel() == GxEPD2::GDEP015OC1)
  {
     // ...
  }
  else
  {
    bool mirror_y = (display.panel() != GxEPD2::GDE0213B1);
    display.clearScreen(0xFF);
    uint16_t x = (display.width() - 200) / 2;
    uint16_t y = (display.height() - 200) / 2;
    for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
    {
      display.drawImage(bitmaps[i], x, y, 200, 200, false, mirror_y, true);
      delay(2000);
    }
  }
  bool mirror_y = (display.panel() != GxEPD2::GDE0213B1);
  for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  {
    int16_t x = -60;
    int16_t y = -60;
    for (uint16_t j = 0; j < 10; j++)
    {
      display.writeScreenBuffer(0xFF);
      display.writeImage(bitmaps[i], x, y, 200, 200, false, mirror_y, true);
      display.refresh();
      delay(2000);
      x += 40;
      y += 40;
      if ((x >= display.width()) || (y >= display.height())) break;
    }
    break; // comment out for full show
  }
  display.writeScreenBuffer(0xFF);
  display.writeImage(bitmaps[0], 0, 0, 200, 200, false, mirror_y, true);
  display.writeImage(bitmaps[0], display.width() - 200, display.height() - 200, 200, 200, false, mirror_y, true);
  display.refresh();
  delay(2000);
}
#endif

For bitmap in RAM set the last parameter to false.