GxEPD2 & Good display GDEY0213B74

Hi all,

I'm trying to use the GxEPD2 library by @ZinggJM with a GDEY0213B74 eink display plugged into a Adafruit RP2040 Feather ThinkInk.

I've tried to run both GxEPD2_HelloWorld and GxEPD2_Example (in the GxEPD2 repo), but to no avail. Selecting the display by uncommenting the display in "_new_style.h" file throws an error at compile time (variable display does not exist) and using the "old style" compiles but nothing happens on screen.

I'm not sure what else I should share, let me know if I missed a key piece of information. Any ideas how to debug this?

@cpa, hi, welcome to the forum!

For your compile issue, I need to know what board you selected to compile for, from which package.
If it is an unofficial package, I need the link to the package.
Please also report the Arduino IDE version you use.
Which line - line number - did you uncomment in GxEPD2_display_selection.h, to successfully compile?

For your "nothing happens on screen" issue, I need links to your devices.
Is the "Adafruit RP2040 Feather ThinkInk" the complete processor with display?
I don't like to need to go searching!
What connection does it/you use to the display panel, pin-to-pin?
Please also report the inking found on the flexible connector of the display panel.
-jz-

1 Like

Here's the details, hope I understood your questions correctly! Thanks for taking some time for me.

  • I have this display: Good display GDEY0213B74
  • I have this board, which has a 24-pin connector : Adafruit RP2040 Feather Think Ink: "At the Feather's heart is an RP2040 chip, clocked at 133 MHz and at 3.3V logic". It is a ARM Cortex M0+ chip.
  • The board is directly connected to which the GDEY0213B74 display using the 24-pin connector.
  • Arduino 2.2.1, on an Intel Mac
  • The board in the Arduino app is "Adafruit Feather ThinkInk RP2040", installed in the Arduino app following this doc. It adivses installing the boards from this package.
  • On the flexible connector, there's FPC-A002 / 20.04.08 maybe the last digit is 3instead of 8 I can't really tell.

In the GxEPD2_Example from your repo:

  • When I uncomment the line 36 #define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // GDEM0213B74 122x250, SSD1680, FPC-7528B) in GxEPD2_display_selection_new_style.h I get this compilation error: Compilation error: 'display' was not declared in this scope; did you mean 'delay'?
  • When I uncomment the line 34 GxEPD2_BW<GxEPD2_213_GDEY0213B74, GxEPD2_213_GDEY0213B74::HEIGHT> display(GxEPD2_213_GDEY0213B74(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4)); // GDEY0213B74 122x250, SSD1680, (FPC-A002 20.04.08) in GxEPD2_display_selection.h I have the same error
  • When I uncomment any lines the GxEPD2_display_selection.h files that contains GDEY0213B74, still the same error (I wasn't sure which architecture I should target so I tried that…)
  • I can't reproduce the "it compiles but nothing happens" I had yesterday. But what I reported just above is from a fresh copy of the examples in the repo. Yesterday, I had probably hacked the files a bit too much for sane debugging anyway.

@cpa, thank you for the additional information!

It confirms what I guessed: you use an unofficial package. This package - of course - uses different conditional compile symbols. That's why none of the conditional compile sections in the display_selection files apply, and therefore display is not defined.

GxEPD2_HelloWorld.ino has a short part that gives a hint for what to do:

// alternately you can copy the constructor from GxEPD2_display_selection.h or GxEPD2_display_selection_added.h to here
// e.g. for Wemos D1 mini:
//GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4)); // GDEH0154D67

means you copy a constructor line, one that matches your display, to outside of any conditional section, and adapt it to your wiring.

Or you add a matching conditional compile symbol of your board selection to the best matching conditional compile section. ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK

I took a quick look at https://github.com/earlephilhower/arduino-pico/blob/master/boards.txt
to find a suitable conditional compile symbol. It is too large, so I will have to install the package later and do a test compile.

This information is contained in https://learn.adafruit.com/assets/57645, but I don't have time to extract that information.

And here:
https://github.com/earlephilhower/arduino-pico/blob/master/variants/adafruit_feather_thinkink/pins_arduino.h
-jz-

1 Like

That makes a lot of sense, thanks! I was convinced I was using an official package since it's the one linked here. Since I'm very new to all this, I did not realise that was not an official resource (maybe those guides are community based?).

I don't mind changing package if that's simpler. So I guess I should try using an official package for Raspberry Pi Pico ? (on which the board seems to be based?).

I've now installed "Arduino MBed OS RP2040 Boards" by Arduino and using the Raspberry Pi Pico, it indeed compiles but still nothing happens on screen (I see "setup done" on the serial monitor though)

I don't have time right now to investigate further and I'll be away for a few days, but I'll report on my progress asap.

You need to adapt the constructor parameters to the wiring used by the Adafruit board.
And you may need to remap the HW SPI pins to the wiring used, if you use the official package.

1 Like

Using the pins_arduino.h, I've tried the following, unsuccessfully (I've also tried countless variations, but this the one that makes most sense):

Using your GxPED_Example sketch and doing what I mentioned above, I also:

  • In _new_style.h, I've defined my display after #if defined(ARDUINO_RASPBERRY_PI_PICO) // adapt the constructor parameters to your wiring as GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ 19, /*DC=*/ 18, /*RST=*/ 17, /*BUSY=*/ 16));
    • I know this the right place to define my display as if I comment this line I get the "display undefined" error.
  • In the GxEPD2_Example.ino, I changed the SPI0 definition arduino::MbedSPI SPI0(8, 15, 14); (as per the github link above)
    • I've uncommented the line display.init(115200, true, 10, false, SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0));
    • I've also tried with 16, 19, 22 which are the corresponding SPI0 pins in this doc

