Go Down

Topic: Waveshare e-paper displays with SPI (Read 208997 times) previous topic - next topic

ZinggJM

Hi szehrer,

Quote
On the cable it is written: HINK-E0213A22
I do have a panel with this inking. It is sold by Good Display named GDEH0213B73:

2.13 inch e-paper display module partial refresh e-ink screen GDEH0213B73

It is supported by GxEPD2, see README.MD or post #1409

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

db2

Hello folks!

Need help using national languages ​​(especially Russian :) with the gxepd library.

Is there a tool for creating a cyrillic font compatible with gxepd?

ZinggJM

Hello folks!

Need help using national languages (especially Russian :) with the gxepd library.

Is there a tool for creating a cyrillic font compatible with gxepd?
You can use any font created for Adafruit_GFX with GxEPD or GxEPD2.

Or you can use U8g2_for_Adafruit_GFX with GxEPD or GxEPD2 (easier with GxEPD2), and look for a Cyrillic font in U8g2:

https://github.com/olikraus/u8g2/wiki/fntlistall

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

ZinggJM

GxEPD2 Version 1.2.1 is available, installable or updated with Library Manager.

- added support for GDEW075T7 7.5" b/w 800x480
- GDEW075T7 has differential update (1.6s) using a charge balancing waveform
- added optional SW SPI support, see /extras/sw_spi/README
- added /extras/tests/GxEPD2_RefreshTests/GxEPD2_RefreshTests.ino, for waveform tuning
- minor fixes
- note that 7.5" e-paper displays don't work reliable if fed from 3.3V Arduino pin

The GDEW075T7 is an excellent e-paper display, with high resolution, good contrast and acceptable refresh time.

The seller Good Display doesn't know yet that this display supports differential refresh; a charge balancing waveform needs to be used to avoid ghosting, leading to a relatively slow (1.6s) "fast partial update".
This e-paper is also available on their AliExpress shop: https://www.aliexpress.com/item/33049611415.html

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Fenix42

ZinggJM,

Just wanted to drop a quick thank you to you for all of the work that you have done. Really helping me with a project. Keep up the good work.

goosst

#1505
Sep 22, 2019, 03:03 pm Last Edit: Sep 22, 2019, 03:25 pm by goosst
Hello,

thanks for the nice library, however I don't understand how I can get multiple displays to work (I've started from your GxEPD2_MultiDisplayExample but can't get it to work on my two 7.5" displays).

