esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
411 stars 26 forks source link

Add support for Lilygo T5-4.7 inch e-paper module #1109

Open lbonherbe opened 3 years ago

lbonherbe commented 3 years ago

Describe the problem you have/What new integration you would like The Lyligo T5-4.7inch is a great e-paper module based on an ESP32. It has a resolution of 960*540, 16 gray level and support partial refresh. I would be great to have it integrated in ESPHome the same / similar way Waveshare e-paper screens and modules are.

Please describe your use case for this integration and alternatives you've tried: To date there is no support for this module in ESPHome. The only support given by the maker is through Arduino IDE

Additional context This is the maker's GitHub for this product: https://github.com/Xinyuan-LilyGO/LilyGo-EPD47

vbaksa commented 2 years ago

Do you have an idea what might be wrong here? I looked at namespaces and it just doesn't make sense to me. 😭

@ashald - it seems that something has changed on esphome or epdiy side. Didn't managed to find what has changed yet.

Cadair commented 2 years ago

@vbaksa thanks, I will give that a go. Is there a way to configure your component to do a full refresh every time?

Schnabulation commented 2 years ago

Good day everyone. I have a wierd issue that I can not solve by myself: The ePaper display works flawlessly on USB-power but when connecting a 18650 battery (with or without having USB connected) the display clears upon boot but stays blank. I have verified that the ESP is powered on: log is displayed in ESPhome and also the three buttons register in Home Assistant. Any ideas?

vbaksa commented 2 years ago

Do you have an idea what might be wrong here? I looked at namespaces and it just doesn't make sense to me. 😭

@ashald - it seems that something has changed on esphome or epdiy side. Didn't managed to find what has changed yet.

@ashald , @Plawasan - this should be fixed now

vbaksa commented 2 years ago

@vbaksa thanks, I will give that a go. Is there a way to configure your component to do a full refresh every time?

@Cadair - it's possible by calling id(screenid).clear(); function.

Something like below:

display:
  - platform: lilygo_t5_47_display
    id: mypaperscreen 
    lambda: |-
      id(mypaperscreen).clear();
      it.circle(450, 450, 50);
vbaksa commented 2 years ago

Good day everyone. I have a wierd issue that I can not solve by myself: The ePaper display works flawlessly on USB-power but when connecting a 18650 battery (with or without having USB connected) the display clears upon boot but stays blank. I have verified that the ESP is powered on: log is displayed in ESPhome and also the three buttons register in Home Assistant. Any ideas?

Would you mind sharing yaml?

Schnabulation commented 2 years ago

Would you mind sharing yaml?

I can do that, but I suspect it is a hardware issue as I just flashed an Arduino demo program (written and compiled in Visual Studio Code) and I have the same issue: draws the screen just fine on USB-power but on battery power the screen gets cleared but never re-drawn.

EDIT: Update: it seems that the battery did not make correct contact with the terminals passing only enough current to drive the ESP but not the display. After bending the terminals and ensuring the connection the display works flawlessly on battery power.

ashald commented 2 years ago

A little update on the fading after update - with changes @kaweksl mentions here https://github.com/vroland/epdiy/issues/136, I do not see any fading even without a sleep. Which is a good news for those of us who looks to make a battery powered setup based on LilyGo. The only caveat - interestingly enough - is that there is severe fading after I just unplug it from laptop after flashing (I would imagine it's not an issue if using OTA, but I have Wi-Fi disabled for power saving, and use BLE for data transmission). So I unplug the battery for few minutes, and then once I reconnect it later, it looks perfect and clear and no fading whatsoever.

I wish @vroland would incorporate @kaweksl's changes into the epdiy lib.

Schnabulation commented 2 years ago

with changes @kaweksl mentions here vroland/epdiy#136

Can I ask: Is this only a fix for the screen fading or does this also decrease the power usage of the device? I can run the display for around a week with deep sleep enabled and refreshes around every 5 minutes - which is already impressive. But it would be really great to have it running even longer.

ashald commented 2 years ago

