Прошло 2 года.

This commit is contained in:
Кобелев Андрей Андреевич
2026-03-10 22:54:23 +03:00
parent c7636ebd6f
commit a111352dc5
313 changed files with 274971 additions and 1409 deletions

View File

@@ -0,0 +1,44 @@
About
=====
EPDiy is a driver board for e-Paper (or E-ink) displays.
.. _display_types:
Display Types
-------------
The EPDiy driver board targets multiple E-Paper displays.
As the driving method for all matrix-based E-ink displays seems to be more or less the same, only the right connector and timings are needed.
A table of supported displays is mainained in the :code:`README.md` file.
Some of the supported displays are showcased below.
ED097OC4
~~~~~~~~
The ED097OC4 was the original target of this project. It is an 9.7 inch screen, with a resolution of 1200 * 825 pixels (150dpi).
It is fairly available on Ebay and AliExpress, for around 30$ to 35$.
There is also a lower contrast version (ED097OC1) which also works.
.. image:: img/ed097oc4.jpg
ED060SC4
~~~~~~~~
This is a 6 inch display, with a 800 * 600 resolution. With 150dpi as well, it has about half the total display area of the ED097OC4.
To connect this display, the 39-pin connector on the back has to be populated.
It is also the display a lot of experimentation was done with (see Thanks To), so there are alternative controllers available.
Besides the obvious difference in size, this display is cheaper (~20$) and also refreshes slightly faster than the ED097OC4.
.. image:: img/ed060sc4.jpg
ED097TC2
~~~~~~~~
Information on this display should be taken with a grain of salt. One of the displays I ordered as ED097OC4 came as ED097TC2,
and upon testing it also exhibited noticably better contrast and a more responsive electro-phoretic medium.
The ribbon connector looked like a ED097TC2 as well, or like the `9.7 inch screens offered by Waveshare <https://www.waveshare.com/9.7inch-e-Paper.htm>` (which is sold for a lot more).
If you are on the lookout for such a display keep in mind the authenticity of my sample is disputable and resolution and connector type should be double-checked.
.. image:: img/ed097tc2.jpg

View File

@@ -0,0 +1,20 @@
.. _pub_api:
Library API
===========
Highlevel API
-------------
.. doxygenfile:: epd_highlevel.h
Complete API
------------
.. doxygenfile:: epdiy.h
Internals
----------
.. doxygenfile:: epd_internals.h
Board-Specific Extensions
-------------------------
.. doxygenfile:: epd_board_specific.h

View File

@@ -0,0 +1,71 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import subprocess, os
# -- Project information -----------------------------------------------------
project = 'EPDiy'
copyright = '2023, Valentin Roland'
author = 'Valentin Roland'
# The full version, including alpha/beta/rc tags
release = '2.0.0'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'breathe'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
breathe_projects = { "epdiy": "./xml/" }
breathe_default_project = "epdiy"
breathe_domain_by_extension = {
"h" : "c",
"c" : "c",
}
read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
if read_the_docs_build:
subprocess.call('cd ../; doxygen', shell=True)

View File

