Giter VIP home page Giter VIP logo

omni-epd's Introduction

Omni-EPD

Python Version from PEP 621 TOML build-status standard-readme compliant

An EPD (electronic paper display) class abstraction to simplify communications across multiple display types.

There are several great EPD projects all over the internet, many in written in Python. The problem with a lot of these is that the code is often for one specific type of display, or perhaps a family of displays. This project abstracts the EPD communications into a common interface so a variety of displays can be interchangeably used in the same project. It also adds a lot of helpful conveniences such as the ability to automatically rotate, add contrast, or dither images on their way to the display. This gives more control to end users without having to add extra features in your upstream project.

For EPD project builders this expands the number of displays you can use for your project without having to code around each one. To utilize this in your project read the usage instructions. For a list of (known) projects that use this abstraction see the list below.

Table Of Contents

Install

Installing this module installs any required Python library files. Refer to instructions for your specific display for any additional requirements that may need to be satisfied. A common requirement is enabling SPI support on a Raspberry Pi. Install any required libraries or setup files and then run:


pip3 install git+https://github.com/robweber/omni-epd.git#egg=omni-epd

This will install the abstraction library. The test utility can be used to test your display and ensure everything is working properly. You can also clone this repo and install from source with:


git clone https://github.com/robweber/omni-epd.git
cd omni-epd
pip3 install --prefer-binary .

Python Virtual Environments

It is best practice to install inside a virtual environment. For implementing projects you may experience errors installing outside of a virtual environment.

The numpy package, required by Pillow, needs access to the system installed version of numpy in order to work properly. When setting up your virtual environment be sure to pass in the --system-site-packages argument to enable using system packages if they're available. An example would be:

# create the environment
python3 -m venv --system-site-packages .venv

# activate the environment
source .venv/bin/activate

# deactivate the environment
deactivate

Usage

Usage in this case refers to EPD project implementers that wish to abstract their code with this library. In general, this is pretty simple. This library is meant to be very close to a 1:1 replacement for existing EPD code you may have in your project. Function names may vary slightly but most calls are very similar. Refer to the examples folder for some working code examples you can run. In general, once the VirtualEPD object is loaded it can interact with your display using the methods described below. For testing, the device omni_epd.mock can be used to write output to a PNG file instead of to a display.

VirtualEPD Object

Objects returned by the displayfactory class all inherit methods from the VirtualEPD class. The following methods are available to be implemented once the object is loaded. Be aware that not all displays may implement all methods but display is required.

  • width and height - these are convenience attributes to get the width and height of the display in your code.
  • prepare() - does any initializing information on the display. This is waking up from sleep or doing anything else prior to a new image being drawn.
  • display(image) - draws an image on the display. The image must be a Pillow Image object.
  • sleep() - puts the display into sleep mode, if available for that device. Generally this is lower power consumption and maintains longer life of the display.
  • clear() - clears the display
  • close() - performs any cleanup operations and closes access to the display. Use at the end of a program or when the object is no longer needed.

If the display you're using supports any advanced features, like multiple colors, these can be handled by setting some additional variables. See advanced display control for a better idea of how to additional options.

  • modes_available - a tuple containing the names of valid modes, BW available by default
  • max_colors - The maximum number of colors supported (up to 256 RGB)
  • palette_filter - a tuple of RGB values for valid colors an Image can send to the display

Display Testing

There is a utility, omni-epd-test to verify the display. This is useful to provide users with a way to test that their hardware is working properly. Many displays have specific library requirements that need to be installed with OS level package utilities and may throw errors until they are resolved. The test utility helps confirm all requirements are met before doing more advanced work with the display. This can be run from the command line, specifying the device from the table below.

# this will draw a series of rectangles
user@server:~ $ omni-epd-test -e omni_epd.mock

# this will draw the specified image
user@server:~ $ omni-epd-test -e omni_epd.mock -i /path/to/image.jpg

# print a list of all valid EPD options
user@server:~ $ omni-epd-test --list

Advanced EPD Control

There are scenarios where additional post-processing needs to be done for a particular project, or a particular display. An example of this might be to rotate the display 180 degrees to account for how the physical hardware is mounted. Another might be always adjusting the image with brightness or contrast settings. These are modifications that are specific to display requirements or user preferences and can be applied by use of a .ini file instead of having to modify code or allow for options via implementing scripts.

