caemor / epd-waveshare

Drivers for various EPDs from Waveshare
ISC License
215 stars 131 forks source link

4.2": Quick refresh and background color #47

Open mgottschlag opened 4 years ago

mgottschlag commented 4 years ago

I have experimented with the 4.2 inch e-ink display from waveshare, and the last days I have tried to make quick refresh work. I have observed a number of deficiencies in this library, some of which I do not know how to fix:

mgottschlag commented 4 years ago

Oh, and initial testing indicates that those LUTs work for the 3-color display as well (when the display is initialized in two-color mode). Maybe the documentation should state something like that as well. I, at least, did not expect that.

caemor commented 4 years ago

Newer 4.2" B/W displays seem to require different LUTs for quick refresh.

Are they also v2 ones, since they also updated the epd7in5 to v2 for example? The current LUTs are for the slow ones from the waveshare repo and the fast ones directly from Ben Krasnows code.

It also seems to look like they have added support for 2-Bit Grey colors in their repo now: https://github.com/waveshare/e-Paper/blob/853a3a4632fcb64a215e5335700f512b692bee91/Arduino/epd4in2/epd4in2.cpp#L71 (White G1 G2 Black). So they most likely have a newer and better version of these displays.

Link to the example code: http://www.e-paper-display.com/download_detail/downloadsId=1022.html

I need to look into this further when I have more time but since good display is making all the einks for waveshare this look good at a first glance.

I am unsure what the point of the "background color" provided by this library is - the documentation is lacking and I think usage the background color as-is is wrong and unusable.

Being able to change it should be possible yes. At least I can't remember any good reason why I added it. Yes I can agree with you here. I think being able to change it shouldn't be possible. So removing set-background should be a good way going forward. See the 3rd point for more about why I am using this for the refresh.

For your current problem: You could modify the update_frame and have a 2nd buffer and replace the line here https://github.com/caemor/epd-waveshare/blob/22f16eaa050abe518db9683548c82adbd3e266a8/src/epd4in2/mod.rs#L216 with .cmd_with_data(...) so it ends in something like this:

fn update_frame_old(&mut self, spi: &mut SPI, buffer: &[u8], buffer_old: &[u8]) -> Result<(), SPI::Error> {
        self.wait_until_idle();
        let color_value = self.color.get_byte_value();

        self.send_resolution(spi)?;

        self.interface
            .cmd_with_data(spi, Command::VCM_DC_SETTING, &[0x12])?;

        //VBDF 17|D7 VBDW 97  VBDB 57  VBDF F7  VBDW 77  VBDB 37  VBDR B7
        self.interface
            .cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x97])?;

        self.interface
            .cmd_with_data(spi, Command::DATA_START_TRANSMISSION_1, buffer_old)?;

        self.interface
            .cmd_with_data(spi, Command::DATA_START_TRANSMISSION_2, buffer)?;
        Ok(())
    }

If this is improving the situation and you get real stable faster luts we can include this for everyone

The library does not provide a method to upload the "old" ("background") data.

The official quick refresh LUTs for this display depend on having the old data. For this part I looked at the official recommendation/code by waveshare which does the same (just putting background color there): https://github.com/waveshare/e-Paper/blob/853a3a4632fcb64a215e5335700f512b692bee91/Arduino/epd4in2/epd4in2.cpp#L358

David-OConnor commented 4 years ago

Are there any tricks on the 4.2" using an STM32F3? Getting no signs of life from the display, and the program crashing once I hit the let mut display = Display4in2::default(); line.

caemor commented 4 years ago

Are there any tricks on the 4.2" using an STM32F3? Getting no signs of life from the display, and the program crashing once I hit the let mut display = Display4in2::default(); line.

Then you most likely don't have enough ram left over. It needs 15kB for the full default display buffer and the Display4in2::default() doesn't do much besides making a 15kB framebuffer. You could look into the examples/epd4in2_variable_size.rs example which is using a smaller buffer to update only little parts of the display.

You could also check how much ram you have left and try to reduce your usage elsewhere.

mgottschlag commented 4 years ago

Are they also v2 ones, since they also updated the epd7in5 to v2 for example? The current LUTs are for the slow ones from the waveshare repo and the fast ones directly from Ben Krasnows code.

I think this is a newer version of the display, yes. It seems ugly to me to completely duplicate the code for such a small change, though, as done for the 7.5in display.

For your current problem: You could modify the update_frame and have a 2nd buffer and replace the line here

https://github.com/caemor/epd-waveshare/blob/22f16eaa050abe518db9683548c82adbd3e266a8/src/epd4in2/mod.rs#L216 with .cmd_with_data(...) so it ends in something like this:

[...]

If this is improving the situation and you get real stable faster luts we can include this for everyone

I have done something similar in https://github.com/mgottschlag/epd-waveshare/commit/dbd065a71595b62147b5a4af8846f1ce1af6e191 and it indeed fixes quick refresh. I will rewrite my code to make use of partial refresh instead of my hacked "streaming interface" as soon as I have time, and then I can write a PR for that.

David-OConnor commented 4 years ago

Are there any tricks on the 4.2" using an STM32F3? Getting no signs of life from the display, and the program crashing once I hit the let mut display = Display4in2::default(); line.

Then you most likely don't have enough ram left over. It needs 15kB for the full default display buffer and the Display4in2::default() doesn't do much besides making a 15kB framebuffer. You could look into the examples/epd4in2_variable_size.rs example which is using a smaller buffer to update only little parts of the display.

You could also check how much ram you have left and try to reduce your usage elsewhere.

Thank you. It also looks like this command: let mut epd = EPD4in2::new(&mut spi, cs_disp, busy, dc, rst, &mut delay).expect("eink initalize error"); is crashing it as well. I think I need to figure out how to set up panics to see what's going on.

David-OConnor commented 4 years ago

edit: Given that you mentioned they updated the examples to v2, and I can get the arduino example to work on V1 but not V2, maybe I need to see what V1 looks look.

mgottschlag commented 4 years ago

From my experience, the "original" version of this crate (without my modifications) worked well with this display except for quick refresh. I did also have the issues with RAM size, though.

Given that the display protocol is write-only, errors during initialization should be limited to errors from your SPI/GPIO HAL implementation.

caemor commented 4 years ago

@David-OConnor, I made a seperate issue for the stm32f3 problem, so that this issue can stay focused around quick refreshs.

caemor commented 3 years ago

@mgottschlag Have you tested your LUTs over a longer time now? Did you have any problems with them? and you only tested these on the newer 4-color variant (B, g1, g2, w)?

mgottschlag commented 3 years ago

Sorry, the project got stalled for time reasons, so I did not do any intensive testing. I only tested on the 4-color variant.

caemor commented 3 years ago

@mgottschlag & @David-OConnor I opened a new PR to combine everything that is still left over. It would be great if you could take a quick glance at what is still missing there.

Thanks in advance