GxEPD2 using esp32 - lilygo higrow

I'm struggling with a very strange problem.
I use lilygo higrow board which is an eps32 driven board with many sensors built in.
I hooked up a 1.54 inch 200x200 e-ink display to display the sensors' data.
When printing anything to the e-ink display however, the character (or rects/circles etc.) seem to get randomly offset every time.
It seems like every line from top to bottom offsets more and more.
Also, on rare occasions, the display prints fine.

I tested the display using a regular esp32 dev board and the display worked fine.

In this example, it should display two columns of boxes aligned to the left.

Does someone have an idea why this happens?

That line in your code may be incorrect or not but until we can see the line the line, troubleshooting the line would be guesswork.

Interesting doing a e-ink display with only 3 wires.

1 Like

This is the code. Pretty basic.
The pins should be correct. I tripple checked.
CS=5, DC=17, RST=15, BUSY=27, CLK=18, SDI=23

Also this display uses all regular pins. its not a 3 wire display. You just cant see them in the picture :wink:

#include <Wire.h>
#include <GxEPD2_BW.h> 
#include "GxEPD2_display_selection_new_style.h"

void setup()
{
  Serial.begin(115200);
  display.init();
  display.setTextColor(GxEPD_BLACK);
  display.firstPage();
}

void loop() {
  delay(1000);
  do
  {
    display.fillScreen(GxEPD_WHITE);
    display.drawRect(0, 0, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 0, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 30, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 30, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 60, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 60, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 90, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 90, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 120, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 120, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 150, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 150, 20, 20, GxEPD_BLACK);
  }
  while (display.nextPage());
};

in that file which thingy did you uncomment?

I prefer to copy the library instantation from the .h file and paste it directly into my ino
Like so.

GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEW042T2

This ends up being the only include from the library I use

#include <GxEPD2_BW.h>

Without seeing the new style thingy you picked tracking down issues will be problematic.

Thanks for your tip. I also pasted the instantiation in my main.cpp like you now.
Now the code looks like this:

#include <Wire.h>
#include <GxEPD2_BW.h> 

GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 15, /*BUSY=*/ 27));

void setup()
{
  Serial.begin(115200);
  display.init();
  display.setTextColor(GxEPD_BLACK);
  display.firstPage();
}

void loop() {
  delay(1000);
  do
  {
    display.fillScreen(GxEPD_WHITE);
    display.drawRect(0, 0, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 0, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 30, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 30, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 60, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 60, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 90, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 90, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 120, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 120, 20, 20, GxEPD_BLACK);
    display.drawRect(0, 150, 20, 20, GxEPD_BLACK);
    display.drawRect(30, 150, 20, 20, GxEPD_BLACK);
  }
  while (display.nextPage());
};

Still got the same issue tho

I'm getting ready to go on a road trip. Here is some code that I use to do the e-ink thing. I'm doing things a bit different and hope these things gives you some ideas to get you going.