Two types of ini files can be used in these situations. A global file, named omni-epd.ini, or a device specific file; which is the device name from the table below with a .ini suffix. These must exist in the root directory where the calling script is run. This is the directory given by the os.getcwd() method call. Valid options for this file are listed below. These will be applied on top of any processing done to the passed in image object. For example, if the implementing script is already modifying the image object to rotate 90 degrees, adding a rotate command will rotate an additional X degrees. For precedence device specific configurations trump any global configurations. Some displays also have options specific to them only. Consult with that list if these additional options are needed in your situation.

# file shown with default values
[EPD]
type=none  # only valid in the global configuration file, will load this display if none given to displayfactor.load_display_driver()
mode=bw  # the mode of the display, typically b+w by default. See list of supported modes for each display below

[Display]
rotate=0  # rotate final image written to display by X degrees [0-360]
flip_horizontal=False  # flip image horizontally
flip_vertical=False  # flip image vertically
dither=FloydSteinberg  # apply a dithering algorithm to the image

[Image Enhancements]
palette_filter=[[R,G,B], [R,G,B]]  # for multi color displays the palette filter used to determine colors passed to the display, must be less than or equal to max colors the display supports
contrast=1  # adjust image contrast, 1 = no adjustment
brightness=1  # adjust image brightness, 1 = no adjustment
sharpness=1  # adjust image sharpness, 1 = no adjustment

Palette Filtering