The displays work when used individually with an ESP32 (this example: https://github.com/G6EJD/ESP32-e-Paper-Weather-Display, so nothing should be wrong with the wiring).
To be fair, I don't understand c++, so I'm quite lost with all the constructing stuff that is ongoing to debug your example properly.

Code: [Select]

#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>

//HSPI
static const uint8_t EPD_BUSY1 = 25;  // to EPD BUSY
static const uint8_t EPD_RST1  = 34; // to EPD RST
static const uint8_t EPD_DC1   = 32; // to EPD DC
static const uint8_t EPD_CS1   = 15;  // to EPD CS
static const uint8_t EPD_SCK1  = 14; // to EPD CLK
static const uint8_t EPD_MISO1 = 12; // Master-In Slave-Out not used, as no data from display
static const uint8_t EPD_MOSI1 = 13; // to EPD DIN
GxEPD2_BW<GxEPD2_750, GxEPD2_750::HEIGHT> display1(GxEPD2_750(/*CS=*/ EPD_CS1, /*DC=*/ EPD_DC1, /*RST=*/ EPD_RST1, /*BUSY=*/ EPD_BUSY1));   // B/W display


//VSPI
static const uint8_t EPD_BUSY = 4;  // to EPD BUSY
static const uint8_t EPD_CS   = 5;  // to EPD CS
static const uint8_t EPD_RST  = 21; // to EPD RST
static const uint8_t EPD_DC   = 22; // to EPD DC
static const uint8_t EPD_SCK  = 18; // to EPD CLK
static const uint8_t EPD_MISO = 19; // Master-In Slave-Out not used, as no data from display
static const uint8_t EPD_MOSI = 23; // to EPD DIN
GxEPD2_BW<GxEPD2_750, GxEPD2_750::HEIGHT> display2(GxEPD2_750(/*CS=*/ EPD_CS, /*DC=*/ EPD_DC, /*RST=*/ EPD_RST, /*BUSY=*/ EPD_BUSY));   // B/W display

// comment out unused bitmaps to reduce code space used
#include "bitmaps/Bitmaps640x384.h" // 7.5"  b/w

template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void helloWorld(T<GxEPD2_Type, page_height>& display);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void helloFullScreenPartialMode(T<GxEPD2_Type, page_height>& display);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void helloArduino(T<GxEPD2_Type, page_height>& display);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void helloEpaper(T<GxEPD2_Type, page_height>& display);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void showBox(T<GxEPD2_Type, page_height>& display, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool partial);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void drawCornerTest(T<GxEPD2_Type, page_height>& display);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void showFont(T<GxEPD2_Type, page_height>& display, const char name[], const GFXfont* f);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void drawBitmaps(T<GxEPD2_Type, page_height>& display);
template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
void showPartialUpdate(T<GxEPD2_Type, page_height>& display);

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

  display1.init(115200); // enable diagnostic output on Serial
  delay(1000);
  display2.init(115200); // enable diagnostic output on Serial
  Serial.println("displays initialized");

  Serial.println("helloWorld display 1");
  display1.setRotation(1);
  display1.setFont(&FreeMonoBold9pt7b);
  display1.setTextColor(GxEPD_BLACK);
  uint16_t x = (display1.width() - 160) / 2;
  uint16_t y = display1.height() / 2;
  display1.setFullWindow();
  display1.firstPage();
  do
  {
    display1.fillScreen(GxEPD_WHITE);
    display1.setCursor(x, y);
    display1.println("Hello World!");
  }
  while (display1.nextPage());
  Serial.println("helloWorld display 1 finished");
  delay(1000);

  Serial.println("helloWorld display 2");
  display2.setRotation(1);
  display2.setFont(&FreeMonoBold9pt7b);
  display2.setTextColor(GxEPD_BLACK);
  x = (display2.width() - 160) / 2;
  y = display2.height() / 2;
  display2.setFullWindow();
  display2.firstPage();
  do
  {
    display2.fillScreen(GxEPD_WHITE);
    display2.setCursor(x, y);
    display2.println("Hello World!");
  }
  while (display2.nextPage());
  Serial.println("helloWorld display 2 finished");

  delay(1000);
  Serial.println("setup done");
}

void loop()
{
}

 

ZinggJM

#1506
Sep 22, 2019, 05:21 pm Last Edit: Sep 23, 2019, 07:01 am by ZinggJM
Hi goosst,

I apologize for confusing Newbies with my examples; I am definitely not a good teacher.

There are 2 examples for using multiple e-paper displays, one is the intended example for users, and one I have kept as "abschreckendes Beispiel", discouraging example, using template functions.

I should have added an additional comment in "GxEPD2_MultiDisplayExample.ino" to discourage its use, or I should have put it in a different directory, but wanted to keep it after I finally got it working:

Code: [Select]
// Ok, I will learn how to use nested templates in my next life, maybe
// Ok, this works at least, maybe I learned enough for a start


The example intended for use is "GxEPD2_GFX_MultiDisplayExample.ino".
It uses a base class for the template classes, to allow to have simple display parameters in normal functions instead of needing to use template functions. The base class is available by enabling its use:

Code: [Select]
// base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter
// enable GxEPD2_GFX base class
#define ENABLE_GxEPD2_GFX 1


Please try again by starting with use of GxEPD2_GFX_MultiDisplayExample.ino.

Use this example directly for your 2 displays, using common SPI pins but separate pins for CS, BUSY and RST.

