Go Down

Topic: Good Dispay ePaper for Arduino (Read 114015 times) previous topic - next topic

ZinggJM

#450
Jan 06, 2021, 11:29 am Last Edit: Jan 06, 2021, 11:31 am by ZinggJM
@emde34,

thank you for the diagnostic output.

Comparison of the refresh times with my display makes it clear that your display has a different waveform table.
Full refresh times are similar, I have either ~2509602us (early morning) or ~1986670us, depending on temperature.
But differential refresh times are considerably different, I have ~456740us.

From some distance (in time) I found an obvious alternative solution to the refresh mode dependent buffer switching of this controller:

Code: [Select]
void GxEPD2_154_D67::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
{
  // this controller switches buffers (ping-pong) after differential refresh (display mode 2), but not after full refresh (display mode 1)
  // the easy solution is to update both buffers. both buffers need be set equal and equal to the display after refresh.
  _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm);
  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
}


But for some unknown reason this doesn't work completely with my display. It still works with ping-pong disabled.

The symptoms are a white screen instead Hello World!, grey Hello World on the second screenful, and some remains on the 200x200 partial refresh screens.

I attach the modified GxEPD2_154_D67.cpp file, so you could check the behavior with your screen and report.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

emde34

#451
Jan 06, 2021, 07:38 pm Last Edit: Jan 06, 2021, 07:39 pm by emde34
I think I get the same behavior as your display. But it's definitely better than before.
Full updates work ok (except first hello world). Partial updates kinda work but as your said, the previous ram content still remains and slowly fades out as partial updates go on.

I'm currently working on my own subclass of Adafruit GFX inspired from Good display's code, your library and Adafruit EPD.
So far I got the full update and partial update (in full window) to work. I still need to rework the ram settings for partial update in a partial window but it looks promising. I'll post the code when done.

Using the panel settings from good display code:
For full updates: I write either the buffer to the black ram (0x24) or both black and red ram (0x24+0x26) . Both seems to work.
For partial update. I write both rams in a full update first, and then do only black ram 0x24 writings before triggering a partial update.


ZinggJM

@emde34

thank you for providing the information I had asked for.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

emde34

Hi Jean Marc,
I'm trying to wrap my head around the partial window ram settings (0x44, 0x45, 0x4e 0x4f) but my brain is about to get fried.
I got the full update and partial update in full window working but I just can't find the good RAM settings for partial window partial updates!


I got it to kind of work by writing the full buffer instead of just the partial buffer window but it's far from great.
I just can't find good documentation on these controllers and need to take a break before I throw my display through the window.

Attached is my code if you want to test how it does with your display. Full and partial updates work on mine.
I'll post cleaner code in the next days.

ZinggJM

#454
Jan 08, 2021, 07:35 am Last Edit: Jan 08, 2021, 07:37 am by ZinggJM
@emde34,

you don't need to throw away your e-paper display.

The controller of this display needs both previous and current buffer to be written with the same data before a full refresh, if the ping-pong enable bit is set, because of an undocumented feature of the controller.

You can either wait for the next version of GxEPD2.

Or you can take a look at the controller specs for command 0x2d and 0x37 for read or write Display Option Registers. Use 0x2d to read the option registers of your display, and adapt the parameters of the 0x37 command in _InitDisplay(). Clear the ping-pong enable bit (F[6]).
To read from the controller with GxEPD2, you can use the SW SPI option, see extras/sw_spi/README.MD

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

ZinggJM

Version 1.2.16 of library GxEPD2 is available through Library Manager.


fix for GDEH0154D67, to work independent of OTP version (ping-pong issue)


Jean-Marc

No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

emde34

Thank you Jean-Marc for the fix, works well now.

Cheers from canton de Vaud ;)

ZinggJM

Hi @ZinggJM ,

Thank you for the impressive work you have done in setting up this library.

I owe a screen that I guess to be refered as GDEH029Z13.

I did a test with your library (GxEPD2) using GDEW029Z10 (b/w/r) and GDEW029T5 (b/w) references.

Both of them are almost working using the HelloWorld example, except for a small strip at the top of the screen that does not refresh at all. (see attached picture)

I would have liked to know if you can give me some indications on what to adapt in the library to make it work?

Thank you for your help,
Quote
Thank you for the panel you sent.

It is a 2.6" 3-color e-paper display of unknown provenience.

It has a 24 pin flex connector with marks for pin 1 and pin 24.

I connected it to a DESPI-C02 with pin 1 to pin 1, pin 24 to pin 24, bottom connection.
Maybe this was wrong. It didn't survive. Connecting the other way didn't work either.
I should have asked you how you connected, or a link to information.

Neither Good Display nor Waveshare have this display, so I would not have added it to GxEPD2 anyway.
They have a 2.66" 3-color display with a different controller.

Never send ESD sensible devices without ESD protection bag. It may have been dead on arrival.

Jean-Marc
I need to learn how to deal with devices of unknown provenience and improper ESD protection.
Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

claudius310

Hello,
I have a little problem writing using the library: U8g2_for_Adafruit_GFX.h. in GxPD2 with an epaper screen:
https://www.waveshare.com/6inch-e-Paper-HAT.htm (800 x 600)
I would like to write with a character size larger than u8g2_font_logisoso92_tn, but I can't find a solution.
Any ideas?

Thank you
Jean-Claude

claudius310

hello,
To adapt the font size to different screens, I found a small application on the internet that makes libraries that can be used in Adafruit GFX Font format.
You simply have to position the writing with a certain offset because the library produced is suitable for smaller screens
http://oleddisplay.squix.ch/#/home