@@ -0,0 +1,95 @@
Fonts, Images, Waveforms
========================
The ESP32 is, although fairly capable, still a microcontroller.
Thus, with memory and computational resources limited, it is useful to do as much of the processing
for displaying fonts and images on a computer.
Epdiy comes with scripts that convert fonts, images and waveforms to C headers,
that you can then simply `#include` in your project.
Generating Font Files
---------------------
Fonts can only be used by the driver in a special header format
(inspired by the Adafruit GFX library), which need to be generated from TTF fonts.
For this purpose, the :code:`scripts/fontconvert.py` utility is provided.
.. code-block::
fontconvert.py [-h] [--compress] [--additional-intervals ADDITIONAL_INTERVALS] name size fontstack [fontstack ...]
The following example generates a header file for Fira Code at size 10, where glyphs that are not found in Fira Code will be taken from Symbola:
.. code-block::
./fontconvert.py FiraCode 10 /usr/share/fonts/TTF/FiraCode-Regular.ttf /usr/share/fonts/TTF/Symbola.ttf > ../examples/terminal/main/firacode.h
You can change which unicode character codes are to be exported by specifying additional
ranges of unicode code points with :code:`--additional-intervals`.
Intervals are written as :code:`min,max`.
To add multiple intervals, you can specify the :code:`--additional-intervals` option multiple times.
.. code-block::
./fontconvert.py ... --additional-intervals 0xE0A0,0xE0A2 --additional-intervals 0xE0B0,0xE0B3 ...
The above command would add two addtitional ranges.
You can enable compression with :code:`--compress`, which reduces the size of the generated font but comes at a performance cost.
If the generated font files with the default characters are too large for your application,
you can modify :code:`intervals` in :code:`fontconvert.py`.
Generating Images
-----------------
The process for converting images is very similar to converting fonts.
Run the :code:`scripts/imgconvert.py` script with an input image, an image name and an output image.
.. code-block::
imgconvert.py [-h] -i INPUTFILE -n NAME -o OUTPUTFILE [-maxw MAX_WIDTH] [-maxh MAX_HEIGHT]
The image is converted to grayscale scaled down to match fit into :code:`MAX_WIDTH` and :code:`MAX_HEIGHT` (1200x825 by default).
For accurate grayscale it is advisable to color-grade and scale the image with a dedicated tool before converting it.
:code:`OUTPUTFILE` will be a C header with the following constants defined:
- :code:`{NAME}_width` is the width of the image
- :code:`{NAME}_height` is the height of the image
- :code:`{NAME}_data` is the image data in 4 bit-per-pixel grayscale format.
Converting Waveforms
--------------------
.. note:: Waveform Timings and V7
Epdiy builtin waveforms currently use variable frame timings to reduce the number
of update cycles required. This is currently not implemented in V7. Hence, for best results it is recommended to use Vendor waveforms where available, which use constant frame timings.
In comercial applications, displays are driven with information in so-called `Waveform Files`.
These specify how which pulses to apply to the pixel to transition from one gray tone to another.
Unfortunately, they are display-specific and proprietary.
However, while they are not freely available, they can be obtained through a number of ways:
- Being a large customer of E-Ink. Unfortunately not doable for mere mortals.
- Finding them scattered around the internet. Examples include the `MobileRead forums <https://www.mobileread.com/>`_ or the `NXP Support forum <https://community.nxp.com/t5/i-MX-Processors/How-to-convert-wbf-waveform-file-to-wf-file/m-p/467926/highlight/true>`_.
- Extracting from e-Reader firmware.
- Extracting from a flash chip that comes with some displays. More on this can be found `here <https://hackaday.io/project/21168-fpga-eink-controller/log/57822-waveforms-binary-extract>`_.
Waveforms usually come with a :code:`*.wbf` file extension.
If you have a matching waveform file for your display, it can be converted to a waveform header that's usable by epdiy.
The advantage of using vendor waveforms include the availability of all implemented modes in the waveform file, support of a wide range of temperatures and more accurate grayscale-to-grayscale transitions.
As a first step, the waveform data is extracted from the original waveform file and stored in JSON format.
This can be done using a `modified version <https://github.com/vroland/inkwave>`_ of `inkwave <https://github.com/fread-ink/inkwave>`_ by Marc Juul.
Once a matching JSON file is obtained, the :code:`scripts/waveform_hdrgen.py` utility can be used to generate a waveform header, which can be included in your project.
::
waveform_hdrgen.py [-h] [--list-modes] [--temperature-range TEMPERATURE_RANGE] [--export-modes EXPORT_MODES] name
With the :code:`--list-modes` option, a list of all included modes is printed.
:code:`name` specifies a name for the generated :code:`EpdWaveform` object.
Additionally, the temperature range and modes to export can be limited in order to reduce file size.
An example for the usage of this script can be found in the top-level :code:`Makefile` of the epdiy repository.

View File