void fDoTheDisplayThing( void * parameter )
{
  float *ptr = CollectionPressure;
  int yIncrement = 18;
  int CurrentY = 20;
  int CurrentX = 5;
  String temp1 = "";
  temp1.reserve(10);
  String temp2 = "";
  temp2.reserve(10);
  int boxSpacing = 80;
  size_t item_size;
  for (;;)
  {
    xEventGroupWaitBits (eg, evtDisplayUpdate, pdTRUE, pdTRUE, portMAX_DELAY );
    xSemaphoreTake( sema_eData, portMAX_DELAY );
    struct stu_eData px_eData = x_eData;
    xSemaphoreGive ( sema_eData );
    CurrentY = 20;
    display.init();
    //display.setFont(&FreeMonoBold9pt7b);
    display.setFont(&FreeMono9pt7b);
    //u8g2Fonts.setFont(u8g2_font_helvB08_tf);
    display.setTextColor(GxEPD_BLACK);
    display.setFullWindow();
    display.fillScreen(GxEPD_WHITE); // set the background to white (fill the buffer with value for white)
    display.setCursor( CurrentX, CurrentY );
    // first line
    display.drawRect( CurrentX, CurrentY , 70, 55, GxEPD_BLACK);
    display.drawBitmap( CurrentX + 10, CurrentY + 5, temperature_icon16x16, 16, 16, GxEPD_BLACK);
    display.setCursor( CurrentX + 30, CurrentY + 15 );
    //display.print( char(223) + "F" );
    display.print( "F" );
    display.setCursor( CurrentX + 10, CurrentY + 40);
    display.print( String(px_eData.oTemperature) );
    display.drawRect( CurrentX + boxSpacing, CurrentY , 70, 55, GxEPD_BLACK);
    display.setCursor( CurrentX + 90, CurrentY + 15 );
    display.print( "R.H.");
    display.setCursor( CurrentX + 90, CurrentY + 35 );
    display.print( String((int)px_eData.oHumidity) + "%" );
    display.setCursor( CurrentX, CurrentY + 40);
    display.drawRect( CurrentX + (boxSpacing * 2 ), CurrentY , 70, 55, GxEPD_BLACK);
    display.setCursor( CurrentX + 163, CurrentY + 15 );
    display.print( "Dew Pt" );
    display.setCursor( CurrentX + 165, CurrentY + 35 );
    display.print( String(px_eData.DewPoint) );
    display.drawRect( CurrentX + (boxSpacing * 3 ), CurrentY , 70, 55, GxEPD_BLACK);
    display.setCursor( CurrentX + 246, CurrentY + 15 );
    display.print( "AQI" );
    display.setCursor( CurrentX + 246, CurrentY + 35 );
    display.print( String(int(px_eData.IAQ)) + "%" );
    display.drawRect( CurrentX + (boxSpacing * 4 ), CurrentY , 70, 55, GxEPD_BLACK);
    display.setCursor( CurrentX + 327, CurrentY + 15 );
    display.print( "R.M." );
    display.setCursor( CurrentX + 327, CurrentY + 35 );
    display.print( String(int(px_eData.RM0)) + "%" );
    // end of first line
    if ( px_eData.SunRiseMin < 10 )
    {
      temp1.concat( "0" + String(px_eData.SunRiseMin) );
    } else {
      temp1.concat( String(px_eData.SunRiseMin) );
    }
    if ( px_eData.SunSetMin < 10 )
    {
      temp2.concat( "0" + String(px_eData.SunSetMin) );
    } else {
      temp2.concat( String(px_eData.SunSetMin) );
    }
    CurrentY += yIncrement;
    CurrentY += yIncrement;
    CurrentY += yIncrement;
    CurrentY += yIncrement;
    display.setCursor( CurrentX, CurrentY );
    display.print( "Wind: " );
    CurrentY += yIncrement;
    display.setCursor( CurrentX, CurrentY );
    display.print( "Speed " + String(px_eData.WS) + "KPH, Dir " + String(px_eData.WD) + " Chill " + String(px_eData.WindChill) + "F" );
    CurrentY += yIncrement;
    display.drawRect( CurrentX, CurrentY , 70, 55, GxEPD_BLACK);
    addsun( 35, CurrentY + 30 , Small, SmallIcon );
    display.setCursor( CurrentX + 5, CurrentY + 15 );
    display.print( "0" + String(px_eData.SunRiseHr) + ":" + temp1 );
    display.setCursor( CurrentX + 5, CurrentY + 50 );
    display.print( String(px_eData.SunSetHr) + ":" + temp2 );
    display.drawRect( CurrentX + boxSpacing, CurrentY , 70, 55, GxEPD_BLACK);
    addraindrop(CurrentX + 110, CurrentY + 15, 7);
    display.setCursor( CurrentX + 90, CurrentY + 35 );
    display.print( String(px_eData.RF) );
    display.setCursor( CurrentX + 100, CurrentY + 50 );
    display.print( "mm" );
    display.drawRect( CurrentX + (boxSpacing * 2 ), CurrentY , 70, 55, GxEPD_BLACK);
    display.setCursor( CurrentX + 177, CurrentY + 15 );
    display.print( "C02" );
    display.setCursor( CurrentX + 165, CurrentY + 35 );
    display.print( String(int(px_eData.CO2)) );
    display.setCursor( CurrentX + 165, CurrentY + 50 );
    display.print( "PPM" );
    //make graph
    xSemaphoreTake( sema_CollectPressure, portMAX_DELAY );
    CurrentY += yIncrement * 6;
    display.setCursor( CurrentX, CurrentY); //set cursor position
    //display.drawLine( CurrentX, CurrentY, CurrentX + 200, CurrentY, GxEPD_BLACK);
    //int BaseLine = (int)CollectionPressure[0];
    int BaseLine = (int)*ptr;
    int offsetX = 0;
    for ( int j = 0; j < BufferCount; j++ )
    {
      if ( *(ptr + j) != 0.0f )
      {
        //int yAdj = BaseLine - (int)CollectionPressure[j];
        int yAdj = BaseLine - (int)*(ptr + j);
        display.setCursor( CurrentX + offsetX, CurrentY + yAdj );
        display.print( "-" );
        offsetX += 5;
        // log_i( "pressure %f item %d", CollectionPressure[j], j );
      }
    }
    CurrentY += yIncrement;
    display.setCursor( CurrentX, CurrentY );
    display.print( String(px_eData.oPressure) + "mmHg" );
    int Xone = 48;
    int Yone = 59;
    CurrentY += yIncrement;
    display.setCursor( CurrentX, CurrentY );
    display.print( PressureRateOfChange() );
    xSemaphoreGive( sema_CollectPressure );
    temp2 = "";
    temp1 = "";
    //
    display.display(false); // full update
    display.hibernate();
    //log_i( "DoTheBME280Thing high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
  } //for (;;)
  vTaskDelete( NULL );
} //void fDoTheDisplayTHing( void * parameter )
////

Sadly this didnt really help. Like I said, the code works on my other board with no issue.
It kinda looks like some sort of timing issue with the data transfer?

I noticed something interesting.
When connecting RST with GND, then disconnect from GND again the next display refresh will look good...
Dont know what to make of this tho...

For anyone who stumbles upon this.
For me this issue was cause by a broken cable.
So the boards should work fine with e-ink displays like any other esp32 board.

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