Jean-Claude

d2468

I'm using GXEPD2_MultiDisplayExample with an Arduino Nano 33 Iot and three 2.9in DES displays with the DESPI-C02 (GDEW029M06) for each display.

I'm having trouble with partial refresh. It is leaving a significant ghosting effect running the example showPartialUpdate(). (See photos).
I tried enabling and disabling hasFastPartialUpdate and it had no change.
I tried using GDEW029 and GDEW029_T5. The screen did not work with 029. It worked with _T5 and had less ghosting but it was still there. There was less contrast with _T5 (see attached).

I adapted the example to work with the SAMD processor. I added in the three display instances.
For my wiring, each CS has its own pin, and each BUSY has its own pin. RST are disconnected (-1).
All SCK->D13. All SDI-> D11. All DC->D6. Power supply is going to the 3.3V out on the board (pin #17).
Code: [Select]
#if defined(ARDUINO_ARCH_SAMD)
#define RST_PIN 25 // D3(0)
#define MAX_DISPLAY_BUFFER_SIZE 15000ul // ~15k is a good compromise
#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_290_M06, MAX_HEIGHT(GxEPD2_290_M06)> display1(GxEPD2_290_M06(/*CS=4*/ 2, /*DC=*/ 6, /*RST=*/ -1, /*BUSY=*/ 4)); // GDEW029M06
GxEPD2_BW<GxEPD2_290_M06, MAX_HEIGHT(GxEPD2_290_M06)> display2(GxEPD2_290_M06(/*CS=4*/ 5, /*DC=*/ 6, /*RST=*/ -1, /*BUSY=*/ 7)); // GDEW029M06
GxEPD2_BW<GxEPD2_290_M06, MAX_HEIGHT(GxEPD2_290_M06)> display3(GxEPD2_290_M06(/*CS=4*/ 8, /*DC=*/ 6, /*RST=*/ -1, /*BUSY=*/ 9)); // GDEW029M06
#endif


Do you know what might be going on?

Thanks.






ZinggJM

@d2468,

thank you for the detailed information about what you want to achieve.

I would suggest you first try one display with GxEPD2_Example.ino.
The approach to try different driver classes is ok, but the correct driver class for your DES display is GxEPD2_290_M06.

I would need to know the RESE position you selected that corresponds to your pictures.
It should be set to 0.47 ohms, see page 9 of GDEW029M06-201110.pdf.

If you disable hasFastPartialUpdate (by setting this attribute to false in GxEPD2_290_M06.h) you should see only full updates, refresh with flashing effect, and have no resulting ghosting.

My tests showed only minimal ghosting on the panel I have, and I think I use the same waveform (same parameters) as the demo from Good Display. But you can experiment yourself by changing values in GxEPD2_290_M06.cpp at lines beginning at 329:

Code: [Select]
// this panel doesn't seem to need balanced charge

#define T1  0 // charge balance pre-phase
#define T2  0 // optional extension
#define T3 25 // color change phase (b/w)
#define T4  0 // optional extension for one color
#define T5  0 // white sustain phase
#define T6  0 // black sustain phase


Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

d2468

Thanks for the quick response. 
The RESE is set to 0.47. It doesn't work at all when set to 3. 

I'm always using GXEPD2_290_M06 for the driver class. I tried a couple times with other driver classes to see what would happen. 

There is no ghosting when doing a full screen refresh. It's only when doing partial refresh that the ghosting is visible.

When disabling FastPartialUpdate, it displays "slow partial mode" as expected. It still runs the routine of 
Code: [Select]
if (display3.epd2.hasPartialUpdate)
  {
    showPartialUpdate(display3);
  }

The ghosting looks the same when FastPartialUpdate is enabled or disabled. 

When running GXEPD2_Example with one display, the ghosting looks the same. 

So it seems like this might be a waveform issue? 
I was comparing the Good Display example code to the values in GxEPD2_290_M06.cpp. How does the good display code compare to yours? For example, from Good Display P202001204 Ap_29demo.h :
Code: [Select]
const unsigned char lut_vcom1[] PROGMEM={
0x00  ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  ,0x00 ,0x00,          };


In your code GxEPD2_290_M06.cpp
Code: [Select]
const unsigned char GxEPD2_290_M06::lut_20_vcomDC_partial[] PROGMEM =
{
  0x00, T1, T2, T3, T4, 1, // 00 00 00 00
};



Are these two equivalent? I'm not familiar with this style of coding.

If I begin to experiment with the waveforms, what values could T1-T6 span? 0 to 1? 0 to 25?
If this is more than you're willing to support, that's okay. 

Thanks for the help.



d2468

One more interesting note. 
When running GxEPD2_Example, I connected the reset and defined the pins (using the same pins from my display3 in MultiExample. Everything worked as expected.

On going back to MultiExample, I disconnected the reset pin and ran the same code from before. However, now display3 doesnt work. I had to move to a different busy pin. Then sometimes, it would give me a "Busy Timeout!" on the serial monitor. 
After I disconnected the power to the Arduino, it behaves better but sometimes that same display hangs up. 

I'll have to do some more methodical testing to understand why this is happening

ZinggJM

@d2468,

I would expect that your Arduino Nano 33 Iot has enough pins, so you could use a separate RST pin for each display.

Then test again. I got confused by your two posts, don't really understand what worked and what didn't.

Methodical testing and reporting is a good idea.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

Go Up