Still nothing on screen, although I can read the debug info on the Serial monitor (_Upadate_Part, _PowerOn and such).

A few things that strike me as odd:

  • The PINs I've used (from here) do not match the schematic which itself do not match (for SPI0) this doc.
  • I don't know how to read schematics but:
    • In the bottom right corner it refers to a eInk display (which is different than mine), not to the board? (although is it indeed linked from the board product page)
    • I can't find any way to reconcile the github lib with the schematic

Finally, I should add that using the package (the very first one I used) and the lib Adafruit EPD, I was able to use part of the screen (the top fifth of the screen is completely random but otherwise I can draw just fine), so the hardware is fine. I was then able to crosscheck that my values for CS, DC, RST and BUSY were right (using Serial.print(EPD_CS)) since those were the one used in the "working" sketch, but I was not able to extract the requied values for SPI because the data is private to the object and I could not find a way to print it.

If anything, I don't really feel like I'm making progress :frowning:

There are two problems I have with your issue:

  • I don't have that Adafruit board, so I can't check.
  • I can't check with the schematics, as they left out the processor!

Therefore I must rely on the information from the earlephilhower/arduino-pico package.

// EPD connector
#define PIN_EPD_BUSY   (16u)
#define PIN_EPD_RESET  (17u)
#define PIN_EPD_DC     (18u)
#define PIN_EPD_CS     (19u)
#define PIN_EPD_SCK    (22u)
#define PIN_EPD_MOSI   (23u)
// SPI
#define PIN_SPI0_MISO  (8u)
#define PIN_SPI0_MOSI  (15u)
#define PIN_SPI0_SCK   (14u)
#define PIN_SPI0_SS    (13u)
#define __SPI0_DEVICE  spi1

// EPD SPI
#define PIN_SPI1_MISO  (31u)
#define PIN_SPI1_MOSI  (23u)
#define PIN_SPI1_SCK   (22u)
#define PIN_SPI1_SS    (19u)
#define __SPI1_DEVICE  spi0

EPD is set to use channel spi0. But strangely using global instance SPI1. Channels are swapped.
There is a global instance for it in SPI.cpp:

#ifndef __SPI0_DEVICE
#define __SPI0_DEVICE spi0
#endif
#ifndef __SPI1_DEVICE
#define __SPI1_DEVICE spi1
#endif

SPIClassRP2040 SPI(__SPI0_DEVICE, PIN_SPI0_MISO, PIN_SPI0_SS, PIN_SPI0_SCK, PIN_SPI0_MOSI);
SPIClassRP2040 SPI1(__SPI1_DEVICE, PIN_SPI1_MISO, PIN_SPI1_SS, PIN_SPI1_SCK, PIN_SPI1_MOSI);

The global instance to use is SPI1.

This is what I used to test-compile:

#if defined(ARDUINO_ARCH_RP2040)
#define MAX_DISPLAY_BUFFER_SIZE 131072ul // e.g. half of available ram
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
#if defined(ARDUINO_NANO_RP2040_CONNECT)
// adapt the constructor parameters to your wiring
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
#endif
#if defined(ARDUINO_RASPBERRY_PI_PICO)
// adapt the constructor parameters to your wiring
//GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // my proto board
// mapping of GoodDisplay DESPI-PICO. NOTE: uses alternate HW SPI pins!
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ 3, /*DC=*/ 2, /*RST=*/ 1, /*BUSY=*/ 0)); // DESPI-PICO
//GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ 3, /*DC=*/ 2, /*RST=*/ 11, /*BUSY=*/ 10)); // DESPI-PICO modified
#endif
#if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK)
// Adafruit Feather RP2040 ThinkInk used with package https://github.com/earlephilhower/arduino-pico
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ PIN_EPD_CS, /*DC=*/ PIN_EPD_DC, /*RST=*/ PIN_EPD_RESET, /*BUSY=*/ PIN_EPD_BUSY));
#endif
#undef MAX_DISPLAY_BUFFER_SIZE
#undef MAX_HEIGHT
#endif

Uncomment and modify this line to use SPI1 with GxEPD2_Example:

  display.epd2.selectSPI(SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));

I hope this helps, but I can't check.
-jz-

1 Like

Looks like it works!

When using the RP2040 ThinkInk from earlephilhower, the symbol ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK was not defined (I got the display undefined error). So I moved the display definition outside any conditional and changed the GxEPD2_Example to use SPI1 and I got this (and the other examples) :

I haven't thoroughly tested yet, bot looks like this issue is now resolved.

To sum it up, for future hackers facing the same issue:

  • Use earlephilhower RP2040 ThinkInk board (see the package.json link and the doc in my first posts)
  • Using the GxEPD2_Example sketch
    • Uncomment #define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // GDEM0213B74 122x250, SSD1680, FPC-7528B) in _new_style.h
    • Put GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ PIN_EPD_CS, /*DC=*/ PIN_EPD_DC, /*RST=*/ PIN_EPD_RESET, /*BUSY=*/ PIN_EPD_BUSY)); right above (so outside of all if macros) #undef MAX_DISPLAY_BUFFER_SIZE in the same file. You can hunt for the symbol to put inside a IF if you're brave
    • In the main .ino file, add display.epd2.selectSPI(SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0)); above display.init(115200);

Many, many, many thanks for your support and your patience, I learnt a lot in the process!

1 Like

Thank you for the feedback!

There was a # missing before the if. -> #if

I shouldn't try to do two things at the same time.
And I should look at the result of a test-compile before posting.

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