I recommend to use common SPI for both displays. You can't use separate SPI with GxEPD2, as GxEPD2 uses the HW SPI instance every Arduino has.

With only 2 displays you don't need to share BUSY and RST, which is also shown by the example.

Code: [Select]
// create display class instances for each display, each instance with different CS line, each instance with RST disabled,
// (or use separate RST pins for each display),
// each instance with different BUSY line, or BUSY lines or-ed to one pin
// disable reset line to disable cross resets by multiple instances


I hope this helps get you started. Please post again if you succeed or need more help.

Jean-Marc

Addition:

For ESP32 HW SPI class instance SPI is VSPI, see:
C:\Users\xxx\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3\libraries\SPI\src\SPI.cpp
at the end of this file:
Code: [Select]
SPIClass SPI(VSPI);


The pins for SPI are usually the processor default VSPI pins, but these can be re-mapped. You can find out in pins_arduino.h of the board you select to compile for, e.g.:
C:\Users\xxx\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3\variants\esp32\pins_arduino.h
Code: [Select]
static const uint8_t SS    = 5;
static const uint8_t MOSI  = 23;
static const uint8_t MISO  = 19;
static const uint8_t SCK   = 18;
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

goosst

Thanks for the detailed response! I'll probably find my way now :).

In this example below, it seems to be resolved in a slightly different way to use other SPI pins. Maybe there was a way to use all SPI's, so I don't have to create a lot of splicing pins that will probably get loose :).

https://github.com/G6EJD/ESP32-e-Paper-Weather-Display/blob/master/examples/Waveshare_7_5/Waveshare_7_5.ino

Code: [Select]

void InitialiseDisplay() {
  display.init(115200);
  SPI.end();
  SPI.begin(EPD_SCK, EPD_MISO, EPD_MOSI, EPD_CS);
  u8g2Fonts.begin(display); // connect u8g2 procedures to Adafruit GFX
  u8g2Fonts.setFontMode(1);                  // use u8g2 transparent mode (this is default)
  u8g2Fonts.setFontDirection(0);             // left to right (this is default)
  u8g2Fonts.setForegroundColor(GxEPD_BLACK); // apply Adafruit GFX color
  u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
  u8g2Fonts.setFont(u8g2_font_helvB10_tf);   // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
  display.fillScreen(GxEPD_WHITE);
  display.setFullWindow();
}

ZinggJM

This method changes, re-maps, the pins of the global SPI instance. I don't think it helps you to use different SPI pins for your multiple displays.
The same method is used in the GxEPD2_WS_ESP32_Driver.ino example.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Narceen

Hello ZinggJM,

can u tell me what Pins i need to connect ePaper Display Pins for an STM32L432KC Ladybug?

ZinggJM

#1510
Sep 24, 2019, 08:46 am Last Edit: Sep 24, 2019, 09:06 am by ZinggJM
No, I can't, I don't have that processor board, and the info in the Arduino package is confusing or wrong:

in C:\Users\xxx\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.6.1\variants\NUCLEO_L432KC\PeripheralPins.c:

Code: [Select]
//*** SPI ***

