Seeed Xiao ePaper Breakout Board and XIAO ESP32S3 and a GooDisplay 184x88 screen not working with GxEPD2_BW

Hi all,

Im using the Seeed Xiao ePaper Breakout Board and XIAO ESP32S3 and a GooDisplay 0.97 inch screen.

I have it printing text to the screen using the GxEPD2_BW library (GxEPD2_102). The screen notes that it has a 184x88 resolution. I can set the static const uint16_t HEIGHT = 188; but if I set the static const uint16_t WIDTH = 80; to anything else (e.g. 84 or 88) the text becomes gibberish.

If I print an image at 184x88 though I can use the whole screen dimensions. I’m assuming somewhere else in the GxEPD2_BW code there’s something I missed for setting screen dimensions correctly?

Has anyone else had any experience with this screen? It would be great to get printing text working on this screen. So tiny and versatile!

This is my test script working with a 188x80 image setting that works mostly (minus the missing 8 pixel rows):

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

// Define pins
#define BUSY_PIN D5
#define RES_PIN D0
#define DC_PIN D3
#define CS_PIN D1
// 
// Define color constants
#define EPD_BLACK 0
#define EPD_WHITE 1

GxEPD2_BW<GxEPD2_102, GxEPD2_102::HEIGHT> display(GxEPD2_102(CS_PIN, DC_PIN, RES_PIN, BUSY_PIN));

void setup() {
  Serial.begin(9600);
  display.init();
}

void loop() {
  // For debugging.

  display.fillScreen(GxEPD_WHITE);
  display.setTextColor(GxEPD_BLACK);
  display.setFont(&FreeMonoBold9pt7b);

  display.setCursor(20, 140);
  display.print("Hello");
  display.display();
  delay(5000);

  display.fillScreen(GxEPD_WHITE);
  display.display();
  delay(5000);
}

Hi there,
Not sure if this helps or not, but I tried the Xiao Nrf52840 with this E-ink and it worked if I used the specifig version of GxEPD.
Check that out , code is attached.

HTH
GL :slight_smile: PJ :v:

Thanks for the suggestion!

I was able to find the culprit. The GxEPD2_102 library sets the height in two spots.

Here in the GxEPD2_102.h file:

