Waveshare B/W 1.45 inch EPD Arduino Library

Hi, I've been trying to interface a Waveshare 1.45inch 200x200 B/W e-paper display with arduino. The standard liberary test codes from both Waveshare and GxEPD work as expected. The issue is I'm not able to understand how the partial update function works in these displays. I tried to search for a GxEPD wiki, but seems like it doesn't exist. Please allow me to begin with the standard GxEPD Partial Update example. The code below only addresses an Arduino and is the bare minimum that I could get it work. Its working is perplexing and Im not able to understand when the code is refreshing a specific area on the display.

#include <GxEPD.h>
#include <GxGDEP015OC1/GxGDEP015OC1.cpp>    // 1.54" b/w
#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>
#include <Fonts/FreeMonoBold9pt7b.h> // FreeFonts from Adafruit_GFX
#include GxEPD_BitmapExamples

// pins_arduino.h, e.g. AVR
#define PIN_SPI_SS    (10)
#define PIN_SPI_MOSI  (11)
#define PIN_SPI_MISO  (12)
#define PIN_SPI_SCK   (13)

GxIO_Class io(SPI, SS, 8, 9);
GxEPD_Class display(io);

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

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

void loop()
{
  showPartialUpdate_AVR();

}

void showBlackBoxCallback(uint32_t v)
{
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  display.fillRect(box_x, box_y, box_w, box_h, v);
}

void showValueBoxCallback(const uint32_t v)
{
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + box_h - 6;
  display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  display.setCursor(box_x, cursor_y);
  display.print(v / 100);
  display.print(v % 100 > 9 ? "." : ".0");
  display.print(v % 100);
}

void showPartialUpdate_AVR()
{
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + box_h - 6;
  uint32_t value = 1395;
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  display.setRotation(0);
  // draw background
  display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
  delay(2000);

  // partial update to full screen to preset for partial update of box window
  // (this avoids strange background effects)
  display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_flip_x | GxEPD::bm_partial_update);
  delay(1000);

  // show where the update box is
  for (uint16_t r = 0; r < 4; r++)
  {
    display.setRotation(r);
    display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_BLACK);
    //display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_BLACK);
    delay(1000);
    display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_WHITE);
  }
  // show updates in the update box
  for (uint16_t r = 0; r < 4; r++)
  {
    display.setRotation(r);
    for (uint16_t i = 1; i <= 10; i++)
    {
      uint32_t v = value * i;
      display.drawPagedToWindow(showValueBoxCallback, box_x, box_y, box_w, box_h, v);
      delay(500);
    }
    delay(1000);
    display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_WHITE);
  }
}


I have certain questions regarding the code:

1. Why do we need to define a function like this:
[code]void showBlackBoxCallback(uint32_t v)
{
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  display.fillRect(box_x, box_y, box_w, box_h, v);
}

Is it not possible to include this in the loop itslef instead of "showPartialUpdate_AVR();"?

  1. When I add a standard Adafruit code, like:
display.setCursor(0, 5);
display.fillScreen(GxEPD_BLACK);
display.setTextColor(GxEPD_BLACK);
display.setTextSize(0);
display.println("Hello World!");

I see none of that displayed anywhere on the display. I've not been able to add any custom element since last couple of days. All I need is a few elements like text, shapes and variables (eg, DHT22) to be displayed and update them individually. I need some guidance here.

Thanks.

ZinggJM:
Starting with critics is not the best method to get any help from me.

I am not a teacher, and this library may not be best suited for all beginners.
If it is too complicated for you, then you could start with understanding the Waveshare demo code.

I would need to know at least what your target Arduino is; AVR Arduino needs paged update because of buffer size limits; Callback functions may not be best for beginners.

Maybe you could use the U8G2 library with its more intuitive firstPage(), nextPage() methods.

In this topic you find more details, and some evidence of Newbies successfully using GxEPD.

My apologies if this appeared a criticism. I'm a beginner in programming, from this perspective, any help in the implementation of code could make a great difference for me. I appreciate your suggestion to utilize the U8G2Lib, and I have already tried that. It works well, however, it begins to cycle the display between black and white with every frame and that occurs every two seconds. It works well with OLEDs though (for which its designed).

Can you please suggest a simpler method of displaying contents with partial refresh? I'm using an Arduino Uno.

Thanks.

ZinggJM:
The Waveshare demo code uses partial refresh.

You have not answered my question about your Arduino, IT IS IMPORTANT TO KNOW IF IT IS AVR.

I will only answer if you tell me that you have looked at the topic dedicated to GxEPD with Waveshare EPD.

And please post questions regarding GxEPD there, so all is collected in one topic.

I made an error by clicking the "Post" button sooner than I could add the board info. Yes, I'm using Arduino UNO, (ATmega328). I'm aware of the RAM constraint and here partial update is of certain importance. As for the link, that's infact the first page that google offered and I tried to assimilate as much I could from that resource, however I'm not well acquainted with the language. I'm not shifting blame here, since the beginning all I have expressed here is what I could not do and where I need help, I do not intend to introduce any sarcasm, and as a principle, I post here only when I certainly need help.

ZinggJM:
this post and comment 23 of may explain why I am not very motivated to help.

I do not find quick enough all explanations I produced about paged drawing and partial update and screen refresh; this post may give some hints.

