GxEPD2 Waveshare 1.54" R2.1 & Raspberry Pico W

I wondering if anyone can help with getting a Waveshare 1.54" paper display working with a Raspberry Pico W and GxEPD2 library. I'm struggling a little and failing to get the display to work, code compiles and uploads, I've been trying to use the GxEPD2_Example.ino and stripped it back to basics to make it more understandable, SPI configuration as per comments in code.

The display does work using the SPI pins and the WaveShare example code but not GxEPD2

#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include "bitmaps/Bitmaps200x200.h" // 1.54" b/w

#define ENABLE_GxEPD2_GFX 0
#define MAX_DISPLAY_BUFFER_SIZE 131072ul // e.g. half of available ram
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))

//GxEPD2_BW<GxEPD2_150_BN, MAX_HEIGHT(GxEPD2_150_BN)> display(GxEPD2_150_BN(/*CS=*/ 9, /*DC=*/ 8, /*RST=*/ 12, /*BUSY=*/ 13)); // DEPG0150BN 200x200, SSD1681, TTGO T5 V2.4.1
//GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ 9, /*DC=*/ 8, /*RST=*/ 12, /*BUSY=*/ 13)); // GDEP015OC1 200x200, IL3829, no longer available

// Waveshare-Paper 1.5" Rev 2.1
// Raspberry Pico W, pins:
// DC 	- GP08
// CS	  - GP09
// CLK  -	GP10
// DIN  - GP11
// RESET- GP12
// BUSY	- GP13
GxEPD2_BW<GxEPD2_154_D67, MAX_HEIGHT(GxEPD2_154_D67)> display(GxEPD2_154_D67(/*CS=*/ 9, /*DC=*/ 8, /*RST=*/ 12, /*BUSY=*/ 13)); // GDEH0154D67 200x200, SSD1681

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

  //display.init(115200); // default 10ms reset pulse, e.g. for bare panels with DESPI-C02
  display.init(115200, true, 2, false); // USE THIS for Waveshare boards with "clever" reset circuit, 2ms reset pulse
  //display.init(115200, true, 10, false, SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0)); // extended init method with SPI channel and/or settings selection
  // first update should be full refresh

  helloWorld();

  // remaining code as per original example```

See C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\mbed_rp2040\4.0.6\variants\RASPBERRY_PI_PICO\pins_arduino.h:

// SPI
#define PIN_SPI_MISO  (16u)
#define PIN_SPI_MOSI  (19u)
#define PIN_SPI_SCK   (18u)
#define PIN_SPI_SS    (17u)

static const uint8_t SS   = PIN_SPI_SS;   // SPI Slave SS not used. Set here only for reference.
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK  = PIN_SPI_SCK;

GxEPD2 uses HW SPI. If you want to use other pins for MOSI and SCK than the default ones, then you need to remap pins. See comments in GxEPD2_Example.ino
-jz-

Thank you for the prompt reply, I'm sorry that I'm not an expert when it comes to Arduino & SPI configuration and I'm not sure if I fully understood your reply. So few basic questions:

  • Am I using the correct driver, GDEH0154D67 for the WaveShare 1.54" display?
  • Have I included the correct remapping code you referred to and is it correct, what should be used for MISO if not used or connect?
  • display.epd2.selectSPI I have no idea what this is doing, I've just cut 'n' pasted from example.

I'm still failing to see any updates on the display.

#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include "bitmaps/Bitmaps200x200.h"  // 1.54" b/w

#define ENABLE_GxEPD2_GFX 0
#define MAX_DISPLAY_BUFFER_SIZE 131072ul  // e.g. half of available ram
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))

// Waveshare-Paper 1.5" Rev 2.1
// Raspberry Pico W, pins:
static const uint8_t EPD_MISO = 4;  // not used or connected, as no data from display
static const uint8_t EPD_DC   = 8;
static const uint8_t EPD_CS   = 9;
static const uint8_t EPD_SCK  = 10;
static const uint8_t EPD_MOSI = 11;
static const uint8_t EPD_RST  = 12;
static const uint8_t EPD_BUSY = 13;

#if defined(ARDUINO_ARCH_RP2040) && defined(ARDUINO_RASPBERRY_PI_PICO)
// SPI pins used by GoodDisplay DESPI-PICO. note: steals standard I2C pins PIN_WIRE_SDA (6), PIN_WIRE_SCL (7)
// uncomment next line for use with GoodDisplay DESPI-PICO. // MbedSPI(int miso, int mosi, int sck);
arduino::MbedSPI SPI0(EPD_MISO, EPD_MOSI, EPD_SCK);  // need be valid pins for same SPI channel, else fails blinking 4 long 4 short
#endif

