Bitmap Distorted Issue on Waveshare 7.3in e-paper for me

Waveshare 7.3in 7color E-Paper: 7.3inch_e-Paper
ESP32 Waveshare Driver Board: Waveshare Driver Board

Hello, currently attempting to display images from a bitmap .h file to a Waveshare 7.3in 7color E-Paper and running into a bit of distortion. For clarity, I decided to create a simple image that contains the word "Hello World" to understand the distortion, here are the images of what I am seeing:

Here is the original image uploaded for reference:

It looks like from the pictures above, vertical slivers from the screen are inverted across the y axis (looking at the W in "World" above)
Here is the piece of code that draws the image onto the display :

void drawBitmaps()
{
  display.setRotation(0);
  display.setFullWindow();
  #if defined(_OldSargeBmp_H_)
    drawOldSargeBmp();
  #endif
}

#if defined(_OldSargeBmp_H_)
void drawOldSargeBmp()
{
  if ((display.epd2.panel == GxEPD2::GDEY073D46) || (display.epd2.panel == GxEPD2::ACeP730))
  {
    display.epd2.drawImage(OldSarge, 0, 0, 800, 480, false, false, false);
    delay(5000);
  }
}
#endif

I have a bitmap file that I am importing with the "OldSarge" bitmap defined referenced from the display.epd2.drawImage function call that I cannot show here because it is too many characters for this post. If possible, I would like to receive a bitmap to test as a sanity check (the display size is 800X480) This would be greatly appreciated. (Wish I could attach a file but I am new)

My question is if I am using this function correctly, I am using this driver for this display:
#define GxEPD2_DRIVER_CLASS GxEPD2_730c_ACeP_730 // Waveshare 7.3" 7-color

Within the driver code, this is the function that I am calling ("drawImage"):

void GxEPD2_730c_ACeP_730::drawImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
{
  writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
  refresh(x, y, w, h);
}

void GxEPD2_730c_ACeP_730::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
{
  //Serial.print("writeImage("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
  if (!_init_display_done) _InitDisplay();
  if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
  {
    //Serial.println("paged");
    _startTransfer();
    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 8; i++)
    {
      uint8_t data = bitmap[i];
      for (int16_t k = 0; k < 4; k++)
      {
        uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
        data <<= 2;
        _transfer(data2);
      }
    }
    _endTransfer();
    if (y + h == HEIGHT) // last page
    {
      //Serial.println("paged ended");
      _paged = false;
    }
  }
  else
  {
    _paged = false;
    int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
    x -= x % 8; // byte boundary
    w = wb * 8; // byte boundary
    if ((w <= 0) || (h <= 0)) return;
    _writeCommand(0x10);
    _startTransfer();
    for (int16_t i = 0; i < int16_t(HEIGHT); i++)
    {
      for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
      {
        uint8_t data = 0xFF;
        if ((j >= x) && (j <= x + w) && (i >= y) && (i < y + h))
        {
          uint32_t idx = mirror_y ? (j - x) / 8 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 8 + uint32_t(i - y) * wb;
          if (pgm)
          {
#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
            data = pgm_read_byte(&bitmap[idx]);
#else
            data = bitmap[idx];
#endif
          }
          else
          {
            data = bitmap[idx];
          }
          if (invert) data = ~data;
        }
        for (int16_t k = 0; k < 4; k++)
        {
          uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
          data <<= 2;
          _transfer(data2);
        }
      }
    }
    _endTransfer();
  }
  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
}

@dpear5 , my first guess is wrong bit-order, pixels per byte, of your bitmap.

Did you try to show your bitmap on your 7.5inch e-paper?
Do all bitmaps the example GxEPD2_Example shows look correctly?
Did you try to attach your bitmap source in a zip-file?
-jz-

Here is my zipped bitmap (it would be greatly appreciated if this was tested):
file.zip (4.8 KB)

Tested the GxEPD2_Example, it looks like everything is displaying correctly, so most likely my bitmap is not correct. Currently using the pillow package in python to convert an image to a Bitmap and creating a .c file from it

In addition, is there any starter code for simply displaying an image in color for a 7.3in 7color waveshare display? Unsure if I am overcomplicating.

Appreciate the help

I don't know this package. Does it allow to change the bit order?

Both Waveshare and Good Display have descriptions and tools how to create bitmaps.
But for your display Waveshare provides mostly support for the PhotoPainter.
Take a look at the Good Display support; this display is quite similar:

I may find time to check your bitmap later.

Hey @ZinggJM , I am now thinking that the issue is within the function "display.esp2.drawImage from the ACeP_730 driver, as I have used the good display directions to create a bitmap, and have experienced distortion after importing the generated bitmap: Bitmap Directions

I have attempted to convert this image:

I have noticed that I can only see distorted parts of the top left corner of the image, therefore I have made this image with text at that location. Here is my call to the function again (I am unsure if my parameters are incorrect or not):
display.epd2.drawImage(OldSarge, 0, 0, 800, 480, false, false, false);

This is the generated zipped bitmap for testing:
BitmapsOldSarge.zip (13.7 KB)

Appreciate your time

Your bitmaps have a size of 384000 bytes. This would translate to one byte per pixel.

The GxEPD2 methods drawImage() are for one bit per pixel b/w bitmaps.

The driver classes for 7.3" 7-color displays have a method implemented to draw demo bitmaps from Good Display for these panels:

    void writeDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode = 0, bool mirror_y = false, bool pgm = false);
    void drawDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode = 0, bool mirror_y = false, bool pgm = false);

Maybe you understand the meaning of the parameter names (pgm is for program memory, mode is currently not used).

In GxEPD2_Example.ino you can find the methods to use with the demo bitmaps from Good Display near the end (line 1886):

#if defined(_GxBitmaps7c800x480_H_)
void drawBitmaps7c800x480()
{
  if ((display.epd2.panel == GxEPD2::GDEY073D46) || (display.epd2.panel == GxEPD2::ACeP730))
  {
    display.epd2.drawDemoBitmap(Bitmap7c800x480, 0, 0, 0, 800, 480, 0, false, true); // special format
    delay(5000);
  }
}
#endif

and for Waveshare demo bitmaps:

#if defined(_WS_Bitmaps7c300x180_H_)
void drawBitmaps7c300x180()
{
  if ((display.epd2.panel == GxEPD2::GDEY073D46) || (display.epd2.panel == GxEPD2::ACeP730))
  {
    display.drawNative(WS_Bitmap7c300x180, 0, (display.epd2.WIDTH - 300) / 2, (display.epd2.HEIGHT - 180) / 2, 300, 180, false, false, true);
    delay(5000);
  }
}
#endif

Maybe your bitmaps are of the same format as the demo bitmaps from Good Display.
I leave it to you to check. If you need further assistance with this, I will find time to check this.
-jz-

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.