Refresh to the screen is done after the last call to the callback function.
Any drawing needs be done in the draw callback function, or in a function called from the callback function, for paged drawing for AVR processors.

I understand it must've been hard to implement an unknown hardware, but your efforts are the reason why many whose use AVRs are inclined to give EPDs a worthy shot. These modules are brilliant, perhaps the 1.54 inch variant was struck by restrained financial inputs. I have been following the U8G2LIB thread for quiet some time now, and I have seen Oliver express the same concerns while supporting the 1.45 inch variant in particular. The display itself is driven by a dedicated 3.3v power supply, the data lines are parsed through level shifters.

The display and the library is working as expected great, however I'm trying to figure out ways to use native Adafruit code to add text, shapes and variables to the screen. When I do that, even if the code compiles without errors, the same is not displayed on the screen. This is why I made this post, it want meant to populate the Arduino.cc archive.

ZinggJM:
When you add this code where?

If you add it to the draw callback function, I would expect you get a black partial box, as you fill the whole buffer with black.
Drawing black text on black doesn't help, but it is outside of the partial window anyway.

Thank you for considering the issue. I'm trying to integrate some sensors to this setup, preferably a DHT22. I attempted the following way of implementation of code based upon your library. Please take a look:

#include <GxEPD.h>
#include <GxGDEP015OC1/GxGDEP015OC1.cpp>    // 1.54" b/w
#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>
#include <Fonts/FreeMonoBold9pt7b.h> // FreeFonts from Adafruit_GFX
#include GxEPD_BitmapExamples
#include <DHT.h>;

#define DHTPIN 4     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE); //Initialize DHT sensor
float hum;  //Stores humidity value
float temp; //Stores temperature value

// pins_arduino.h, e.g. AVR
#define PIN_SPI_SS    (10)
#define PIN_SPI_MOSI  (11)
#define PIN_SPI_MISO  (12)
#define PIN_SPI_SCK   (13)
GxIO_Class io(SPI, SS, 8, 9);
GxEPD_Class display(io);

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

void setup(void)
{
  //Serial.begin(115200);
  display.init();
  dht.begin();
}

void loop()
{
  hum = dht.readHumidity();
  temp = dht.readTemperature();
  showPartialUpdate_AVR();
  delay(DEMO_DELAY * 1000);
}

// modified to avoid float; reduces program size ~2k (for GxGDEW042T2)
void showBlackBoxCallback(uint32_t v)
{
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  display.fillRect(box_x, box_y, box_w, box_h, v);
}

void showValueBoxCallback(const uint32_t v)
{
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + box_h - 6;
  display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  display.setCursor(box_x, cursor_y);
  display.print(v / 100);
  display.print(v % 100 > 9 ? "." : ".0");
  display.print(v % 100);
}

void showPartialUpdate_AVR()
{

  display.setFont(&FreeMonoBold9pt7b);
  display.setCursor(0, 10);
  display.setTextColor(GxEPD_BLACK);
  display.setTextSize(1);
  display.println(temp);
  display.setCursor(0, 20);
  display.println(hum);

  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 70;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + box_h - 6;
  uint32_t value = 1395;
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  display.setRotation(0);
  // draw background
  display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
  delay(2000);

  // partial update to full screen to preset for partial update of box window
  // (this avoids strange background effects)
  display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_flip_x | GxEPD::bm_partial_update);
  delay(1000);

  // show where the update box is
  for (uint16_t r = 0; r < 4; r++)
  {
    display.setRotation(r);
    display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_BLACK);
    //display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_BLACK);
    delay(1000);
    display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_WHITE);
  }
  // show updates in the update box
  for (uint16_t r = 0; r < 4; r++)
  {
    display.setRotation(r);
    for (uint16_t i = 1; i <= 10; i++)
    {
      uint32_t v = value * i;
      display.drawPagedToWindow(showValueBoxCallback, box_x, box_y, box_w, box_h, v);
      delay(500);
    }
    delay(1000);
    display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_WHITE);
  }
}

The code compiles without errors, however the sensor values are not present on the EPD. This is where I need help. I tried to put the sensor code directly in the loop section, but that also doesnt seem to work. Please guide me in this regard. Further, I have changed the hardware setup, so the Uno is replaced by Arduino Mini Pro 3.3v/8mhz version and the display is powered directly through it (connected to VCC). The demo code works flawlessly but its the sensor data that does not show up.

Thanks.

I don't see where you try to draw your sensor values.

I have added a sort of recipe for multiple partial windows here.

I will no longer answer on this thread/topic.

bye

ZinggJM:
I don't see where you try to draw your sensor values.

Its just above the code that corresponds to your library. Maybe a little "Hello World" like example would be better for people not well versed in programming.

I have added a sort of recipe for multiple partial windows here.

I will no longer answer on this thread/topic.

A little wiki extrapolating various functions of your library would be good head start for new users. That way, you'd have less people bothering you about basics.

I should not ask if you do not wish to support your own creation. Thanks nonetheless for all your efforts though.

I request the moderators to lock this thread.

Lesson learnt: I shouldn't have answered to the OP at all.

ZinggJM:
Lesson learnt: I shouldn't have answered to the OP at all.

You have merely expressed your ego in all those posts. If you do not wish to read the code and figure out which part is your own code and which belongs to the user, it does reflects something substantial and an unwillingness to help.