Waveshare e-paper displays with SPI

@skdfsjlsld, Hi, welcome to the forum!

Please read How to get the best out of this forum.

Then please edit your post and put your code into a code window, using code tags, the </> command symbol. Then your code is more pleasant to read, and can be easily copied for test.
Consider to format your code first, using the Auto Format method of the Arduino IDE.

In the Displays section, you should provide clickable links to the devices in question, so anyone knows exactly what you use, although your information is clear enough for me.

I am busy for now, but may later look at your problem.

Jean-Marc

Sorry for not posting it correctly for the first time, I have edited it now. I appreaciate any help!

I have solved it. As my screen resolution is 296x128, I have scanned 296x128 images horizontally. But it turns out, that is only working if I scan 128x296 images horizontally. I dont really understand why, but it works.

class GxEPD2_290_T94_V2 : public GxEPD2_EPD
{
  public:
    // attributes
    static const uint16_t WIDTH = 128;
    static const uint16_t HEIGHT = 296;
    static const GxEPD2::Panel panel = GxEPD2::GDEM029T94;

PS: the bitmap of your code is 55 * 128. It is shown correctly with:

    display.drawBitmap(0, 0, keret, 55, 128, GxEPD_BLACK);

Hello.
I have several t5d ink screens and the manufacturer's 4-level gray source code, but I don't integrate my bottom code into your library. I hope to add gray function in the future. If you need my gray code, I can email you.
In addition, this is one of my projects. Thank you for your library!
Multifunctional ink screen for weather, reading, clock and distribution network.

你好。
我有几块T5D墨水屏,也有厂家的4阶灰度源码,但我底层代码我不太会融合到你的库里面,希望日后能添加灰度功能,如果需要我的灰度代码,我可以发电邮给你。

另外,这是我的一个项目,很感谢你提供的库!
天气、阅读、时钟、配网多功能墨水屏。

Hi guys! I am building a rotary encoder based menu with an e-paper display. I fell like that the "while (display.nextPage()); " function is blocking my code, and while my screen is refreshing it doesnt record any rotary encoder changes, making the whole menu laggy. What could I do to avoid it?

@skdfsjlsld

You won't get a detailed answer without a detailed question, e.g. library used, display used, processor used.

With GxEPD2 you would need to use interrupts and interrupt handling for your rotary encoder.

Jean-Marc

Hello,

i'm trying to get a 3,7" 480x280 B/W display from waveshare working with an eps8266 (NodeMcu) together with GxEPD2 but i can't figure out wich driverclass to use.
i can't find the display on gooddisplay or the used controller in the datasheet.

Display

Datasheet

can anyone help me with that?

littleC

@littlec, Hi, welcome to the forum!

Thank you for the links. I didn't notice that e-paper display so far.

I have no idea who supplies the panel. Seems to be neither Good Display nor DKE CO, LTD.

The controller might be from Ultra Chip, looking at the command list. SSD1677.

I think I will ask Waveshare for a free sample, to add support to GxEPD2.
But I will first look if I will order anything else I am interested in from Waveshare.

I suggest to first check if an e-paper display is supported by GxEPD2, before buying it.
Or consider a donation.

Jean-Marc

added:
3.7inch E-Paper E-Ink Display HAT For Raspberry Pi, 480×280 Pixels, Black / White, 4 Grey Scales, SPI Interface (waveshare.com)
3.7inch E-Paper E-Ink Raw Display, 480×280 Pixels, Black / White, 4 Grey Scales, SPI Interface, Without PCB (waveshare.com)
3.7inch e-Paper HAT - Waveshare Wiki
SSD1677_1.0 (waveshare.com)

update:
I have made up my mind and decided to order this e-paper panel. It is interesting for me, too.

Dear, i have problem when switching through this two partial parts of the epd.
Display is messed up.
What am i missing here in these two functions?
btw .setPartialWindow is working ok, when selected once and not changed.
regards

void loop() {
einkDataEng(i,i,i);
einkDataAc(i,i,4,1);
  i++;
  if(i>10){i=0;}
  }
void einkDataEng(uint8_t r, uint8_t f,uint8_t e){upper display part
  
      display.setPartialWindow(0,0,128,128);
      r=map(r,0,/*actual data input*/10,0,116); // scale input value to bar length
      f=map(f,0,/*actual data input*/10,0,116);
      e=map(e,0,/*actual data input*/10,0,116);
      do{
      display.fillRect(6, 21, 116, 15, GxEPD_WHITE);
      display.fillRect(6, 21, r, 15, GxEPD_BLACK);
      display.fillRect(6, 61, 116, 15, GxEPD_WHITE);
      display.fillRect(6, 61, f, 15, GxEPD_BLACK);
      display.fillRect(6, 101, 116, 15, GxEPD_WHITE);
      display.fillRect(6, 101, e, 15, GxEPD_BLACK);
      } while (display.nextPage());  
      Serial.println("ENG DATA SHOWN");
}

void einkDataAc( uint8_t t, uint8_t s, uint8_t d , uint8_t ac){ lower display part
  
      display.setPartialWindow(0,136,128,160);
      t=map(t,0,/*actual data input*/10,0,125); // scale input value to bar length
      s=map(s,0,/*actual data input*/10,0,125);
       do{
            switch(d){
              display.fillRect(7, 212, 114, 37, GxEPD_WHITE);
                case 0:
                        display.drawBitmap(10, 215 ,front_on,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(48, 215 ,down_off,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(86, 215 ,up_off,  35, 35, GxEPD_BLACK);
                        break;
                case 1:
                        display.drawBitmap(10, 215 ,front_on,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(48, 215 ,down_on,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(86, 215 ,up_off,  35, 35, GxEPD_BLACK);                
                        break;
                case 2:
                        display.drawBitmap(10, 215 ,front_off,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(48, 215 ,down_on,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(86, 215 ,up_off,  35, 35, GxEPD_BLACK);                
                        break;
                case 3:
                        display.drawBitmap(10, 215 ,front_off,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(48, 215 ,down_on,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(86, 215 ,up_on,  35, 35, GxEPD_BLACK);                
                        break;
                case 4:
                        display.drawBitmap(10, 215 ,front_off,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(48, 215 ,down_off,  35, 35, GxEPD_BLACK);
                        display.drawBitmap(86, 215 ,up_on,  35, 35, GxEPD_BLACK);                
                        break;
            }

            switch(ac){
              display.fillRect(0, 256, 128, 40, GxEPD_WHITE);
                case 0:
                        display.drawBitmap(15, 256,ac_off,  40, 40, GxEPD_BLACK);
                        display.drawBitmap(72, 256,ac_off,  40, 40, GxEPD_BLACK);
                        break;
                case 1:
                        display.drawBitmap(15, 256,ac_on,  40, 40, GxEPD_BLACK);
                        display.drawBitmap(72, 256,ac_off,  40, 40, GxEPD_BLACK);
                        break;
                case 2:
                        display.drawBitmap(15, 256,ac_on,  40, 40, GxEPD_BLACK);
                        display.drawBitmap(72, 256,ac_on,  40, 40, GxEPD_BLACK);
                        break;
                            }
                 
      display.fillRect(1, 141, 125, 15, GxEPD_WHITE);
      display.fillRect(1, 141, t, 15, GxEPD_BLACK);
      display.fillRect(6, 178, 125, 15, GxEPD_WHITE);
      display.fillRect(1, 178, s, 15, GxEPD_BLACK);
      } while (display.nextPage());  
      Serial.println("A/C DATA SHOWN");
}

@stefanb1, Hi, welcome to the forum!

Please read How to get the best out of this forum, if you haven't done yet.

Thank you for using a code window for showing your code.
But please use the auto format feature of the Arduino IDE before pasting; some errors are easier to detect with well formatted code text.

Please always provide complete information. Display used, with clickable link, processor used, connection module or wiring used to connect.

The code provided should be complete, so anyone can try it directly.

I assume you have successfully run at least one of the examples, e.g. GxEPD2_Example.ino.

Your code might work better if you don't leave out display.firstPage() for the page loop.

Jean-Marc

thanks for reply, I sent you only problematic function part when switching through partial segments that i want to be updated and other should be intact. (GxEPD2_290_T5)
I am getting experience that, when i use .setPartialWindow (for example (0,0,128,200):wink: display set x,y(0,128) as new x,y(0,0) and start drawing from that corner. As result i get duplicate picture

Regarding .firstPage and .nextPage functions, i am not really sure when to use them and what is their role in sequence, also .refresh is not clear to me.

Read README.md of the library, and take a look at the example GxEPD2_Example.ino to see how to use the page loop.

Else I can't help you.

The MagTag uses a WFT0290CZ10LW display. I am using the following:

#define ENABLE_GxEPD2_GFX 1
#include <GxEPD2_BW.h>
#include <GxEPD2_3C.h>
// display class, matching the kind of display panel
#define GxEPD2_DISPLAY_CLASS GxEPD2_BW
// display driver class for your  panel
#define GxEPD2_DRIVER_CLASS GxEPD2_290_M06 // GDEW029M06  128x296, UC8151 (IL0373)

and it works but only has b/w. Are there more appropriate choices so I can take advantage of the grayscale or am I just doing something wrong? Thank you.

@craig02445, Hi, welcome to the forum!

GxEPD2 supports only b/w, 3-color and a 7-color e-paper displays.

GxEPD2_4G supports some b/w e-paper displays that can show 4 grey levels. But this library is still experimental and supports only few displays. GDEW029M06 is not (yet) supported.

I would expect your display is well supported by Adafruit software and library.

Jean-Marc

Thanks for the information. I will gladly beta test anything if you need. Last I checked Adafruit did not support partial refresh ... Thanks and keep up the fantastic work.

Hi everybody!

as a beginner, I'm struggling to connect the following hardware:

Waveshare 4.2" ePaper
https://www.waveshare.com/wiki/4.2inch_e-Paper_Module
VCC 3.3V
GND GND
DIN SPI MOSI
CLK SPI SCK
CS SPI chip select (Low active)
DC Data/Cmd control pin (High for data, and low for command)
RST External reset pin (Low for reset)
BUSY Busy state output pin (Low for busy)

AND A

TTGO-LoRa32-V2.1

I struggle to identify these pins on the TTGO... (can't find DIN, CLK, CS, DC, RST, BUSY, ... I have tried for hours, and I think I'm dumb...)

I'm fully autodidact, and "new" to arduino and C is a real pain in the back for me, because I come from PHP and don't declare variables :smiley: ... but I learn fast, and already built a weather station already, with a remote arduino sending the temp via WIFI, but the range beeing too limited, I now try to upgrade the thing with radio instead, but I feel really stupid because I can't even wire the damn thing... so so stupid...

So ... please, ... anyone could help me on that one?

Thank in advance :wink:

@b0b0, Hi, welcome to the forum!

Things always get tricky when related to TTGO boards. But I try to answer anyway.

I assume you compile for TTGO LoRa32-OLED V1.

In C:\Users\ZinggJ\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.1\boards.txt
I find ttgo-lora32-v1.name=TTGO LoRa32-OLED V1
and ttgo-lora32-v1.build.variant=ttgo-lora32-v1
In C:\Users\ZinggJ\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.1\variants\ttgo-lora32-v1\pins_arduino.h
I find:

static const uint8_t SS    = 18;
static const uint8_t MOSI  = 27;
static const uint8_t MISO  = 19;
static const uint8_t SCK   = 5;

These are the usual HW SPI pins used for Arduino on ESP32.

So you would need to connect DIN to 27 (MOSI) and CLK to 5 (SCK).
You would connect CS to 18 (SS), but this pin is already used for LORA.
Connect CS to any free output capable GPIO, as well for DC and RST.
And BUSY to any other free GPIO.

Jean-Marc

Bonjour Jean-Marc =)
Thanks a lot for your answer, I really would like this to work!

When you say

So you would need to connect DIN to 27 (MOSI) and CLK to 5 (SCK).
You would connect CS to 18 (SS), but this pin is already used for LORA.
Connect CS to any free output capable GPIO, as well for DC and RST.
And BUSY to any other free GPIO.

The thing where I am having trouble, is that some of the pins you're mentioning cannot be found physically on the TTGO board...
ex: connect DIN to 27 (MOSI)
I cannot see GPIO 27 on the board... (and that goes for other pins too)

I am not talking about the software configuration, but the physical connection between the waveshare & the ttgo lora32... I'm looooost :cry:

Any idea?

Many thanks again for your input!
Baudouin

// SPI LoRa Radio
#define LORA_SCK 5        // GPIO5 - SX1276 SCK
#define LORA_MISO 19     // GPIO19 - SX1276 MISO
#define LORA_MOSI 27    // GPIO27 - SX1276 MOSI
#define LORA_CS 18     // GPIO18 - SX1276 CS
#define LORA_RST 14   // GPIO14 - SX1276 RST
#define LORA_IRQ 26  // GPIO26 - SX1276 IRQ (interrupt request)

I don't know what LoRa1, LoRa2 pins are. Most likely two of these.

I think you can find schematics on the TTGO website, or on their GitHub site.