lovyan03 / LovyanGFX

SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Other
1.03k stars 189 forks source link

VCOM get / set in IT8951 #269

Closed martinberlin closed 1 year ago

martinberlin commented 1 year ago

Some epaper displays specially big ones like 9.7" where I'm using your component require a special VCOM setting that comes written in the display stickers.

I would like to propose to add to Panel_IT8951.cpp (and header) the following:

  uint16_t Panel_IT8951::getVCOM() {
    _write_command(IT8951_I80_CMD_VCOM);
    _write_word(0);
    uint16_t vcom[1] = { 0 };
    _read_words(vcom, 1);
    return vcom[0];
  }

  void Panel_IT8951::setVCOM(uint16_t vcom) {
    _write_command(IT8951_I80_CMD_VCOM);
    _write_word(0x0001);
    _write_word(vcom);
  }

(NOTE: I wanted to add this in a pull request myself but I'm not entirely familiar with your class structure)

Proposed from Waveshare IT8951 example here

Additional context

Check here in the photo where is coming VCOM in the display. I also suggest not to hardcode this setting since IT8951 save last VCOM (I think) So it could be set only once if desired.

And now this could not be done since it seems to be hardcoded to a certain value:

      _write_command(0x0039); //tcon vcom set command
      _write_word(0x0001);
      _write_word(2300); // 0x08fc -2.3 V which is high for most big displays

The problem is that using a too high VCOM makes strange things, like white becomes grayish and so on, but is not always it seems depend on the model (Which you are never 100% if it's the one that the seller of Aliexpress says it is)

Example of the VCOM label in a 1200*825 9.7" epaper IMG_1790

lovyan03 commented 1 year ago

@martinberlin Thank you for your suggestion. We have updated the develop branch and hope you will give it a try…!

martinberlin commented 1 year ago

Thanks a lot. I will try it as soon as I can hook my board again with the epaper.

One question though, from my CPP program, how can I access this methods?

// Your class instantiation, config, etc:
LGFX display;

// Doing:
uint16_t vcom = display.getPanel()->getVCOM();

// Getting:
// error: 'struct lgfx::v1::Panel_Device' has no member named 'getVCOM'

Can you please show me a short example?

lovyan03 commented 1 year ago

@martinberlin

Since the pointer obtained by getPanel is a basic type, dedicated methods for derived types cannot be called without modification.

You must use typecast.

uint16_t vcom = ((lgfx::Panel_IT8951*)(display.getPanel()))->getVCOM();
((lgfx::Panel_IT8951*)(display.getPanel()))->setVCOM(vcom);

Alternatively, a method may be provided when defining the LGFX type.

class LGFX : public lgfx::LGFX_Device
{
// ~~~~~~
public:
  void setVCOM(uint16_t v) { _panel_instance.setVCOM(v); }
  uint16_t getVCOM(void) { return _panel_instance.getVCOM(); }
};
// ~~~~~

LGFX display;

uint16_t vcom = display.getVCOM();
display.setVCOM(vcom);
martinberlin commented 1 year ago

Thanks a lot! The second one, method declared into the LGFX type sounds cleaner for me. I will try that one and let you know.

martinberlin commented 1 year ago

Hi @lovyan03 ,

In my opinion reading VCOM is returning a high number:

  uint16_t vcom = display.getVCOM();
  display.printf("%.2f C  vcom:%d", temp, vcom);

Reading VCOM Would expect a 4 digit number like 2180 (representing -2.18 V)

Now if I set it before using:

display.setVCOM(1178);

The number I get when doing display.getVCOM() printed in the epaper is: 64596 (Is pretty close to uint16_t limit which is 65535). Any ideas?

UPDATE: Same PCB you can see in the photo and Cinread IT8951 board below where send today to you. I hope they arrive safe and then you can also try this so we can make LovyanGFX the best component to drive this epapers.

From datasheet page 20:

When IT8951 is connected to the AC-panel, the four IO pins act as the VCOM voltage selection. Its output value is controlled by hardware engine according to the AC VCOM Table Register ACVTR0~ACVTR15(0x11C4~0x11E0, 0x122C~0x1248. When IT8951 is connected to the DC-panel, the four IO pins act as the GPO function. Its output value is directly controlled by register (0x0008~0x000C)

I'm at this point unsure if VCOM is saved in internal memory since I cannot read that in the datasheet of the chip. But I'm quite sure it got persisted on a different Waveshare IT8951 board. Will make some additional checks when the next Cinread PCB's arrive.

lovyan03 commented 1 year ago

@martinberlin I remembered that the data read timing had previously malfunctioned too early. I added a delay before reading vcom and updated the develop branch. See if this improves the situation.

I have confirmed that M5Paper is reading the correct values.

martinberlin commented 1 year ago

Thanks I will try in 10 days when the new Cinread boards from GoodDisplay arrive. Last one is shipped to you along with my SPI Master ESP32S3 PCB.

martinberlin commented 1 year ago

5AA7FFB3-DC9D-4E7B-AC59-D8F576CC07E9I I can confirm that now I can read and set VCOM:

Display.setVCOM(1178); // draws that with getVCOM

now there is still a weird effect that after setting VCOM sometimes randomly stops updating. Maybe it’s worth adding some ms delay after this? I think this won’t be the same to test in M5 epaper since the IT8951 has a different config. But I hope your boards arrive soon, checked today in the post and they told me is normal that there delays and between countries sometimes you cannot see the new tracking number when they switch international partners (does not sound real in 2022 but that’s what they told)

martinberlin commented 1 year ago

Happy that the board has arrived safe! Only from time to time, like 1 each 20 times, still the getVCOM() is delivering a unusually high number. It does not bother me much but still maybe needs just some ms more delay.

Other than that this is working correctly and IMHO if works with other panels like M5-epaper be merged in next release.

martinberlin commented 1 year ago

News: Cinread has acknowledged that there is a problem with this revision of their boards setting VCOM. They said there will be a new batch where setVCOM will release busy in 700ms. Will keep you updated if I can test it. I would say that now your component works very stable setting this and I only see the numbers read wrong from getVCOM once per 100 calls. It does not bother me at all and it's just because of this SPI timing issue.

martinberlin commented 1 year ago

Just wanted to update this with my Cinwrite board consumption so we can preview what it can be optimized to make battery last longer: Consumption IT8951 In average for the 5 seconds that takes from boot to update it consumes around 120 mA average. It would be great if we could update the initialization time @lovyan03 . But still it consumes too much, with the benefit of being faster than another ESP32 only projects as EPDiy. It seems the waveform and way to send the data of the IT8951 is indeed faster of what you can do with ESP32. Thanks a lot for implementing this VCOM setting, I hope it can be used in this board soon, but if not we have it at least for other boards. A pleasure to use your component for some projects would like to present in Catalunya, Spain.

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] commented 1 year ago

This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.