@Schnabulation according to @kaweksl, it helps with power consumption as well. I only got my PPK2 today and plan to setup it in the evening, so should be able to see if I can reproduce his findings on my setup.

@Schnabulation speaking of power consumption, IDK what's your setup, but there is a lot at play. I'm actually aiming at setting up a battery-powered eInk device, which I can use to show arbitrary data around home, and which could last at least a month on a single charge while refreshing every minute. I just finished some significant optimizations yesterday and will share my configs later this week, once I measure power consumptions, but here is the summary of my observations so far:

  1. When ESP doesn't sleep, it consumes [relatively] a lot of energy
  2. The key to long battery life is to minimize runtime between sleeps
  3. Any unnecessary waiting wastes energy (that's to my post above on fighting waiting for 700ms, also waiting in the battery component)
  4. eInk refresh takes [relatively] long, but I was able to bring it down to ~850ms by forking @vbaksa's component, and also using a custom waveform provided by @martinberlin in https://github.com/vroland/epdiy/issues/146
  5. Wi-Fi consumes a lot of energy, and takes long time [to connect before it can transmit data] - I first switched to BLE client connection, and the to BLE advertisement

So far my journey was following:

  1. Wi-Fi based setup as described by @Plawasan - min 12s runtime, 20-30s on average (mostly Wi-Fi connection not working on 1st attempt, a delay before connecting to HomeAssistant API)
  2. BLE Server (wifwucite/esphome-ble-controller by @wifwucite) + Client (myhomeiot/esphome-components by @myhomeiot) based setup - min 4s runtime, 4-5s on average
  3. BLE Advertisement based setup - min 2.5s runtime, 3s on average

So where I'm going with all of this? @kaweksl's fix is so much valuable because it allows us to skip 700ms sleep before epd_deinit() and going to deep sleep. Yes, it's a huge difference if eInk consumes 100mAh or 200mAh for 700ms, but if it's just ~5ms (or whatever it takes to run deinit and drop into sleep), it's much less noticeable, and there are lots of other factors at play that make much bigger difference.

kaweksl commented 2 years ago

with changes @kaweksl mentions here vroland/epdiy#136

Can I ask: Is this only a fix for the screen fading or does this also decrease the power usage of the device? I can run the display for around a week with deep sleep enabled and refreshes around every 5 minutes - which is already impressive. But it would be really great to have it running even longer.

All depends how fast your esp32 goes to sleep after display initialization and drawing. Also in my opinion running on battery without fix may damage screen .

ashald commented 2 years ago

@Schnabulation, answering your question above:

Can I ask: Is this only a fix for the screen fading or does this also decrease the power usage of the device?

Now as I measured things with PPK2, I can confirm that it decreases power usage, indeed. That being said, if you immediately go into the deep sleep after screen update, then the power saving is less noticeable.

I've got Lilygo receiving data over BLE on wakeup, refreshing the screen, and going back to sleep. Here is the difference I see.

With the fix: cycle_with_power_fix Without the fix: cycle_without_power_fix

As you can see, the diff is only about 20 mC per cycle, which yields about 6% in my case

And for the background, there is a bit more detail about the energy leak. https://github.com/vroland/epdiy/issues/136#issuecomment-1032224682

Plawasan commented 2 years ago

I got my touchscreen, I'm working on cleaning up the yaml now but it works in principle, only a couple issues

It's not a showstopper for me as the use case I have for the touchscreen anyway requires it to be always on but it's still unfortunate..

Good news is that I got the whole "chain" working, i.e. ESPHome registers a touch in a given area, sends an event to HA, HA automation triggers and toggles a light and all that without any perceivable delay, for a zigbee light it's (almost..) as immediate as pushing a wall switch..

Proof of concept - https://youtu.be/r9HC_PaG8AA

Bad news is that the 3d printed cases that exist now for the display won't fit the touchscreen, it adds about 1mm of height and at least 2mm on each side.

martinberlin commented 2 years ago

@Plawasan I have a class for the L58 touch from Lilygo: https://github.com/martinberlin/FT6X36-IDF Albeit if you need to support "software rotation" you need to do that on your end. The class just limits itself to deliver the events and coordinates. I made a PR request to LVGL to add this as a driver but it won't ever be merged because of a License incompatibility.

ashald commented 2 years ago

@kaweksl I noticed a strange behavior on my Lilygo T5-4.7. The image is crisp and doesn't fade in general, except for one case. When I plug it via USB, it' and the disconnect - if it's powered by battery - or if I plug in battery immediately - there is a sever fading just seconds after epd_poweroff()/deinit(). But if I wait for about 5 mins after it was plugged via USB, and power if from battery - it works like a charm. Since you found an issue with energy consumption previously, and even came up with a workaround - do you have an idea what might be wrong here? Thanks!

kaweksl commented 2 years ago

@ashald I can't reproduce what you are describing, can you post your yaml ?

swissjon commented 2 years ago

@Cadair , I am having the same issues as you, did you figure something out? I tried id(screenid).clear(); but that ended up making the background a darker grey.

martinberlin commented 2 years ago

After many hours playing with the Lilygo EPD47 it also has this when disconnected from power. This does not happen with EPDiy based PCBs so sadly should be a hardware error in their side. There is nothing you can do about it if the power lines do this kind of effect. IMHO not solvable with software.

Itzamna44 commented 2 years ago

Hello. Strange battery level, is not it? Sensors are the same https://github.com/esphome/feature-requests/issues/1109#issuecomment-1003735817 And it keeps working now.

Lilygo

NeroWard commented 2 years ago

Привет. Странный уровень заряда батареи, не правда ли? Сенсоры те же https://github.com/esphome/feature-requests/issues/1109#issuecomment-1003735817 И теперь он продолжает работать.

How did you add Russian language support?

Cadair commented 2 years ago

@Cadair , I am having the same issues as you, did you figure something out? I tried id(screenid).clear(); but that ended up making the background a darker grey.

@swissjon I have been using tiaanv's component, it does a full refresh but I have no bleeding issues etc.

Plawasan commented 2 years ago

@Itzamna44 - it's completely arbitrary, there's a lower voltage limit in the % calculation set to 3.1 now, that's why you get a negative % when the voltage drops below that. I honestly have no idea what it should be set to or whether the board has any battery protection, I let it drop to 2.9 and then I figured I'd rather recharge it.. not sure how low it can go before it either stops powering up the ESP or the battery dies..

Btw I'm not sure if anything has changed but I've had the board running on battery for a week now and it hasn't even dropped below 4.05V.. curious how long it will actually last.

@NeroWard - just swap the font for one with Cyrillic characters.

Itzamna44 commented 2 years ago

How did you add Russian language support?

@NeroWard Just add Russian characters to glyphs:

swissjon commented 2 years ago

@swissjon I have been using tiaanv's component, it does a full refresh but I have no bleeding issues etc.

Thanks, I was using the vbaksa/esphome component, I/m giving tiaanv a try now.

mattmoo commented 2 years ago

Looks like touch screen support is in ESPHome 2022.2!!!

kaweksl commented 2 years ago

Underlying library, epdiy, has beed recently updated to address issue with increased power consumption. Some say it also helped with "bleeding".

@Cadair , @swissjon can you post your yaml and describe this bleeding i more detail. I'm trying to reproduce that issue and i can't . Did you tried to adjust VCOM ? https://github.com/esphome/feature-requests/issues/1109#issuecomment-1008307883

I also added PR to vbaksa/esphome that adds full refresh every n partial refresh.

Cadair commented 2 years ago

hey @kaweksl

I adjusted my VCOM up to ~1.1 V as high as it would go, it was down about 0.6 V when I started.

I tested vbaksa's component with and without the explicit clear command, and compared them to tiaanv's component. You can see the results here: https://imgur.com/a/c5XDVKR

vbaksa's component with the explicit call to clear, is good, but has very slightly more aliasing than tiaanv's. Without the clear the aliasing and bleeding is very prominent.

My config for vbaksa's without the clear is here: https://gist.github.com/Cadair/7db53154a8d353eb304bcc515a9273bb

Thanks to everyone for their work on this, please let me know if I can give you any more information to help out!

kaweksl commented 2 years ago

@Cadair tiaanv version is making full refresh every each update, something like vbaksa with a call to id(screenid).clear(); at the start of each lambda (with different waveform) . For You fading occurs on partial screen updates. i have tried yours yaml (not exact) and i don't have so extreme fading. This is not a fix for fading but until vbaksa merge my PR https://github.com/vbaksa/esphome/pull/9 you can try this

external_components:
  - source:
      type: git
      url: https://github.com/kaweksl/esphome
      ref: dev
    components: [lilygo_t5_47_display]

this adds full_update_every: x, by default is set to 10. 0 will disable it, setting to 1 will make it so each update will be full. example:

display:
  - platform: lilygo_t5_47_display
    id: mydisplay
    rotation: 180
    update_interval: never
    clear: false
    full_update_every: 1
    power_off_delay_enabled: false

With yours yaml i have found that on battery, screen background is becoming grey after epd_poweron/off cycle if there are no changes on screen. I have no idea why is that but as workaround i have added digital clock with seconds, so there is always something to change on screen, and background graying is not occurring anymore.

So lilygo_t5_47_battery may also cause background graying as it is performing poweron/off without screen update

ashald commented 2 years ago

@kaweksl in my experience it doesn't depend on the yaml - I was able to reproduce it with minimal example with EPDiy library directly. If I disconnect Lilygo from USB power while the battery is attached (or attach it within a minute or so), I'd see some ghosting appearing on previously blank areas of the screen. Once screen is updated, it will go away, but then come back in few seconds. It seems like it gets back to normal within couple of minutes. I can try capturing a video. I was just wondering if you think there might be some current leaking or what not at play, such that higher-voltage power supply via USB would skew the voltage in the system and there will be this glitch until it the voltage reduces back to normal. Not sure if this makes sense.

kaweksl commented 2 years ago

It seams like this happens when there is poweron/off cycle without any pixel being updated (and on battery). At least that way i can reproduce that. I gonna look more into that. For now make sure there is always something to refresh on screen (for example a clock), and don't use lilygo_t5_47_battery

kaweksl commented 2 years ago

@ashald , @Cadair , epdiy library has been updated and probably fixed that issue, try it now, make sure you have newest epdiy https://github.com/vroland/epdiy/pull/158

swissjon commented 2 years ago

@Cadair , @swissjon can you post your yaml and describe this bleeding i more detail. I'm trying to reproduce that issue and i can't . Did you tried to adjust VCOM ? #1109 (comment)

I had this:

external_components:
  - source:
      type: git
      url: https://github.com/vbaksa/esphome
      ref: dev
    components:
      - lilygo_t5_47_battery 
      - lilygo_t5_47_display

  - platform: lilygo_t5_47_display
    id: t5_display
    rotation: 180
    update_interval: 60s
    full_update_every: 5

60 sec refresh because I was still designing the lambda. I hadn't tried changing the VCOM yet. Today I just changed it to 1.19, it was at ~0.3 ish before I think. What would be the ideal value? I still have some of text that seems burnt into the screen. It might be fading slowly, time will tell.

ashald commented 2 years ago

I got inspired @Plawasan and all the work I saw in this thread and decided to build an info display based on Lilygo T5-4.7 which could run on battery for prolonged periods of time. This means optimizing for update speed and energy consumption, which is not aligned with the default mode of operation of EPDiy library's high-level API that @vbaksa's component uses.

With lots of help from @vroland and @martinberlin I hacked together https://github.com/ashald/platformio-epdiy-monochrome, which is a wrapper around EPDiy's low-level APIs. As I target performance, I sacrificed support for grayscale and focused on monochrome images, which resulted into significantly improved performance.

I've been running on it for few days by now and totally happy with it so far! If monochrome mode works for you - you can give it a try with:

external_components:
  - source: github://ashald/esphome@lilygo-t5-47
    components:
      - lilygo_t5_47

and configure it as:

display:
    platform: lilygo_t5_47
    full_update_every: 1 # 0 - never, 1 (default) - every, 2+ - throttled

And you can use other options from the base display component such as auto_clear_enabled (this wipes out the buffer but not the screen), update_interval etc.

I'm working on a dedicated component for the battery sensor, but for now I integrated the measurement function into the display so that it's easier to access it. The best way to use it as of now is like show below:

display:
    platform: lilygo_t5_47
    id: eink
    lambda: |-
        // Some constants for convenience
        #define BATTERY_MAX 4.2
        #define BATTERY_MIN 2.9

        // We know we will turn on the display soon to refresh it because we're already within its lambda
        // so we're just turning it on a bit earlier
        id(eink).power_on();

        // We need to let the ADC to stabilize for few ms - lets draw something in the meantime
        it.line(0, 0, 50, 50);

        // Now we're ready to read the battery
        double_t battery_voltage = id(eink).get_battery_voltage();
        double_t percentage = (1-(4.2-battery_voltage)/(4.2-2.9))*100;
        uint8_t battery_percentage = percentage < 0 ? 0 : percentage > 100 ? 100 : percentage;

        // And we can immediately print it
        id(eink).printf(..., "%.2fV %3d%%", battery_voltage, battery_percentage);

        // Now we can do something else if needed.
        // Once lambda completes, the display component will render the image and turn off the power.

The only issue that I observe - and I observed it with all versions that were shared here so far - when you disconnect a Lilygo from USB and connect to a battery within a minute or two (or if it's powered by a battery while disconnecting), there would be some fading on white areas after either power_off() or deinit() (need to double-check which one actually does it). I mentioned this to @kaweksl previously, and updating to the latest EPDiy didn't help either. I recorded a video demonstrating the issue. I disconnect it there around 15s, and you can see how imagine is clear before that, or how it gets back to normal couple minutes later. I reproduced it with a basic example as seen in https://github.com/ashald/platformio-epdiy-monochrome/tree/main/examples/basic, so that we can take out of the picture rest of the YAML and the battery component shared here previously - cc @kaweksl as you were asking for a reproduction.

kaweksl commented 2 years ago

@ashald With your component i always have grey background, looks like every secend line is grey https://imgur.com/a/f3bueyM

It is like that on battery or USB, with full_update_every: 1 or 10

EDIT: Sadly esphome is not very well suited for battery projects.

ashald commented 2 years ago

@kaweksl hm, that's really interesting - especially given that the lines are across the shorter dimension. Can you try full_update_every: 0 to see how it behaves on partial updates, or try id(eink).fill(COLOR_ON) to see if it could flush the entire screen black?

As far as I know, @martinberlin tried the code behind the component, and I didn't see such behavior on his board https://twitter.com/martinfasani/status/1494699220879687681, so I'm curious why your board behaves like that. Would be interesting to see if @Plawasan or somebody else tell whether they see the same issue. 🤔

EDIT: Sadly esphome is not very well suited for battery projects.

Would be curious to hear more details - in my experiments, I didn't see notable difference in terms of power consumption between my project when I compile it with Arduino or PlatformIO, or if I build it on top of ESPHome. If anything, it's ESP32s seem to be quite power hungry [compared to something like nrf52840], but that's a different story.

jesserockz commented 2 years ago

I sacrificed support for grayscale and focused on monochrome images

@ashald Maybe I missed something, but what is the difference?

ashald commented 2 years ago

@jesserockz I guess you're not referring to difference between black & white image versus 16 shades of grey, but rather in terms of how it works? I'm not super deep about eInk technology, but what I saw in EPDiy library is that grayscale images are rendered with the help of specific waveforms, and also depend on the temperature of the environment. At the same time, I found a piece of code in EPDiy which flushes the entire screen with a single color (black or white), and adjusted it so that it renders a bitmap buffer rather than a solid color.

The code that drives grayscale image rendering uses 4 bits per pixel, and then somehow uses waveforms to translate a particular shade into a set of pulses required to achieve desired color on the given pixel. This means that it requires more memory to store the buffer (and therefore needs SPIRAM). With monochrome mode I pack 8 pixels per byte so it fits into SRAM, which seem to be faster, and plus we don't incur extra ~800ms at startup for SPIRAM memtest which couldn't be disabled (until this option was added last month in Arduino and is not widely available yet).

Unfortunately, I lack domain knowledge required to go into more detail about how grayscale rendering works based on waveforms.

jesserockz commented 2 years ago

@ashald Ah, so by monochrome, you actually mean black & white. "Monochrome" can still have grey in between, so in the case of ESPHome displays, I believe that "monochrome" is the same as "greyscale"

ashald commented 2 years ago

@jesserockz ah, I see, sorry for confusion - I guess I need to learn relevant terminology. 😅 Will be sticking with black&white going forward to avoid confusion.

Schnabulation commented 2 years ago

@ashald I have just converted from vbaksa to your component - and since then I also have these lines that @kaweksl is refering to. Looking exactly the same as in the picture he posted.

I have tried with full_update_every: 0 and 1, no change.

Have to say though: the refreshing process is fast as f*** boiii...

martinberlin commented 2 years ago

I tried this and at least in my Lilygo I cannot see the gray lines. Or they are so subtle that they do not make any difference for me. But I can't also see it in the imgur posted image, maybe a good photo with a magnifying glass can show something more.

Schnabulation commented 2 years ago

Open the imgur page again and scroll down to the second and third picture - I actually uploaded a picture with a magnifying glass.

If you take a close look you will see that every other line is darker. But if you step back you won't see it, that's true.

martinberlin commented 2 years ago

Ah now I see, though was only one image! I can confirm this does not happen to me with the standalone epdiy balck&white version that @ashald did. I even went further and added GFX functions to test it in this repository. Never used ESP-Home though, so maybe there are some timings affected, or there is a problem in the way the component is receiving the pixels. You might also try my demo and see for yourself if you get also this lines, but I don't see them at all.

Schnabulation commented 2 years ago

Ah so if I understand you correctly: Using @ashalds library standalone (not through ESPHome but programmed from scratch) you don't get the lines. Interesting... Then it has to be something in ESPHome...

Cadair commented 2 years ago

make sure you have newest epdiy

@kaweksl How do I do this, is it automatically pulled in with the custom component or do I have to reconfigure something?

kaweksl commented 2 years ago

@Cadair simplest method is to delete ".esphome" folder from where you have esphome configuration yaml . at least on linux

Cadair commented 2 years ago

@kaweksl Thanks, I have done that, and on a non-full refresh am still getting significant fading on partial refresh :(

tdroza commented 2 years ago

@ashald I'm also seeing the alternating line shading with your component (see here), so I'll stick with the @vbaksa version for now. Screen updates were super-fast though!

ashald commented 2 years ago

@tdroza @kaweksl @Schnabulation could you try this PlatformIO example to see if it'll give you the same result? https://github.com/ashald/platformio-epdiy-monochrome/tree/main/examples/basic

If you need, I can provide more detailed instructions for your operating system, or the binary file you could flash with ESP esphome-flasher.

Also, could you share the section of your YAMLs where you configure the display? I don't need to see your lambdas if that of any concern, but only the settings you set on the display component.

If there is something wrong with my code, I'd love to fix it so it can be used by more people, but that's hard to do unless I can reproduce it. So I'm trying to narrow down source of the issue.

The only thing I have in mind so far is that there could be something wrong with the memory (huh), so whenever I have a moment, I will add an option to the component to prefer dynamic memory allocation, or PSRAM so we can see if that will make any difference.

kaweksl commented 2 years ago

https://github.com/ashald/platformio-epdiy-monochrome/tree/main/examples/basic looks good on my display.

my config: https://github.com/kaweksl/esphome-configs/blob/master/eh-lilygot5-1.yaml + https://github.com/kaweksl/esphome-configs/blob/master/display.yaml