#ifdef HAL_SPI_MODULE_ENABLED
const PinMap PinMap_SPI_MOSI[] = {
  {PA_7,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PA_12, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  //  {PB_5,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PB_5,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
  {NC,    NP,    0}
};
#endif

#ifdef HAL_SPI_MODULE_ENABLED
const PinMap PinMap_SPI_MISO[] = {
  {PA_6,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PA_11, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  //  {PB_4,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PB_4,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
  {NC,    NP,    0}
};
#endif

#ifdef HAL_SPI_MODULE_ENABLED
const PinMap PinMap_SPI_SCLK[] = {
  {PA_1,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PA_5,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  //  {PB_3,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PB_3,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
  {NC,    NP,    0}
};
#endif

#ifdef HAL_SPI_MODULE_ENABLED
const PinMap PinMap_SPI_SSEL[] = {
  //  {PA_4,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {PA_4,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
  //  {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, // STLink RX
  //  {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, // STLink RX
  {PB_0,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
  {NC,    NP,    0}
};
#endif



And it may be dependent on the STM32 package you have installed in your Arduino IDE.

The package STM32GENERIC https://github.com/danieleff/STM32GENERIC/tree/master/STM32/variants is less confusing, but it doesn't support STM32L432KC. But see e.g. DISCOVERY_F429ZI\variant.h:

Code: [Select]
// Connected to on board LIS3DSH accelerometer, CS: PE3
#define MOSI PA7
#define MISO PA6
#define SCK PA5
#define SS PA4


I think these are the usual SPI pins for the Arduino global SPI instance.

For the other pins you can use any free GPIO pin.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

pfeerick

Hi ZinggJM  :)

Recently got this 1.54" 200x200 display, and  thought I'd use an ESP32 board to get it up and running. Using your library (GxEPD2@1.2.1) and the Adafruit GFX Library@1.5.7 it is working, but the full display isn't being used... Wiring is as suggested in the code, with the following initialiser...

Code: [Select]
GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));

I initially used 3v3, and then tried 5v on VCC with no difference in behaviour. What looks to be a date code on the ribbon shows 2018.12.26.

I'll add a picture tomorrow, but the current symptoms are when the display is in the same orientation as the photo in the listing (ribbon on the left,), the 'right side' stays blank and the 'top' is either blank, or has a black bar when running the `GxEPD2_Example` with some re-ordering of the functions so it works with PlatformIO. Is this a problem you've heard of before? I didn't find anything jumping out after some skimming and searches of the forum. Next up will be trying again with the Arduino IDE to make sure it's not something funny going on there.

ZinggJM

#1512
Sep 25, 2019, 03:42 pm Last Edit: Sep 25, 2019, 03:51 pm by ZinggJM
Hi pfeerick,

No, I never heard of this symptom. Do you have the option to observe diagnostic output on a serial monitor with your PlatformIO environment?

I can't think of any reason that could cause this, except a broken display.

The current 1.54" e-paper from Waveshare has a level converter chip on board, so yours seem to be older or not genuine.

https://www.waveshare.com/1.54inch-e-paper-module.htm

Quote
with some re-ordering of the functions
Seems examples for PlatformIO would need forward declarations? Arduino IDE does this hidden from the user.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

pfeerick

#1513
Sep 26, 2019, 02:18 am Last Edit: Sep 26, 2019, 02:20 am by pfeerick
Damn electronics!  :smiley-confuse:

I'd just ensured I was running the current Arduino, ESP32 platform and installed GxEDP2 on the Arduino IDE, and was taking photos before I tried the example program there... and in the process of doing so... the display went from this...



to this



Since I was moving the wires around a lot to get the display to sit in the right place for a photo, I'm guessing there was a dodgy connection there, as it is now using the full screen. So now at least it looks like I can start putting this display to work now... and hopefully this will help someone else if they get the same problem. It's running just fine now with a 'MH ET Live ESP32 MiniKit' ESP32 module.

And yes, since PlatformIO doesn't do all the preprocessing that the Arduino IDE does, it needs function prototypes / forward declarations per standard C++ requirements. But thankfully it doesn't seem to have introduced any problems of it's own! :)

Btw, this module does have the TI TXS0108E level shifter on it... and I would be worried if it weren't genuine, since it was from Waveshare, via Amazon... but you just never know! ;) Anyway, sorry for the noise, and thanks for the great library! :)





ZinggJM

@pfeerick, thank you for the feedback!

There is an issue with these new e-paper modules from Waveshare with level shifters when used with 3.3V processors. If you connect VCC to 3.3V the supply to the e-paper panel is marginal because of the drop caused by the LDO series regulator. If you connect VCC to 5V the high level of the BUSY signal will be too high for the 3.3V processor. Safe solution would be to use a series resistor on BUSY and 5V VCC.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Go Up