joukos / PaperTTY

PaperTTY - Python module to render a TTY or VNC on e-ink
946 stars 101 forks source link

waveshare 2.13b (blk/wht/red) displays nothing but mostly red garbage. #56

Open wolfspyre opened 4 years ago

wolfspyre commented 4 years ago

Hi there!

firstly thanks for all the awesome work on this. I'm super excited to play with it.

It seems the 2.13b is different enough that the standardization of the driver seems to have sorta rendered it unfunctional.

I'll play around with it and see if I can't get something working, but figured I'd open an issue first before digging in.

joukos commented 4 years ago

Hi,

Thanks for the info - I don't think I've heard anyone try the tricolor variety of this yet (I haven't had time to try my 2.9" tricolor one yet) so whether it works or not is pretty much a gamble. Does your display work with the reference Python code from Waveshare?

wolfspyre commented 4 years ago

yep! reference code works. I stripped reference files down to just the pieces needed to run the 2.13bc waveshare demo code:

minimal_reference_code/
├── lib
│   └── waveshare_epd
│       ├── __init__.py
│       ├── epd2in13bc.py
│       └── epdconfig.py
├── pic
│   ├── 100x100.bmp
│   ├── 2in13bc-b.bmp
│   ├── 2in13bc-ry.bmp
│   └── Font.ttc
└── test
    └── epd_2in13bc_test.py

Currently, I'm testing on ubuntu 20.04 64bit on a pi4, but arguably that shouldn't matter..

Running from the same venv, the reference code behaves as expected..

attaching the above files as a targz in case it's helpful at all. I'll continue to dork around with it and see if I can make any progress minimal_reference_code.tar.gz

joukos commented 4 years ago

Well, quickly looking at the display method, it seems to me that it's missing the PARTIAL_OUT (0x92) command entirely after writing the buffers (note: current code actually ignores the red data completely anyway).

Waveshare's example has this (lines 123-135 in epd2in13bc.py):

    def display(self, imageblack, imagered):
        self.send_command(0x10)
        for i in range(0, int(self.width * self.height / 8)):
            self.send_data(imageblack[i])
        self.send_command(0x92)

        self.send_command(0x13)
        for i in range(0, int(self.width * self.height / 8)):
            self.send_data(imagered[i])
        self.send_command(0x92)

        self.send_command(0x12) # REFRESH
        self.ReadBusy()

And PaperTTY has this (https://github.com/joukos/PaperTTY/blob/master/drivers/drivers_colordraw.py#L79-L96):

    # this variant is for EPD1in54c, EPD2in13b and EPD2in9b - EPD1in54b and EPD2in7b override it
    def display_frame(self, frame_buffer_black, *args):
        frame_buffer_red = args[0] if args else None
        if frame_buffer_black:
            self.send_command(self.DATA_START_TRANSMISSION_1)
            self.delay_ms(2)
            for i in range(0, int(self.width * self.height / 8)):
                self.send_data(frame_buffer_black[i])
            self.delay_ms(2)
        if frame_buffer_red:
            self.send_command(self.DATA_START_TRANSMISSION_2)
            self.delay_ms(2)
            for i in range(0, int(self.width * self.height / 8)):
                self.send_data(frame_buffer_red[i])
            self.delay_ms(2)

        self.send_command(self.DISPLAY_REFRESH)
        self.wait_until_idle()

Note that currently in the above method, the frame_buffer_red will always be None because it's ignored in WaveshareColor class's draw method - currently there's no implementation to use it.

The difference here seems to be that after the data is sent, the command 0x92 should (probably) be sent too, so maybe try to replace the display_frame method in drivers_colordraw.py (lines 79-96) with this:

    # this variant is for EPD1in54c, EPD2in13b and EPD2in9b - EPD1in54b and EPD2in7b override it
    def display_frame(self, frame_buffer_black, *args):
        frame_buffer_red = args[0] if args else None
        if frame_buffer_black:
            self.send_command(self.DATA_START_TRANSMISSION_1)
            self.delay_ms(2)
            for i in range(0, int(self.width * self.height / 8)):
                self.send_data(frame_buffer_black[i])
            self.send_command(self.PARTIAL_OUT)
            self.delay_ms(2)
        if frame_buffer_red:
            self.send_command(self.DATA_START_TRANSMISSION_2)
            self.delay_ms(2)
            for i in range(0, int(self.width * self.height / 8)):
                self.send_data(frame_buffer_red[i])
            self.delay_ms(2)
            self.send_command(self.PARTIAL_OUT)

        self.send_command(self.DISPLAY_REFRESH)
        self.wait_until_idle()

It's very likely that's not the only problem, but maybe worth a try to see if it makes a difference.

wolfspyre commented 4 years ago

didn't make much of a difference yet. I'll keep tinkering on my branch

joukos commented 4 years ago

Okay, good luck, please make a PR if you get it working :) Maybe I'll have time to try the 2.9" too at some point (and figure out what options there should be for using the colors).

wolfspyre commented 4 years ago

okay. Found out that using the D driver seems to work if I use the --nopartial flag. that's at least progress for the moment, and points me in a direction

wolfspyre commented 4 years ago

oh interesting:

(papertty) pi@ubuntu:~/PaperTTY$ ./papertty.py --nopartial --driver EPD2in13b scrub
Loading PIL font tom-thumb.pil. Font size is ignored.
Traceback (most recent call last):
  File "./papertty.py", line 794, in <module>
    cli()
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context().obj, *args, **kwargs)
  File "./papertty.py", line 514, in scrub
    ptty.driver.scrub(fillsize=size)
  File "/home/pi/PaperTTY/drivers/drivers_base.py", line 60, in scrub
    self.fill(self.black, fillsize=fillsize)
  File "/home/pi/PaperTTY/drivers/drivers_base.py", line 67, in fill
    self.draw(x, 0, image)
  File "/home/pi/PaperTTY/drivers/drivers_color.py", line 41, in draw
    self.display_frame(self.get_frame_buffer(image))
  File "/home/pi/PaperTTY/drivers/drivers_colordraw.py", line 485, in get_frame_buffer
    super().get_frame_buffer(image, reverse=reverse)
  File "/home/pi/PaperTTY/drivers/drivers_full.py", line 75, in get_frame_buffer
    raise ValueError('Image must be same dimensions as display: required ({0}x{1}), got ({2}x{3})'
ValueError: Image must be same dimensions as display: required (104x212), got (16x212)

and

(papertty) pi@ubuntu:~/PaperTTY$ ./papertty.py --nopartial --driver EPD2in13d scrub
Loading PIL font tom-thumb.pil. Font size is ignored.
Traceback (most recent call last):
  File "./papertty.py", line 794, in <module>
    cli()
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/pi/.virtualenvs/papertty/lib/python3.8/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context().obj, *args, **kwargs)
  File "./papertty.py", line 514, in scrub
    ptty.driver.scrub(fillsize=size)
  File "/home/pi/PaperTTY/drivers/drivers_base.py", line 60, in scrub
    self.fill(self.black, fillsize=fillsize)
  File "/home/pi/PaperTTY/drivers/drivers_base.py", line 67, in fill
    self.draw(x, 0, image)
  File "/home/pi/PaperTTY/drivers/drivers_partial.py", line 597, in draw
    self.display_full(self.get_frame_buffer(image))
  File "/home/pi/PaperTTY/drivers/drivers_partial.py", line 112, in get_frame_buffer
    raise ValueError('Image must be same dimensions as display \
ValueError: Image must be same dimensions as display                 (104x212).
(papertty) pi@ubuntu:~/PaperTTY$
joukos commented 4 years ago

The reason it crashes is perhaps related to the orientation (maybe), the pull request opened a while ago has some thoughts about it: https://github.com/joukos/PaperTTY/pull/52.

16x212 does sound pretty wrong though...