GxEPD2_BW<GxEPD2_154_D67, MAX_HEIGHT(GxEPD2_154_D67)> display(GxEPD2_154_D67(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));  // GDEH0154D67 200x200, SSD1681
//GxEPD2_BW<GxEPD2_150_BN, MAX_HEIGHT(GxEPD2_150_BN)> display(GxEPD2_150_BN(/*CS=*/ 9, /*DC=*/ 8, /*RST=*/ 12, /*BUSY=*/ 13)); // DEPG0150BN 200x200, SSD1681, TTGO T5 V2.4.1
//GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ 9, /*DC=*/ 8, /*RST=*/ 12, /*BUSY=*/ 13)); // GDEP015OC1 200x200, IL3829, no longer available

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

#if defined(ARDUINO_ARCH_RP2040) && defined(ARDUINO_RASPBERRY_PI_PICO)
  // uncomment next line for use with GoodDisplay DESPI-PICO, or use the extended init method
  display.epd2.selectSPI(SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0));
  // uncomment next 2 lines to allow recovery from configuration failures
  pinMode(15, INPUT_PULLUP);            // safety pin
  while (!digitalRead(15)) delay(100);  // check safety pin for fail recovery
#endif

  //display.init(115200); // default 10ms reset pulse, e.g. for bare panels with DESPI-C02
  display.init(115200, true, 2, false);  // USE THIS for Waveshare boards with "clever" reset circuit, 2ms reset pulse
  //display.init(115200, true, 10, false, SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0)); // extended init method with SPI channel and/or settings selection
  // first update should be full refresh

  helloWorld();```

No, they actually use the panels know as DEPG0150BN. Same controller, but no waveform table for differential refresh in OTP. Compare the inking on the flexible connector with GxEPD2_display_selection_new_style.h.

Yes, but bad MISO pin. Pins 10, 11 are available for SPI channel SPI1, pin 4 is available for SPI0.
Use any pin for MISO that belongs to the same channel.
Mixing pins of SPI channels will cause a fatal exception, and can lead to upload problems.

The Waveshare code most likely uses SW SPI.

I see that default HW SPI pins of the RP2040 package have been changed since I had tested, so my wiring suggestion in GxEPD2_wiring_examples.h is no longer valid for RP2040.

I don't know the Raspberry Pico W, but I found a pinout: https://cdn.shopify.com/s/files/1/0176/3274/files/Raspberry-Pi-Pico-W-Pinout_1.jpg

I use to ask for links to the devices in question.
-jz-

Great, thank you for your updates the display is working perfectly, the key changes were the SPI port & PIN's and the correct driver.

#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include "bitmaps/Bitmaps200x200.h"  // 1.54" b/w

#define ENABLE_GxEPD2_GFX 0
#define MAX_DISPLAY_BUFFER_SIZE 131072ul  // e.g. half of available ram
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))

// Waveshare-Paper 1.5" Rev 2.1
// Raspberry Pico W, pins:
static const uint8_t EPD_MISO = 4;  
static const uint8_t EPD_DC   = 16;
static const uint8_t EPD_CS   = 17;
static const uint8_t EPD_SCK  = 18;
static const uint8_t EPD_MOSI = 19;
static const uint8_t EPD_RST  = 20;
static const uint8_t EPD_BUSY = 21;

#if defined(ARDUINO_ARCH_RP2040) && defined(ARDUINO_RASPBERRY_PI_PICO)
arduino::MbedSPI SPI0(EPD_MISO, EPD_MOSI, EPD_SCK);  
#endif

GxEPD2_BW<GxEPD2_150_BN, MAX_HEIGHT(GxEPD2_150_BN)> display(GxEPD2_150_BN(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // DEPG0150BN 200x200, SSD1681, TTGO T5 V2.4.1

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

#if defined(ARDUINO_ARCH_RP2040) && defined(ARDUINO_RASPBERRY_PI_PICO)
  display.epd2.selectSPI(SPI0, SPISettings(4000000, MSBFIRST, SPI_MODE0));
  pinMode(15, INPUT_PULLUP);         
  while (!digitalRead(15)) delay(100); 
#endif

  display.init(115200, true, 2, false);  // USE THIS for Waveshare boards with "clever" reset circuit, 2ms reset pulse

  helloWorld();```

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