The palette_filter option controls what colors are passed to multi color displays by filtering the image so only the listed colors remain. The total number of colors must be less than or equal to the max number of colors the display supports. Colors can be specified as an array of RGB values ([[R,G,B], [R,G,B]]), hexidecimal values (#ff0000, #00ff00), or color names (blue, maroon). Combinations of these can also be given as long as each color specified is separated by a comma.

Dithering

When using the dither option many algorithms are available. Please read the full instructions for dithering and how it can be used.

Displays Implemented

Below is a list of displays currently implemented in the library. The Omni Device Name is what you'd pass to displaymanager.load_display_driver(deviceName) to load the correct device driver. Generally this is the packagename.devicename Devices in bold have been tested on actual hardware while others have been implemented but not verified. This often happens when multiple displays use the same libraries but no physical verification has happened for all models. The color modes are available modes that can be set on the device.

Device Library Device Name Omni Device Name Color Modes
Inky Inky AutoDetect (try this first) inky.auto bw, yellow, red, color
Inky Impression 7 Color inky.impression bw, color
Inky pHAT Red/Black/White - 212x104 inky.phat_red bw, red
Inky pHAT Yellow/Black/White - 212x104 inky.phat_yellow bw, yellow
Inky pHAT Black/White - 212x104 inky.phat_black bw
Inky pHAT Red/Black/White - 250x122 inky.phat1608_red bw, red
Inky pHAT Yellow/Black/White - 250x122 inky.phat1608_yellow bw, yellow
Inky pHAT Black/White - 250x122 inky.phat1608_black bw
Inky wHAT Red/Black/White inky.what_red bw, red
Inky wHAT Yellow/Black/White inky.what_yellow bw, yellow
Inky wHAT Black/White inky.what_black bw
Omni-EPD Mock Display (emulates EPD with no hardware) omni_epd.mock bw, color, palette
Waveshare 1.02inch E-Ink display module waveshare_epd.epd1in02 bw
1.54inch E-Ink display module waveshare_epd.epd1in54
waveshare_epd.epd1in54_V2
bw
1.54inch e-Paper Module B waveshare_epd.epd1in54b
waveshare_epd.epd1in54b_V2
bw, red
1.54inch e-Paper Module C waveshare_epd.epd1in54c bw, yellow
1.64inch e-Paper Module G waveshare_epd.epd1in64g bw, red, yellow, 4color
2.13inch e-Paper HAT waveshare_epd.epd2in13
waveshare_epd.epd2in13_V2
waveshare_epd.epd2in13_V3
bw
2.13inch e-Paper HAT B waveshare_epd.epd2in13b
waveshare_epd.epd2in13b_V3
bw, red
2.13inch e-Paper HAT C waveshare_epd.epd2in13c bw, yellow
2.13inch e-Paper HAT D waveshare_epd.epd2in13d bw
2.36inch e-Paper Module G waveshare_epd.epd2in36g bw, red, yellow, 4color
2.66inch e-Paper Module waveshare_epd.epd2in66 bw
2.66inch e-Paper Module B waveshare_epd.epd2in66b bw, red
2.7inch e-Paper HAT waveshare_epd.epd2in7 bw
2.7inch e-Paper HAT B waveshare_epd.epd2in7b
waveshare_epd.epd2in7b_V2
bw, red
2.9inch e-Paper Module waveshare_epd.epd2in9
waveshare_epd.epd2in9_V2
bw
2.9inch e-Paper Module B waveshare_epd.epd2in9b
waveshare_epd.epd2in9b_V3
bw, red
2.9inch e-Paper Module C waveshare_epd.epd2in9c bw, yellow
2.9inch e-Paper HAT D waveshare_epd.epd2in9d bw
3inch e-Paper Module G waveshare_epd.epd3in0g bw, red, yellow, 4color
3.7inch e-Paper HAT waveshare_epd.epd3in7 gray4
4.01inch 7 color e-Paper HAT waveshare_epd.epd4in01f bw, color
4.2inch e-Paper Module waveshare_epd.epd4in2 bw
4.2inch e-Paper Module B waveshare_epd.epd4in2b
waveshare_epd.epd4in2b_V2
bw, red
4.2inch e-Paper Module C waveshare_epd.epd4in2c bw, yellow
4.37inch e-Paper Module G waveshare_epd.epd4in37g bw, red, yellow, 4color
5.65inch e-Paper Module F waveshare_epd.epd5in65f bw, color
5.83inch e-Paper HAT waveshare_epd.epd5in83
waveshare_epd.epd5in83_V2
bw
5.83inch e-Paper HAT B waveshare_epd.epd5in83b
waveshare_epd.epd5in83b_V2
bw, red
5.83inch e-Paper HAT C waveshare_epd.epd5in83c bw, yellow
6inch e-Ink Display waveshare_epd.it8951 bw, gray16
7.3inch e-Paper HAT G waveshare_epd.epd7in3g bw, red, yellow, 4color
7.3inch e-Paper HAT F waveshare_epd.epd7in3f bw, color
7.5inch e-Paper HAT waveshare_epd.epd7in5 bw
7.5inch e-Paper HAT V2 waveshare_epd.epd7in5_V2 bw
7.5inch HD e-Paper HAT waveshare_epd.epd7in5_HD bw
7.5inch HD e-Paper HAT B waveshare_epd.epd7in5b_HD bw, red
7.5inch e-Paper HAT B waveshare_epd.epd7in5b bw, red
7.5inch e-Paper HAT B V2 waveshare_epd.epd7in5b_V2 bw, red
7.5inch e-Paper HAT C waveshare_epd.epd7in5c bw, yellow
7.8inch e-Ink Display waveshare_epd.it8951 bw, gray16
9.7inch e-Ink Display waveshare_epd.it8951 bw, gray16
10.3inch e-Ink Display waveshare_epd.it8951 bw, gray16

Display Driver Installation

Each display type has different install requirements depending on the platform. While loading this module will install any required Python libraries for supported displays; specific OS level configuration may need to be done. Basic instructions are below for each library type. Refer to instructions for your specific display to make sure you've satisfied these requirements. The omni-epd-test utility can be used to verify things are working properly.

Inky

Inky makes things pretty easy with a one-line installer. This makes the necessary OS level changes and pulls in the Inky library. Using the inky.auto device type uses Inky library's auto detect method and is the most surefire way of loading the proper driver.

curl https://get.pimoroni.com/inky | bash

If installing Inky manually be sure that SPI and I2C are enabled via sudo raspi-config.

Waveshare

The Waveshare device library requires that SPI support be enabled on your system prior to use. The waveshare-epd module is automatically downloaded and installed as a dependency of this module.

Please note: The version of the Waveshare repo used by this library is a fork of the official repository. This is due to the official repo not having correct detection support for Raspberry Pi OS 12 (Bookworm). Once the official repo is updated the source for the Waveshare drivers will be moved back to the official repo.

IT8951

IT8951 devices, such as the Waveshare 6in EPD, are supported via a separately maintained Python module from Greg Kahanamoku-Meyer. This module and it's requirements are downloaded as part of omni-epd setup.

Implementing Projects

Below is a list of known projects currently utilizing omni-epd. If you're interested in building a very small media player, check them out.

  • SlowMovie - A very popular VSMP player with lots of options for playing files and an easy install process.
  • VSMP+ - My own VSMP project with a built in web server for easy administration.
  • pycasso - System to send AI generated art to an E-Paper display through a Raspberry PI unit.
  • PiArtFrame - EPD project that displays randomly generated fractal art.

Acknowledgements

Dithering support provided by the didder Tool - https://github.com/makeworld-the-better-one/didder

Contributing

PRs accepted! If there a fix for any of the documentation or something is not quite clear, please point it out. If you test one of the listed displays, please mark it as verified by bolding it in the Displays Implemented section. If you want to extend this framework by adding a new display type; a good place to start is one of the existing display classes for an example. Installing the library in development mode will also make live testing easier. This will allow you test your changes quickly without re-installation.


pip3 install -e .[dev] --prefer-binary

Contributors

License

GPLv3

omni-epd's People

Contributors

aaronr8684 avatar donbing avatar dr-boehmerie avatar evelyndooley avatar missionfloyd avatar qubist avatar robweber avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

omni-epd's Issues

Review epd1in54c

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd1in54c.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_1in54c_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in13d

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in13d.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in13d_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

More Complex Examples

Update the examples for more complicated use cases. Primary ones would be:

  1. Setting individual display to either b/w or color
  2. Passing device specific args (requires #9)
  3. Setting a custom color palette

Mock Display Palette with Dithering

This doesn't impact usability in a meaningful way but it is a shortcoming. When using the omni_epd.mock display in color mode the value of the palette_filter attribute returns the colors for black and white but no other colors.

The main effect this has is if you also try and apply a dither effect to the image when using the mock display. The dithering process expects this attribute to exist and have correct values. When testing this on a color image, applying a dither always results in a black and white image as that is the returned palette.

Since the mock display is really more of a testing tool it isn't a meaningful usability issue but will not yield correct results in it's current form.

Issues with a fix

A simple fix for this wasn't evident at first glance. The dithering code is triggered when display() is called within the parent VirtualEPD class prior to the display implementation method _display() being called. As a result the effect is already applied before the specific device class has access to the Image. Because this is a parent class function it's not easy to code around this by simply importing the palette of the Image object. There are other displays that use color as their mode that do set a proper palette correctly from the device driver.

Workarounds

Not really a workaround but if no fix can be found I think it would be ok to simply document this as a shortcoming and leave it as is. It's not really a show stopper as it doesn't effect actual devices.

Add Partial Update Support

If I have time, I can work on a solution, but in the meantime, I'm just going to add this here as a future feature request. Not sure if MissionFloyd wants to take a crack at it. I imagine that it could be another mode since only the bw/grey screens seem to support it.

Screens with official partial update support:

  • 1.02
  • 1.54
  • 2.13
  • 2.66
  • 2.9
  • 3.7
  • All IT8951 based HD screens

Issue with 3.7 in Waveshare

From @ZubaZ21

I love the idea of abstracting this. Very cool.

Pulled it down and ran the test util.
It threw an error.
File
"/usr/local/lib/python3.7/dist-packages/omni_epd/displays/waveshare_display.py",
line 251, in prepare
self._device.init()
TypeError: init() missing 1 required positional argument: 'mode'

I added a 0 so it became self._device.init(0) as that is what the waveshare
driver requested.

Fired it off again and got the following.

pi@GeneralPie:~ $ omni-epd-test -e waveshare_epd.epd3in7

Loaded waveshare_epd.epd3in7 with width 280 and height 480
Drawing rectangle of width 210.0 and height 360.0
Drawing rectangle of width 105.0 and height 180.0
Drawing rectangle of width 26.25 and height 45.0
Traceback (most recent call last):
File "/usr/local/bin/omni-epd-test", line 10, in
sys.exit(main())
File "/usr/local/lib/python3.7/dist-packages/omni_epd/test_utility.py",
line 127, in main
test.draw()
File "/usr/local/lib/python3.7/dist-packages/omni_epd/test_utility.py",
line 85, in draw
self.__draw_on_display(im)
File "/usr/local/lib/python3.7/dist-packages/omni_epd/test_utility.py",
line 67, in __draw_on_display
self.epd.display(image)
File "/usr/local/lib/python3.7/dist-packages/omni_epd/virtualepd.py",
line 202, in display
self._display(self.__applyConfig(image))
File
"/usr/local/lib/python3.7/dist-packages/omni_epd/displays/waveshare_display.py",
line 263, in _display
self._device.display(self._device.getbuffer(image))
AttributeError: 'EPD' object has no attribute 'display'

Let me know if you need further testing.

Aaron

Config file

Many projects (like Python logging) allow for advanced config to be read in from a config file. This might be a good idea to allow users to define more advanced parameters for displays that don't necessarily need to be part of the VSMP implementers code. Examples of this would be display rotation or color formatting. This would allow for some sane defaults but if a user needed more advanced config for their purpose it isn't on the VSMP project to pass down these directives as part of their codebase.

Waveshare 7.8in HAT support?

Donโ€™t know if this is the right place to ask, but is there any chance to support the waveshare 7.8in HAT screen at all?

https://www.waveshare.com/wiki/7.8inch_e-Paper_HAT

I would love to replace my Rasp Pi 4b / 7in5_V2 screen (which works perfectly) with this higher res screen that I bought months ago but I havenโ€™t got anywhere with waveshare directly. They have no plans to support their own screen in the python library -

โ€œI'm sorry that we don't have a plan toย release a python driver for the library, since the speed of the parallel port screen is too slow if you use python to refresh it.โ€

I donโ€™t understand the answer (Iโ€™m a beginner following instructions), but hoped someone here could help.

Review epd1in54b

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd1in54b.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd1in54b_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_1in54b_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_1in54b_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

clear() results in TypeError for WaveShare epd2in7

Display Type: waveshare_epd.epd2in7
Version pulled: 2021.05.08 Main Branch

The omni-epd-test and example code both successfully display rectangles and the nebula image respectively without issue.

Calling the clear() method on a displayfactory object raises a TypeError:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-7ef3a3b8a5ed> in <module>
----> 1 epd.clear()

~/.local/share/virtualenvs/epdlib-AIMLabQa/lib/python3.7/site-packages/omni_epd/displays/waveshare_display.py in clear(self)
     64         Most devices utilize the same clear function
     65         """
---> 66         self._device.Clear()
     67 
     68     def close(self):

TypeError: Clear() missing 1 required positional argument: 'color'

The root cause is that the epd2in7 B&W driver expects a color value. This is extra frustrating because the 2in7 doesn't even use the color value.

I've started rewriting the waveshare EPD drivers to clean up some of this mess, but there's so much inconsistency, copy/pasta, and lack of proper documentation that I haven't made much progress beyond the 2in7 and 5in83.

Minimal example:

import sys
from omni_epd import displayfactory, EPDNotFoundError
from PIL import Image

displayName = "waveshare_epd.epd2in7"
print('Loading display')
try:
    epd = displayfactory.load_display_driver(displayName)
except EPDNotFoundError:
    print(f"Couldn't find {displayName}")
    sys.exit()

# if now load an image file using the Pillow lib
print('Loading image')
image = Image.open('../PIA03519_small.jpg')
# resize for your display
image = image.resize((epd.width, epd.height))
# prepare the epd, write the image, and close
print('Writing to display')
epd.prepare()
epd.display(image)
epd.close()

epd.prepare()
epd.clear()
epd.close()

โ€œIllegal instructionโ€ when importing from `omni-epd` on Raspberry Pi Zero

Hi, sorry in advance for the silly question. Python deps are endlessly confusing to me, and Iโ€™m sure this is my fault ๐Ÿ˜–

Context:

I just went through the โ€œAutomated Installationโ€ to set up SlowMovie on a Raspberry Pi Zero. When I tried to run python3 slowmovie.py to start the program, I got an โ€œIllegal instructionโ€ error. I traced it back to the following line:

from omni_epd import displayfactory, EPDNotFoundError

Minimal repro:

I isolated the above line into its own file and observed the same error.


I was able to get slowmovie.py working by swapping out omni_epd with waveshare_epd, following how itโ€™s used in helloworld.py. But I figured that since youโ€™re an active contributor to SlowMovie, you might be interested in this bug.

Happy to provide additional information if it would be helpful, just let me know! Cheers.

Review epd7in5_HD

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd7in5_HD.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_7in5_HD_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in9bc

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in9bc.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in9b_V3.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in9bc_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in9bc_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd7in5bc

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd7in5bc.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_7in5bc_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd7in5b_HD

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd7in5b_HD.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_7in5b_HD_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd3in7

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd3in7.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_3in7_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Simplify Display Testing

Simplify the display testing procedure of EPDTestUtility by using a console script when installed. This will remove the need for implementers to bundle test scripts themselves and then can use the built in function.

Pillow Static Variables Changed

In version of Pillow 9.1.0 and greater several variables have changed related to image transformations. There are places in the omni-epd code that use the pre-9.1.0 variable names and are likely to throw an error as Pillow updates on new installs or upgrades to existing systems. To further complicate matters downstream libraries, like the IT8951 drivers, have already updated to work with the new variable names. This means pinning a specific version won't work as these libs will fail should someone try and load them.

Code related to the image transformations will need to be updated. Most of it (perhaps all) starts in the virtualepd.py file - https://github.com/robweber/omni-epd/blob/main/src/omni_epd/virtualepd.py#L89

Links

https://pillow.readthedocs.io/en/latest/releasenotes/9.1.0.html#constants

Review epd2in7

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in7.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in7_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in13

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in13.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in13_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in13_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in13_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in7b

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in7b.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in7b_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in7b_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in7b_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd5in83bc

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in83bc.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in83b_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_5in83bc_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_5in83b_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Waveshare 7.8 display

I have been running SlowMovie player on a 7.5 inch Waveshare display but wanted to try it on the 7.8. the only change I made was to set epd = waveshare_epd.it8951 and remove the other epd display from the conf file. When I run the program nothing displays on the 7.8 and I get the following;

Traceback (most recent call last):
File "/home/pi/SlowMovie/slowmovie.py", line 251, in
epd = displayfactory.load_display_driver(args.epd)
File "/home/pi/.local/lib/python3.9/site-packages/omni_epd/displayfactory.py", line 113, in load_display_driver
result = classObj(deviceType[1], config)
File "/home/pi/.local/lib/python3.9/site-packages/omni_epd/displays/waveshare_display.py", line 404, in init
self._device = deviceObj.AutoEPDDisplay(vcom=self._getfloat_device_option('vcom', -2.06),
File "/home/pi/.local/lib/python3.9/site-packages/IT8951/display.py", line 227, in init
AutoDisplay.init(self, self.epd.width, self.epd.height, **kwargs)
File "/home/pi/.local/lib/python3.9/site-packages/IT8951/display.py", line 26, in init
self._set_rotate(rotate, mirror)
File "/home/pi/.local/lib/python3.9/site-packages/IT8951/display.py", line 69, in _set_rotate
'CW' : Image.Transpose.ROTATE_270,
File "/home/pi/.local/lib/python3.9/site-packages/PIL/Image.py", line 65, in getattr
raise AttributeError(f"module '{name}' has no attribute '{name}'")
AttributeError: module 'PIL.Image' has no attribute 'Transpose'

Any ideas what is going wrong?

thanks,
Tom

Review epd1in02

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd1in02.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_1in02_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in9d

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in9d.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in9d_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd4in01f

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd4in01f.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_4in01f_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in9

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in9.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in9_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in9_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in9_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Couldn't find waveshare_epd.epd5in65f

Thanks for your development of this tool. I've implemented this in a project I'm working on. Previously was working with "waveshare_epd.epd7in5_V2", however I have tried to implement using a "waveshare_epd.epd5in65f". Official screen tests from waveshare work.

Receiving error on run for 'waveshare_epd.epd5in65f'
INFO:root:Couldn't find waveshare_epd.epd5in65f

When running displayfactory.list_supported_displays() I get a 'waveshare_epd.epd5in64f' in the list, which does not appear to be a valid name for a waveshare driver/product. When trying to run for waveshare_epd.epd5in64f as a test:
"waveshare_epd.epd5in64f not found, refer to install instructions"

Tried reinstalling waveshare package, no dice. Have tried to find where this error is occurring but I've not been able to dig too far into this code. Logging issue just in case it actually is an issue. As far as I can tell there may be a minor spelling error but can't find the text in the drivers or the code of this repo, really scratching my head about this one.

Inky BW inversion problem

Seems that #61 introduced an issue with Inky displays in BW mode. Prior to that fix Inky models used black as the color mode instead of bw. This caused images in that mode to use palette based color filtering with a palette. By fixing the mode it now triggers the conditional to convert the image to using convert(mode=1). For some reason having the image in this mode causes the black and white pixels to be inverted when drawn to the display.

In hindsight this was working correctly, but only because the code block that should have been triggered was actually missed. Inky seems to respond correctly by having the image in P mode.

Review epd2in66b

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in66b.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in66b_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd4in2

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd4in2.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_4in2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

only red pixels

Hi, I've got a waveshare_epd.epd2in7b_V2 that i'm trying to show a picture on.

when i configure the device for red mode using an ini file all I get is red pixels on the display, should it also display black?

e.g:
source image:
origonal
resized and converted to RBG:
converted
displayed:
rendered

Review epd5in65f

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in65f.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_5in65f_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Black vs BW

I noticed when looking through things that some devices use bw as they default mode identifier while others use black. It's more of a semantic difference but sticking with a single identifier across all types would be more consistent. There are also areas in the parent virtualepd.py class where it checks specifically for bw as a string before applying certain functions.

Might be worth the effort of defining some constants for comparisons as well as consistency.

Review epd7in5

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd7in5.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd7in5_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_7in5_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_7in5_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Inky Impression library doesn't work

I have followed the Pimoroni instructions w/ latest version (1.3.1) and installed Omni-epd with my Inky Impression color 5.7" display on raspberry pi 3 A+ and 4 B+, however the command omni-epd-test -e inky.impression does nothing. It doesn't update the display or output anything. However - if I run omni-end-test -e waveshare_epd.epd5in83 the screen will update.

more curious, the examples provided by Pimoroni (logo.py, stripes.py etc) will not work, but if I run omni-end-test -e waveshare_epd.epd5in83 immediately after, the screen will refresh with the aforementioned Pimoroni example image. Running it a second time will result in the screen drawing the squares as designed.

Individual EDP instructions

It's almost impossible to bundle all the right libraries for each type of EPD. Many have additional OS requirements (installed with apt-get or similar) or python libraries that need to be built by hand.

Define a place in the documentation that links to each display type's library setup instructions and explain that these need to be part of implementing projects.

Extend INI file

A possible extension for the INI could allow for device specific parameters to be set for things that are device driver dependent. Examples of this include initialization parameters to set b/w vs grayscale for supported devices or pass in values like saturation for Inky Impression devices to the display() function. These are values that don't adjust the Image being passed to the display but instead configuration values on the display itself.

The way this would work is to define a device specific section in the ini file:

[omni-epd.mock]
grayscale=True

Implementing classes would be responsible for checking if these values exist and applying them accordingly. Advantages to this are that implementers can either bundle device specific configs with their projects per the global INI file; or users can modify them to their liking.

Review epd2in66

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in66.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in66_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd4in2bc

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd4in2bc.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd4in2b_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_4in2bc_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_4in2b_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

clear() results in TypeError for WaveShare epd2in13_V2

Display Type: waveshare_epd.epd2in13_V2
Version pulled: 2022.03.29 Main Branch

> from omni_epd import displayfactory
> epd = displayfactory.load_display_driver("waveshare_epd.epd2in13_V2")
> epd.prepare()
> epd.clear()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "$CONDA_PATH/lib/python3.9/site-packages/omni_epd/displays/waveshare_display.py", line 139, in clear
    self._device.Clear()
TypeError: Clear() missing 1 required positional argument: 'color'

I read the issue #19 about this error, and could not solve it. The epd2in13_V2 display is not declared as a device that needs an alternate clear() function, but it should.

I tried to fix this by changing the following line

"epd2in13_V2": {"alt_init": True, "lut_init": False, "alt_clear": False, "version": 2},

to

"epd2in13_V2": {"alt_init": True, "lut_init": True, "alt_clear": True, "version": 2},

but it did not work and I got the same error.

Review epd5in83

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in83.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in83_V2.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_5in83_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_5in83_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd2in13bc

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in13bc.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in13b_V3.py
Example code:
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in13bc_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_2in13b_V3_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Review epd1in54

Review the function calls for the Waveshare device and make sure the omni-epd abstraction uses the right methods, with the right parameters based on the library and example code. Any modifications should be patched in a PR referencing this issue.

Library file: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd1in54.py
Example code: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_1in54_test.py
https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/examples/epd_1in54_V2_test.py

Things to check:

  • init() method
  • display() method
  • clear() method
  • sleep() method

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.