@@ -0,0 +1,140 @@
.. _getting_started:
Getting Started
===============
Getting your Board
------------------
At the current point in time, there is no official way to buy an epdiy board.
Fortunately, it is quite easy to order your own. There are many PCB prototype services
that will manufacture boards for a low price.
To use one of those services, upload the "Gerber files", usually provided as a zip file,
to the service.
You can find all the available hardware listed on the `Hardware Page <https://vroland.github.io/epdiy-hardware/>`_.
Choosing and Finding Parts
~~~~~~~~~~~~~~~~~~~~~~~~~~
The parts needed to assemble the epdiy board are listed in the `BOM.csv` file.
Commodity parts like resistors, capacitors, coils and diodes are interchangable, as long as they
fit the footprint.
When in doubt, use the parts listed in the BOM file.
However, some parts are not as common, especially the connectors.
Most of them can be found on sites like eBay or AliExpress.
Tips:
- Use the WROVER-B module instead of other WROVER variants.
This module exhibits a low deep sleep current and is proven to work.
- The LT1945 voltage booster seems to be out of stock with some distributors,
but they are available cheaply from AliExpress.
Calibrate VCOM
--------------
.. note:: Only for old boards
This is only needed with boards prior to revision 6.
From revision 6 onwards, VCOM can be set in software via :code:`epd_set_vcom(..)`.
EPaper displays use electrical fields to drive colored particles.
One of the required voltages, VCOM (Common Voltage) is display-dependent
and must be calibrated for each display individually.
Fortunately, the VCOM voltage is usually printed on the display, similar to this:
.. image:: img/vcom.jpg
The VCOM value is usually between -1V and -3V.
For the v6 board, you can enter the desired VCOM value in :code:`make menuconfig`.
No interaction is required.
For the older models, use the trimmer marked :code:`RV1`.
You can measure the VCOM on the VCOM test pad (if your board has one) or directly
at the amplifier:
.. image:: img/vcom_tp.jpg
.. image:: img/vcom_opamp.jpg
.. note::
Although most boards do not have it yet, image quality for partial updates can be improved by adding a (at least) 4.7uF capacitor between VCOM and GND.
When adding this capacitor, take care with the polarity as VCOM is negative!
Flashing the demo
-----------------
First, connect you board with the computer. In the output of :code:`lsusb` you should find something like:
::
Bus 001 Device 048: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
This means the serial adapter is working and there a serial like :code:`/dev/ttyUSB0` should appear.
Next, make sure you have the `Espressif IoT Development Framework <https://github.com/espressif/esp-idf>`_ installed.
The current stable (and tested) version is 5.3.
For instructions on how to get started with the IDF, please refer to their `documentation <https://docs.espressif.com/projects/esp-idf/en/stable/get-started/>`_.
Then, clone the :code:`epdiy` git repository (and its submodules):
::
git clone --recursive https://github.com/vroland/epdiy
Now, (after activating the IDF environment) you should be able to build the demo:
::
cd examples/demo/
idf.py build
Hold down the :code:`BOOT` button on your board, while quickly pressing the :code:`RESET` button.
The ESP module is now in boot mode.
Upload the demo program to the board with
::
idf.py flash -b 921600 && idf.py monitor
Pressing :code:`RESET` a second time should start the demo program, which will
output some information on the serial monitor.
With the **board power turned off**, connect your display.
Power on the board.
You should now see the demo output on your display.
Use with esp-idf
----------------
The neccessary functionality for driving an EPD display is encapsulated in the :code:`components/epdiy` IDF component.
To use it in you own project, simply copy the :code:`epdiy` folder to your project-local :code:`components` directory.
The component sould be automatically detected by the framework, you can now use
::
#include "epdiy.h"
to use the EPD driver's :ref:`pub_api`.
Selecting a Board and Display Type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With epdiy 2.0.0, the display type and board are set via :code:`epd_init()`.
Enable SPI RAM
~~~~~~~~~~~~~~~~~~~~~~~~
The ESP32-WROVER-B comes with an additional 8MB external PSRAM, where the :code:`epdiy` is going to store ~2MB for its internal frame buffers.
Since it is dynamically allocated from the heap, and the built-in SRAM of ~160KB is insufficient, we need to enable external SPI RAM first.
Open the :code:`menuconfig` again (see above) and navigate to :code:`Component config -> ESP32-Specific -> Support for external, SPI-connected RAM` and enable it.
Use with Arduino
----------------
Epdiy can be used as an Arduino library. Additionally, epdiy comes with board definitions for its supported boards, which must be installed separately.
To install epdiy to work with the Arduino IDE (>= 1.8), place the downloaded repository into your Arduino libraries folder.
Alternatively, it is possible to use the `Arduino APIs as an IDF component <https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md>`_,
which allows you to use the Arduino ecosystem (Except for a different build process).
This gives you full access to ESP-IDF options.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -0,0 +1,35 @@
.. EPDiy documentation master file, created by
sphinx-quickstart on Sat Apr 18 23:41:08 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
The EPDiy Driver Board
======================
.. toctree::
:maxdepth: 2
:caption: Quickstart:
about.rst
getting_started.rst
filegen.rst
tips.rst
api.rst
EPDiy is a driver board which talks to affordable E-Paper (or E-Ink) screens, which are usually sold as replacement screens for E-Book readers. Why are they interesting?
* Easy on the eyes and paper-like aesthetics
* No power consumption when not updating
* Sunlight-readable
Ready-made DIY modules for this size and with 4bpp (16 Grayscale) color support are currently quite expensive. This project uses Kindle replacement screens, which are available for 20$ (small) / 30$ (large) on ebay!
The EPDiy driver board targets multiple E-Paper displays. As the driving method for all matrix-based E-ink displays seems to be more or less the same, only the right connector and timings are needed. The EPDiy PCB features a 33pin and a 39pin connector, which allow to drive the following display types: ED097OC4, ED060SC4, ED097TC2
:ref:`getting_started`
.. image:: img/demo.jpg
.. image:: img/board_p1.jpg
.. image:: img/board_p2.jpg

View File

@@ -0,0 +1,41 @@
Tips & Tricks
=============
Temperature Dependence
----------------------
The display refresh speed depends on the environmental temperature.
Thus, if your room temperature is significantly different from ~22°C, grayscale
accuracy might be affected when using the builtin waveform.
This can be mitigated by using a different timing curve, but this would require calibrating the display timings at that temperature.
If you did this for some temperature other than room temperature, please submit a pull request!
Deep Sleep Current
------------------
Board Revision V5 is optimized for running from a battery thanks to its low deep sleep current consumption.
In order to achieve the lowest possible deep sleep current, call
::
epd_deinit()
before going to deep sleep. This will de-initialize the I2S peripheral used to drive the diplay and bring the pins used by epdiy to a low-power state.
You should be able to achieve a deep-sleep current of less than 13µA.
If your deep-sleep current is much higher, please check your attached peripherals.
With some modules, you have to isolate GPIO 12 before going to deep sleep:
::
rtc_gpio_isolate(GPIO_NUM_12)
Adding a New Display
--------------------
This section is work-in-progress.
- Add display definitions in :code:`displays.c` and :code:`epd_display.h`.
- Include waveform in :code:`bulitin_waveforms.c`
- Calibrate timing curve in :code:`scripts/generate_epdiy_waveforms.py`.
- Add to the list of displays to build waveforms for in :code:`Makefile`
- Document