class GxEPD2_102 : public GxEPD2_EPD
{
  public:
    // attributes
    static const uint16_t WIDTH = 88;
    static const uint16_t WIDTH_VISIBLE = WIDTH;
    static const uint16_t HEIGHT = 184;```

and here in the GxEPD2_102.cpp file as hex values:

void GxEPD2_102::_InitDisplay()
{
  if (_hibernating) _reset();
  _writeCommand(0xD2); // ??
  _writeData(0x3F);
  _writeCommand(0x00); // Panel Setting Register
  _writeData (useOTPforFullRefresh ? 0x4F : 0x6F);   // LUT from OTP or from Registers
  _writeCommand(0x01); // Power Setting
  _writeData (0x03);   // internal VDH/VDL VGH/VGL
  _writeData (0x00);   // VDG_LVL +15,-15
  _writeData (0x2b);   // VDH_LVL +11
  _writeData (0x2b);   // VDL_LVL -11
  _writeCommand(0x06); // Charge Pump Setting
  _writeData(0x3f);    // 50ms, Stength 4, 8kHz
  _writeCommand(0x2A); // LUT Option
  _writeData(0x00);    // no all gate on
  _writeData(0x00);    // 0..5 : 10s, 20..30 : 4.8s
  _writeCommand(0x30); // PLL
  _writeData(0x13);    // 30 Hz
  _writeCommand(0x50); // VCOM and Data interval setting
  _writeData(0x57);    // default
  _writeCommand(0x60); // TCON
  _writeData(0x22);    // 24us
  _writeCommand(0x61); // Resolution Setting
  _writeData(0x58);    // HRES 88 (0x58 in hex)
  _writeData(0xB8);    // VRES 184 (0xB8 in hex)
  _writeCommand(0x82); // Vcom DC Setting
  _writeData(0x12);    // -1 V
  _writeCommand(0xe3); // Power Saving
  _writeData(0x33);    //
}

Appears to be working fine with text now! Just need to set rotation so it prints parallel to the length. This is working code (with the changes to the GxEPD2_102.h and GxEPD2_102.cpp library files in case anyone else wants to use the micro screen with the SEEED Xiao :star_struck::

#include <SPI.h>
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
// Define pins
#define BUSY_PIN D5
#define RES_PIN D0
#define DC_PIN D3
#define CS_PIN D1
// Define color constants
#define EPD_BLACK 0
#define EPD_WHITE 1
GxEPD2_BW<GxEPD2_102, GxEPD2_102::HEIGHT> display(GxEPD2_102(CS_PIN, DC_PIN, RES_PIN, BUSY_PIN));

void setup() {
  Serial.begin(9600);
  display.init();
  display.setRotation(1); // Rotate display 90 degrees clockwise
}

void loop() {
  display.fillScreen(GxEPD_WHITE);
  display.setTextColor(GxEPD_BLACK);
  display.setFont(&FreeMonoBold9pt7b);
  display.setCursor(20, 20);
  display.print("Hello world!");
  display.display();
  delay(5000);
  display.fillScreen(GxEPD_WHITE);
  display.display();
  delay(5000);
}
1 Like

Hi there,
Lets see a Picture of this masterpiece :grin: :+1:
good Stuff :v:
GL :slight_smile: PJ

I spoke to soon. I was planning on printing the GPS readout from the Xaio GPS hat, but there seems to be a conflict with the pins :frowning: As soon as the epaper starts the GPS stops.

Just found this article so maybe related:

Hmmm, seems the GPS shares pins with the epaper breakout. Can’t get it working at all. One or the other.

Hi there,
Does this run?

#include <SPI.h>
//EPD
#include "Display_EPD_W21_spi.h"
#include "Display_EPD_W21.h"
#include "Ap_29demo.h"  


void setup() {
#ifdef ESP8266
   pinMode(D0, INPUT);  //BUSY
   pinMode(D1, OUTPUT); //RES 
   pinMode(D2, OUTPUT); //DC   
   pinMode(D4, OUTPUT); //CS     
#endif 
#ifdef Arduino_UNO
   pinMode(4, INPUT);  //BUSY
   pinMode(5, OUTPUT); //RES 
   pinMode(6, OUTPUT); //DC   
   pinMode(7, OUTPUT); //CS   
#endif 
   //SPI
   SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); 
   SPI.begin ();  
}

//Tips//
/*
1.Flickering is normal when EPD is performing a full screen update to clear ghosting from the previous image so to ensure better clarity and legibility for the new image.
2.There will be no flicker when EPD performs a partial refresh.
3.Please make sue that EPD enters sleep mode when refresh is completed and always leave the sleep mode command. Otherwise, this may result in a reduced lifespan of EPD.
4.Please refrain from inserting EPD to the FPC socket or unplugging it when the MCU is being powered to prevent potential damage.)
5.Re-initialization is required for every full screen update.
6.When porting the program, set the BUSY pin to input mode and other pins to output mode.
*/
void loop() {
   unsigned char i;
#if 1 //Full screen refresh, fast refresh, and partial refresh demostration.

      EPD_HW_Init(); //Full screen refresh initialization.
      EPD_WhiteScreen_White(); //Clear screen function.
      EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
      delay(2000); //Delay for 2s. 
     /************Full display(2s)*******************/
      EPD_HW_Init(); //Full screen refresh initialization.
      EPD_WhiteScreen_ALL(gImage_1); //To Display one image using full screen refresh.
      EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
      delay(2000); //Delay for 2s. 

  #if 1 //Partial refresh demostration.
  //Partial refresh demo support displaying a clock at 5 locations with 00:00.  If you need to perform partial refresh more than 5 locations, please use the feature of using partial refresh at the full screen demo.
  //After 5 partial refreshes, implement a full screen refresh to clear the ghosting caused by partial refreshes.
  //////////////////////Partial refresh time demo/////////////////////////////////////
      EPD_HW_Init(); //Electronic paper initialization. 
      EPD_SetRAMValue_BaseMap(gImage_basemap); //Please do not delete the background color function, otherwise it will cause unstable display during partial refresh.
      for(i=0;i<6;i++)
      EPD_Dis_Part_Time(32,56+24*0,Num[i],         //x-A,y-A,DATA-A
                        32,56+24*1,Num[0],         //x-B,y-B,DATA-B
                        32,56+24*2,gImage_numdot, //x-C,y-C,DATA-C
                        32,56+24*3,Num[0],        //x-D,y-D,DATA-D
                        32,56+24*4,Num[1],24,32); //x-E,y-E,DATA-E,Resolution 24*32
                        
      EPD_DeepSleep();  //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
       delay(2000); //Delay for 2s. 
      EPD_HW_Init(); //Full screen refresh initialization.
      EPD_WhiteScreen_White(); //Clear screen function.
      EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
       delay(2000); //Delay for 2s. 
  #endif  
  
  #if 0 //Demo of using partial refresh to update the full screen, to enable this feature, please change 0 to 1.
  //After 5 partial refreshes, implement a full screen refresh to clear the ghosting caused by partial refreshes.
  //////////////////////Partial refresh time demo/////////////////////////////////////
      EPD_HW_Init(); //E-paper initialization 
      EPD_SetRAMValue_BaseMap(gImage_p1); //Please do not delete the background color function, otherwise it will cause an unstable display during partial refresh.
      EPD_Dis_PartAll(gImage_p1); //Image 1
      EPD_Dis_PartAll(gImage_p2); //Image 2
      EPD_Dis_PartAll(gImage_p3); //Image 3
      EPD_Dis_PartAll(gImage_p4); //Image 4
      EPD_Dis_PartAll(gImage_p5); //Image 5 
      EPD_DeepSleep();//Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
      delay(2000); //Delay for 2s. 
      EPD_HW_Init(); //Full screen refresh initialization.
      EPD_WhiteScreen_White(); //Clear screen function.
      EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
      delay(2000); //Delay for 2s. 
  #endif
  
  #if 0 //Demonstration of full screen refresh with 180-degree rotation, to enable this feature, please change 0 to 1.
      /************Full display(2s)*******************/
      EPD_HW_Init_180(); //Full screen refresh initialization.
      EPD_WhiteScreen_ALL(gImage_1); //To Display one image using full screen refresh.
      EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
      delay(2000); //Delay for 2s. 
  #endif        
  
#endif

#ifdef ESP8266
  while(1) 
    {
     Sys_run();//System run
     LED_run();//Breathing lamp
    }
#endif
#ifdef Arduino_UNO
 while(1);  // The program stops here   
#endif
}

GL :slight_smile: PJ
:v:

from here?
GDEM0097T61_Arduino.zip (11.6 KB)

Sorry, I should have been a little more clear. Got the ePaper screen working perfectly. Prints text correctly on the tiny screen.

My plan was to have it output the values from the Xiao L76K GNSS Module, but if they are plugged in together then they both wont work together at the same time.

If I flash the ESP32S3 with the GNSS code, it works printing to serial fine. If I flash with the epaper screen it updates fine. If I try read the GNSS while the epaper is running, then I get no GNSS data (this is with them all stacked together).

I could probably reroute the pins from the GPS, but as the GPS is currently soldered to the ESP32S3, I think this is where it ends. No GNSS epaper love :smiling_face_with_tear:

1 Like