Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
6d04685f10
2
.github/workflows/test-on-rpi.yml
vendored
2
.github/workflows/test-on-rpi.yml
vendored
@ -51,7 +51,7 @@ jobs:
|
|||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install wheel
|
pip install wheel
|
||||||
pip install -e ./
|
pip install -e ./
|
||||||
pip install RPi.GPIO==0.7.1 spidev==3.5
|
pip install RPi.GPIO==0.7.1 spidev==3.5 gpiozero==2.0
|
||||||
wget https://raw.githubusercontent.com/aceinnolab/Inkycal/assets/tests/settings.json
|
wget https://raw.githubusercontent.com/aceinnolab/Inkycal/assets/tests/settings.json
|
||||||
pip install pytest
|
pip install pytest
|
||||||
python -m pytest
|
python -m pytest
|
||||||
|
8
.github/workflows/update-os.yml
vendored
8
.github/workflows/update-os.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
|||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install wheel
|
pip install wheel
|
||||||
pip install -e ./
|
pip install -e ./
|
||||||
pip install RPi.GPIO==0.7.1 spidev==3.5
|
pip install RPi.GPIO==0.7.1 spidev==3.5 gpiozero==2.0
|
||||||
wget https://raw.githubusercontent.com/aceinnolab/Inkycal/assets/tests/settings.json
|
wget https://raw.githubusercontent.com/aceinnolab/Inkycal/assets/tests/settings.json
|
||||||
pip install pytest
|
pip install pytest
|
||||||
python -m pytest
|
python -m pytest
|
||||||
@ -84,8 +84,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Compress the release image
|
- name: Compress the release image
|
||||||
run: |
|
run: |
|
||||||
mv ${{ steps.build_image.outputs.image }} inkycal_os_lite.img
|
mv ${{ steps.build_image.outputs.image }} InkycalOS_Lite.img
|
||||||
xz -0 -T 0 -v inkycal_os_lite.img
|
xz -0 -T 0 -v InkycalOS_Lite.img
|
||||||
|
|
||||||
- name: Get latest release version
|
- name: Get latest release version
|
||||||
run: |
|
run: |
|
||||||
@ -99,4 +99,4 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ env.version }}
|
tag_name: ${{ env.version }}
|
||||||
files: inkycal_os_lite.img.xz
|
files: InkycalOS_Lite.img.xz
|
||||||
|
303
README.md
303
README.md
@ -1,9 +1,300 @@
|
|||||||
# Inkycal-based full screen weather display (scraper solution)
|
# Welcome to inkycal v2.0.3!
|
||||||
|
|
||||||
This fork of <https://github.com/aceinnolab/Inkycal/> was used to try out a webscraper approach for a openweathermap-based full screen weather display on a 7in5 waveshare v2 colour epd.
|
<p align="center">
|
||||||
It didn't prove particularly robust, so I've decided to not further develop it.
|
<img src="https://raw.githubusercontent.com/aceisace/Inkycal/assets/Repo/logo.png" width="900" alt="aceinnolab logo">
|
||||||
I'll leave it here in case someone wants to try and play around with it a little.
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://github.com/aceinnolab/Inkycal/blob/c1c274878ba81ddaee6186561e6ea892da54cd6a/Repo/inkycal-featured-gif.gif" width="900" alt="featured-image">
|
||||||
|
</p>
|
||||||
|
|
||||||
Since Selenium doesn't run on Pi Zero, I had to run the scraper part as a cron job on my Pi 4 and scp the resulting image to the Pi Zero that's connected to the e-paper display.
|
<p align="center">
|
||||||
|
<a href="https://github.com/aceinnolab/Inkycal/actions/workflows/test-on-rpi.yml"><img src="https://github.com/aceinnolab/Inkycal/actions/workflows/test-on-rpi.yml/badge.svg"></a>
|
||||||
|
<a href="https://github.com/aceinnolab/Inkycal/actions/workflows/update-docs.yml"><img src="https://github.com/aceinnolab/Inkycal/actions/workflows/update-docs.yml/badge.svg"></a>
|
||||||
|
<a href="https://github.com/aceinnolab/Inkycal/releases"><img alt="Version" src="https://img.shields.io/github/release/aceisace/Inkycal.svg"/></a>
|
||||||
|
<a href="https://github.com/aceinnolab/Inkycal/blob/main/LICENSE"><img alt="Licence" src="https://img.shields.io/github/license/aceisace/Inkycal.svg" /></a>
|
||||||
|
<a href="https://github.com/aceinnolab/Inkycal/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/aceisace/Inkycal?color=yellow"></a>
|
||||||
|
<a href="https://github.com/aceinnolab/Inkycal"><img alt="python" src="https://img.shields.io/badge/python-3.11-lightorange"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
For further information see the official Inkycal repo.
|
Inkycal is a software written in python for selected E-Paper displays. It converts these displays into useful
|
||||||
|
information dashboards. It's open-source, free for personal use, fully modular and user-friendly. Despite all this,
|
||||||
|
Inkycal can run well even on the Raspberry Pi Zero. Oh, and it's open for third-party modules! Hooray!
|
||||||
|
|
||||||
|
## ⚠️ Warning: long installation time expected!
|
||||||
|
|
||||||
|
Starting october 2023, Raspberry Pi OS is now based on Debian bookworm and uses python 3.11 instead of 3.9 as the
|
||||||
|
default version. Inkycal has been updated to work with python3.11, but the installation of numpy can take a very long
|
||||||
|
time, in some cases even hours. If you do not want to wait this long to install Inkycal, you can also get a
|
||||||
|
ready-to-flash version of Inkycal called InkycalOS-Lite with everything pre-installed for you by sponsoring
|
||||||
|
via [Github Sponsors](https://github.com/sponsors/aceisace). This helps keep up maintenance costs, implement new
|
||||||
|
features and fixing bugs. Please choose the one-time sponsor option and select the one with the plug-and-play version of
|
||||||
|
Inkycal. Then, send your email-address to which InkycalOS-Lite should be sent.
|
||||||
|
Alternatively, you can also use the paypal.me link and send the same amount as Github sponsors to get access to InkycalOS-Lite!
|
||||||
|
|
||||||
|
## Main features
|
||||||
|
|
||||||
|
Inkycal is fully modular, you can mix and match any modules you like and configure them on the web-ui. For now, these
|
||||||
|
following built-in modules are supported:
|
||||||
|
|
||||||
|
* Calendar - Monthly Calendar with option to sync events from iCalendars, e.g. Google.
|
||||||
|
* Agenda - Agenda showing upcoming events from given iCalendar URLs.
|
||||||
|
* Image - Display an Image from URL or local file path.
|
||||||
|
* Slideshow - Cycle through images in a given folder and show them on the E-Paper.
|
||||||
|
* Feeds - Synchronise RSS/ATOM feeds from your favorite providers.
|
||||||
|
* Stocks - Display stocks using Tickers from Yahoo! Finance.
|
||||||
|
* Weather - Show current weather, daily or hourly weather forecasts from openweathermap.
|
||||||
|
* Todoist - Synchronise with Todoist app or website to show todos.
|
||||||
|
* iCanHazDad - Display a random joke from [iCanHazDad.com](iCanhazdad.com).
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
Watch the one-minute video on getting started with Inkycal:
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=IiIv_nWE5KI)
|
||||||
|
|
||||||
|
## Hardware guide
|
||||||
|
|
||||||
|
Before you can start, please ensure you have one of the supported displays and of the supported Raspberry
|
||||||
|
Pi: `|4|3A|3B|3B+|2B|0W|0WH|02W|`. We personally recommend the Raspberry Pi Zero W as this is relatively cheaper, uses
|
||||||
|
less power and is perfect to fit in a small photo frame once you have assembled everything.
|
||||||
|
|
||||||
|
**Serial** displays are usually cheaper, but slower. Their main advantage is ease of use, like being able to communicate
|
||||||
|
via SPI. A single update will cause flickering (fully normal on e-paper displays) ranging from a few seconds to half an
|
||||||
|
minute. We recommend these for users who want to get started quickly and for more compact setups, e.g. fitting inside a
|
||||||
|
photo frame. The resolution of these displays ranges from low to medium. Usually, these displays support 2-3 colours,
|
||||||
|
but no colours in between, e.g. fully black, fully red/yellow and fully-white.
|
||||||
|
|
||||||
|
**Parallel** displays on the other hand do not understand SPI and require their own dedicated driver boards individually
|
||||||
|
configured for these displays. Flickering also takes place here, but an update only takes about one to a few seconds.
|
||||||
|
The resolution is much better than serial e-paper displays, but the cost is also higher. These also have 16 different
|
||||||
|
grayscale levels, which does not compare to the 256 grayscales of LCDs, but far better than serial displays.
|
||||||
|
|
||||||
|
**❗️Important note: e-paper displays cannot be simply connected to the Raspberry Pi, but require a driver board. The
|
||||||
|
links below may or may not contain the required driver board. Please ensure you get the correct driver board for the
|
||||||
|
display!**
|
||||||
|
|
||||||
|
| type | vendor | Where to buy |
|
||||||
|
|-------------------------------------------|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| 7.5" Inkycal (plug-and-play) | Aceinnolab (author) | [Buy on Tindie](https://www.tindie.com/products/aceisace4444/inkycal-build-v1/) Pre-configured version of Inkycal with custom frame and a web-ui. You do not need to buy anything extra. Includes Raspberry Pi Zero W, 7.5" e-paper, microSD card, driver board, custom packaging and 1m of cable. Comes pre-assembled for plug-and-play. |
|
||||||
|
| Inkycal frame (kit -> requires wires, 7.5" Display and Zero W with microSD card | Aceinnolab (author) | [Buy on Tindie](https://www.tindie.com/products/aceinnolab/inkycal-frame-custom-driver-board-only/) Ultraslim frame with custom-made front and backcover inkl. ultraslim driver board). You will need a Raspberry Pi, microSD card and a 7.5" e-paper display |
|
||||||
|
| `[serial]` 12.48" (1304×984px) display | waveshare / gooddisplay | Search for `Waveshare 12.48" E-Paper 1304×984` on amazon or similar |
|
||||||
|
| `[serial]` 7.5" (640x384px) -> v1 display (2/3-colour) | waveshare / gooddisplay | Search for `Waveshare 7.5" E-Paper 640x384` on amazon or similar |
|
||||||
|
| `[serial]` 7.5" (800x480px) -> v2 display (2/3-colour) | waveshare / gooddisplay | Search for `Waveshare 7.5" E-Paper 800x480` on amazon or similar |
|
||||||
|
| `[serial]` 7.5" (880x528px) -> v3 display (2/3-colour) | waveshare / gooddisplay | Search for `Waveshare 7.5" E-Paper 800x528` on amazon or similar |
|
||||||
|
| `[serial]` 5.83" (400x300px) display | waveshare / gooddisplay | Search for `Waveshare 5.83" E-Paper 400x300` on amazon or similar |
|
||||||
|
| `[serial]` 4.2" (400x300px)display | waveshare / gooddisplay | Search for `Waveshare 4.2" E-Paper 400x300` on amazon or similar | |
|
||||||
|
| `[parallel]` 10.3" (1872×1404px) display | waveshare / gooddisplay | Search for `Waveshare 10.3" E-Paper 1872×1404` on amazon or similar |
|
||||||
|
| `[parallel]` 9.7" (1200×825px) display | waveshare / gooddisplay | Search for `Waveshare 9.7" E-Paper 1200×825` on amazon or similar |
|
||||||
|
| `[parallel]` 7.8" (1872×1404px) display | waveshare / gooddisplay | Search for `Waveshare 7.8" E-Paper 1872×1404` on amazon or similar |
|
||||||
|
| Raspberry Pi Zero W | Raspberry Pi | Search for `Raspberry Pi Zero W` on amazon or similar |
|
||||||
|
| MicroSD card | Sandisk | Search for `MicroSD card 8GB` on amazon or similar |
|
||||||
|
|
||||||
|
## Configuring the Raspberry Pi
|
||||||
|
|
||||||
|
Flash Raspberry Pi OS on your microSD card (min. 4GB) with [Raspberry Pi Imager](https://rptl.io/imager). Use the
|
||||||
|
following settings:
|
||||||
|
|
||||||
|
| option | value |
|
||||||
|
|:--------------------------|:---------------------------:|
|
||||||
|
| hostname | inkycal |
|
||||||
|
| enable ssh | yes |
|
||||||
|
| set username and password | yes |
|
||||||
|
| username | a username you like |
|
||||||
|
| password | a password you can remember |
|
||||||
|
| set Wi-Fi | yes |
|
||||||
|
| Wi-Fi SSID | your Wi-Fi name |
|
||||||
|
| Wi-Fi password | your Wi-Fi password |
|
||||||
|
| set timezone | your local timezone |
|
||||||
|
|
||||||
|
1. Create and download `settings.json` file for Inkycal from
|
||||||
|
the [WEB-UI](https://aceinnolab.com/inkycal/ui). Add the modules you want with the add
|
||||||
|
module button.
|
||||||
|
2. Copy the `settings.json` to the flashed microSD card.
|
||||||
|
3. Eject the microSD card from your computer now, insert it in the Raspberry Pi and power the Raspberry Pi.
|
||||||
|
4. Once the green LED has stopped blinking after ~3 minutes, you can connect to your Raspberry Pi via SSH using a SSH
|
||||||
|
Client. We suggest [Termius](https://termius.com/download/windows)
|
||||||
|
on your smartphone. Use the address: `inkycal.local` with the username and password you set earlier. For more
|
||||||
|
detailed instructions, check out the page from
|
||||||
|
the [Raspberry Pi website](https://www.raspberrypi.org/documentation/remote-access/ssh/)
|
||||||
|
5. After connecting via SSH, run the following commands, line by line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo raspi-config --expand-rootfs
|
||||||
|
sudo sed -i s/#dtparam=spi=on/dtparam=spi=on/ /boot/config.txt
|
||||||
|
sudo dpkg-reconfigure tzdata
|
||||||
|
|
||||||
|
# If you have the 12.48" display, these steps are also required:
|
||||||
|
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.71.tar.gz
|
||||||
|
tar zxvf bcm2835-1.71.tar.gz
|
||||||
|
cd bcm2835-1.71/
|
||||||
|
sudo ./configure && sudo make && sudo make check && sudo make install
|
||||||
|
wget https://project-downloads.drogon.net/wiringpi-latest.deb
|
||||||
|
sudo dpkg -i wiringpi-latest.deb
|
||||||
|
|
||||||
|
# If you are using the Raspberry Pi Zero models, you may need to increase the swapfile size to be able to install Inkycal:
|
||||||
|
sudo dphys-swapfile swapoff
|
||||||
|
sudo sed -i -E '/^CONF_SWAPSIZE=/s/=.*/=512/' /etc/dphys-swapfile
|
||||||
|
sudo dphys-swapfile setup
|
||||||
|
sudo dphys-swapfile swapon
|
||||||
|
```
|
||||||
|
|
||||||
|
These commands expand the filesystem, enable SPI and set up the correct timezone on the Raspberry Pi. When running the
|
||||||
|
last command, please select the continent you live in, press enter and then select the capital of the country you live
|
||||||
|
in. Lastly, press enter.
|
||||||
|
|
||||||
|
7. Follow the steps in `Installation` (see below) on how to install Inkycal.
|
||||||
|
|
||||||
|
## Installing Inkycal
|
||||||
|
|
||||||
|
⚠️ Please note that although the developers try to keep the installation as simple as possible, the full installation
|
||||||
|
can sometimes take hours on the Raspberry Pi Zero W and is not guaranteed to go smoothly each time. This is because
|
||||||
|
installing dependencies on the zero w takes a long time and is prone to copy-paste-, permission- and configuration
|
||||||
|
errors.
|
||||||
|
|
||||||
|
ℹ️ **Looking for a shortcut to safe a few hours?** We know about this problem and have spent a signifcant amount of time
|
||||||
|
to prepare a pre-configured image with the latest version of Inkycal for the Raspberry Pi Zero. It comes with the latest
|
||||||
|
version of Inkycal, is fully tested and uses the Raspberry Pi OS Lite as it's base image. You only need to copy your
|
||||||
|
settings.json file, we already took care of the rest, including auto-start at boot, enabling spi and installing all
|
||||||
|
dependencies in advance. Pretty neat right? Check the [sponsor button](https://github.com/sponsors/aceisace) at the very
|
||||||
|
top of the repo to get access to Inkycal-OS-Lite. Alternatively, you can also use the paypal.me link and send the same amount as Github sponsors to get access to InkycalOS-Lite!
|
||||||
|
This will help keep this project growing and cover the ongoing expenses too! Win-win for everyone! 🎊
|
||||||
|
|
||||||
|
### Manual installation
|
||||||
|
|
||||||
|
Run the following steps to install Inkycal. Do **not** use sudo for this, except where explicitly specified.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# the next line is for the Raspberry Pi only
|
||||||
|
sudo apt-get install zlib1g libjpeg-dev libatlas-base-dev rustc libopenjp2-7 python3-dev scons libssl-dev python3-venv python3-pip git libfreetype6-dev wkhtmltopdf
|
||||||
|
cd $HOME
|
||||||
|
git clone --branch main --single-branch https://github.com/aceinnolab/Inkycal
|
||||||
|
cd Inkycal
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install wheel
|
||||||
|
pip install -e ./
|
||||||
|
|
||||||
|
# If you are running on the Raspberry Pi, please install the following too to allow rendering on the display
|
||||||
|
pip install RPi.GPIO==0.7.1 spidev==3.5 gpiozero==2.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Inkycal
|
||||||
|
|
||||||
|
To run Inkycal, type in the following command in the terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd $HOME/Inkycal
|
||||||
|
source venv/bin/activate
|
||||||
|
python3 inky_run.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running on each boot
|
||||||
|
|
||||||
|
To make inkycal run on each boot automatically, you can use crontab. Do not use sudo for this
|
||||||
|
|
||||||
|
```bash
|
||||||
|
(crontab -l ; echo "@reboot sleep 60 && cd $HOME/Inkycal && venv/bin/python inky_run.py &")| crontab -
|
||||||
|
```
|
||||||
|
|
||||||
|
## Updating Inkycal
|
||||||
|
|
||||||
|
To update Inkycal to the latest version, navigate to the Inkycal folder, then run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
Yep. It's actually that simple!
|
||||||
|
But, if you have made changes to Inkycal, those will be overwritten.
|
||||||
|
If that is the case, backup your modified files somewhere else if you need them. Then run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git reset --hard
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
## Uninstalling Inkycal
|
||||||
|
|
||||||
|
We'll miss you, but we don't want to make it hard for you to leave.
|
||||||
|
Just delete the Inkycal folder, and you're good to go!
|
||||||
|
|
||||||
|
Additionally, if you want to reset your crontab file, which runs inkycal at boot, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -r
|
||||||
|
```
|
||||||
|
|
||||||
|
## Modifying Inkycal
|
||||||
|
|
||||||
|
Inkycal now runs in a virtual environment to support more devices than just the Raspberry Pi. Therefore, to make changes
|
||||||
|
to Inkycal, navigate to Inkycal, then run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd $HOME/Inkycal && source venv/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
Then modify the files as needed and experiment with Inkycal.
|
||||||
|
To deactivate the virtual environment, simply run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
deactivate
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3D printed frames
|
||||||
|
|
||||||
|
With your setup being complete at this stage, you may want to 3d-print a case. The following files were shared by our
|
||||||
|
friendly community:
|
||||||
|
[3D-printable case](https://github.com/aceinnolab/Inkycal/wiki/3D-printable-files)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
All sorts of contributions are most welcome and appreciated. To start contributing, please follow
|
||||||
|
the [Contribution Guidelines](https://github.com/aceisace/Inkycal/blob/main/.github/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
The average response time for issues, PRs and emails is usually 24 hours. In some cases, it might be longer. If you want
|
||||||
|
to have some faster responses, please use Discord (link below)
|
||||||
|
|
||||||
|
**P.S:** Don't forget to star and/or watch the repo. For those who have done so already, thank you very much!
|
||||||
|
|
||||||
|
## Join us on Discord!
|
||||||
|
|
||||||
|
We're happy to help, to beginners and developers alike. In fact, you are more likely to get faster support on Discord
|
||||||
|
than on Github.
|
||||||
|
|
||||||
|
<a href="https://discord.gg/sHYKeSM">
|
||||||
|
<img src="https://github.com/aceisace/Inkycal/blob/assets/Repo/discord-logo.png?raw=true" alt="Inkycal chatroom Discord" width=200>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## Sponsoring
|
||||||
|
|
||||||
|
Inkycal relies on sponsors to keep up maintainance, development and bug-fixing. Please consider sponsoring Inkycal via
|
||||||
|
the sponsor button if you are happy with Inkycal.
|
||||||
|
|
||||||
|
We now offer perks depending on the amount contributed for sponsoring, ranging from pre-configured OS images for
|
||||||
|
plug-and-play to development of user-suggested modules. Check out the sponsor page to find out more.
|
||||||
|
If you have been a previous sponsor, please let us know on our Dicord server or by sending an email. We'll send you the
|
||||||
|
perks after confirming 💯
|
||||||
|
|
||||||
|
## As featured on
|
||||||
|
|
||||||
|
* [raspberrypi.com](https://www.raspberrypi.com/news/ashleys-top-five-projects-for-raspberry-pi-first-timers/)
|
||||||
|
* [hackster.io](https://www.hackster.io/news/ace-innovation-lab-s-inkycal-v3-puts-a-raspberry-pi-powered-modular-epaper-dashboard-on-your-desk-b55a83cc0f46)
|
||||||
|
* [raspberryme.com](https://www.raspberryme.com/inkycal-v3-est-un-tableau-de-bord-epaper-alimente-par-raspberry-pi-pour-votre-bureau/)
|
||||||
|
* [adafruit.com](https://blog.adafruit.com/2023/12/19/icymi-python-on-microcontrollers-newsletter-circuitpython-9-alpha-6-released-gpt-via-circuitpython-new-books-and-more-circuitpython-python-micropython-icymi-raspberry_pi/)
|
||||||
|
* [ittagesschau.de](https://www.ittagesschau.de/artikel/inkycal-v3-smartes-display-auf-grundlage-des-raspberry-pi-mit-elektronischem-papier-und-vielen-moglichkeiten_365893)
|
||||||
|
* [makeuseof - fantastic projects using an eink display](http://makeuseof.com/fantastic-projects-using-an-e-ink-display/)
|
||||||
|
* [notebookcheck.com](https://www.notebookcheck.com/Inkycal-V3-Smartes-Display-auf-Grundlage-des-Raspberry-Pi-mit-elektronischem-Papier-und-vielen-Moeglichkeiten.783012.0.html?ref=ittagesschau.de)
|
||||||
|
* [linkedin.com](https://www.linkedin.com/pulse/global-epaper-industry-weekly-bulletin-16epaper-jtcqe?trk=article-ssr-frontend-pulse_more-articles_related-content-card)
|
||||||
|
* [sohu.com](https://www.sohu.com/a/745630839_121311165)
|
||||||
|
* [moreware.com](https://www.moreware.org/wp/blog/2023/12/18/inkycal-v3-dashboard-con-display-e-paper-e-raspberry-pi/)
|
||||||
|
* [Waveshare - additional resources](https://www.waveshare.com/wiki/7.5inch_HD_e-Paper_HAT)
|
||||||
|
* [ereaderpro.co.uk](https://www.ereaderpro.co.uk/blogs/news/e-ink-product-made-in-germany-inkycal-v3)
|
||||||
|
* [cnx-software.com](https://www.cnx-software.com/2023/12/13/inkycal-v3-is-a-raspberry-pi-powered-epaper-dashboard-for-your-desk/)
|
||||||
|
* [magpi.de](https://www.magpi.de/news/maginkcal-ein-kalender-mit-epaper-display-und-raspberry-pi)
|
||||||
|
* [goodreader.com](https://goodereader.com/blog/e-paper/inkycal-v3-is-a-raspberry-pi-powered-e-paper-marvel-for-your-desk)
|
||||||
|
* [goodreader.com](https://goodereader.com/blog/e-paper/five-of-the-most-innovative-e-ink-display-projects?doing_wp_cron=1701869793.2312469482421875000000)
|
||||||
|
* [reddit - Inkycal](https://www.reddit.com/r/InkyCal/)
|
||||||
|
* [schuemann.it](https://schuemann.it/2019/09/11/e-ink-calendar-with-a-raspberry-pi/)
|
||||||
|
* [huernerfuerst.de](https://www.huenerfuerst.de/archives/e-ink-kalender-mit-einem-raspberry-pi-zero-teil-1-was-wird-benoetigt)
|
||||||
|
* [canox.net](https://canox.net/2019/06/raspberry-pi-als-e-ink-kalender/)
|
||||||
|
@ -13,23 +13,6 @@ Display
|
|||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|
||||||
Modules
|
|
||||||
===========================
|
|
||||||
- Agenda
|
|
||||||
|
|
||||||
.. automodule:: inkycal.modules.inkycal_agenda.Agenda
|
|
||||||
:members:
|
|
||||||
|
|
||||||
- Calendar
|
|
||||||
|
|
||||||
.. automodule:: inkycal.modules.inkycal_calendar.Calendar
|
|
||||||
:members:
|
|
||||||
|
|
||||||
- Feeds Module (RSS & Atom)
|
|
||||||
.. automodule:: inkycal.modules.inkycal_feeds.Feeds
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
||||||
Custom functions
|
Custom functions
|
||||||
===========================
|
===========================
|
||||||
.. automodule:: inkycal.custom.functions
|
.. automodule:: inkycal.custom.functions
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
<ul class="current">
|
<ul class="current">
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">About Inkycal</a></li>
|
<li class="toctree-l1 current"><a class="current reference internal" href="#">About Inkycal</a></li>
|
||||||
|
@ -48,7 +48,6 @@
|
|||||||
<ul class="current">
|
<ul class="current">
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
||||||
@ -188,6 +187,8 @@
|
|||||||
<li><a href="inkycal.html#module-inkycal.main">module</a>
|
<li><a href="inkycal.html#module-inkycal.main">module</a>
|
||||||
</li>
|
</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
|
</ul></td>
|
||||||
|
<td style="width: 33%; vertical-align: top;"><ul>
|
||||||
<li>
|
<li>
|
||||||
inkycal.modules.ical_parser
|
inkycal.modules.ical_parser
|
||||||
|
|
||||||
@ -195,34 +196,11 @@
|
|||||||
<li><a href="inkycal.html#module-inkycal.modules.ical_parser">module</a>
|
<li><a href="inkycal.html#module-inkycal.modules.ical_parser">module</a>
|
||||||
</li>
|
</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul></td>
|
|
||||||
<td style="width: 33%; vertical-align: top;"><ul>
|
|
||||||
<li>
|
<li>
|
||||||
inkycal.modules.inky_image
|
inkycal.modules.inky_image
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inky_image">module</a>
|
<li><a href="inkycal.html#module-inkycal.modules.inky_image">module</a>
|
||||||
</li>
|
|
||||||
</ul></li>
|
|
||||||
<li>
|
|
||||||
inkycal.modules.inkycal_agenda.Agenda
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inkycal_agenda.Agenda">module</a>
|
|
||||||
</li>
|
|
||||||
</ul></li>
|
|
||||||
<li>
|
|
||||||
inkycal.modules.inkycal_calendar.Calendar
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inkycal_calendar.Calendar">module</a>
|
|
||||||
</li>
|
|
||||||
</ul></li>
|
|
||||||
<li>
|
|
||||||
inkycal.modules.inkycal_feeds.Feeds
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inkycal_feeds.Feeds">module</a>
|
|
||||||
</li>
|
</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="inkycal.html#inkycal.modules.inky_image.Inkyimage">Inkyimage (class in inkycal.modules.inky_image)</a>
|
<li><a href="inkycal.html#inkycal.modules.inky_image.Inkyimage">Inkyimage (class in inkycal.modules.inky_image)</a>
|
||||||
@ -264,12 +242,6 @@
|
|||||||
<li><a href="inkycal.html#module-inkycal.modules.ical_parser">inkycal.modules.ical_parser</a>
|
<li><a href="inkycal.html#module-inkycal.modules.ical_parser">inkycal.modules.ical_parser</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inky_image">inkycal.modules.inky_image</a>
|
<li><a href="inkycal.html#module-inkycal.modules.inky_image">inkycal.modules.inky_image</a>
|
||||||
</li>
|
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inkycal_agenda.Agenda">inkycal.modules.inkycal_agenda.Agenda</a>
|
|
||||||
</li>
|
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inkycal_calendar.Calendar">inkycal.modules.inkycal_calendar.Calendar</a>
|
|
||||||
</li>
|
|
||||||
<li><a href="inkycal.html#module-inkycal.modules.inkycal_feeds.Feeds">inkycal.modules.inkycal_feeds.Feeds</a>
|
|
||||||
</li>
|
</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul></td>
|
</ul></td>
|
||||||
|
@ -48,7 +48,6 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
||||||
@ -91,7 +90,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a><ul>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="inkycal.html#inkycal.custom.functions.auto_fontsize"><code class="docutils literal notranslate"><span class="pre">auto_fontsize()</span></code></a></li>
|
<li class="toctree-l2"><a class="reference internal" href="inkycal.html#inkycal.custom.functions.auto_fontsize"><code class="docutils literal notranslate"><span class="pre">auto_fontsize()</span></code></a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="inkycal.html#inkycal.custom.functions.draw_border"><code class="docutils literal notranslate"><span class="pre">draw_border()</span></code></a></li>
|
<li class="toctree-l2"><a class="reference internal" href="inkycal.html#inkycal.custom.functions.draw_border"><code class="docutils literal notranslate"><span class="pre">draw_border()</span></code></a></li>
|
||||||
|
@ -58,7 +58,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="#module-inkycal.custom.functions">Custom functions</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="#module-inkycal.custom.functions">Custom functions</a><ul>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#inkycal.custom.functions.auto_fontsize"><code class="docutils literal notranslate"><span class="pre">auto_fontsize()</span></code></a></li>
|
<li class="toctree-l2"><a class="reference internal" href="#inkycal.custom.functions.auto_fontsize"><code class="docutils literal notranslate"><span class="pre">auto_fontsize()</span></code></a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#inkycal.custom.functions.draw_border"><code class="docutils literal notranslate"><span class="pre">draw_border()</span></code></a></li>
|
<li class="toctree-l2"><a class="reference internal" href="#inkycal.custom.functions.draw_border"><code class="docutils literal notranslate"><span class="pre">draw_border()</span></code></a></li>
|
||||||
@ -195,24 +194,6 @@ rendering images and calibrating the E-Paper display</p>
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</section>
|
</section>
|
||||||
<section id="modules">
|
|
||||||
<h1>Modules<a class="headerlink" href="#modules" title="Link to this heading"></a></h1>
|
|
||||||
<ul class="simple">
|
|
||||||
<li><p>Agenda</p></li>
|
|
||||||
</ul>
|
|
||||||
<p id="module-inkycal.modules.inkycal_agenda.Agenda">Agenda class
|
|
||||||
Create agenda and show events from given icalendars</p>
|
|
||||||
<ul class="simple">
|
|
||||||
<li><p>Calendar</p></li>
|
|
||||||
</ul>
|
|
||||||
<p id="module-inkycal.modules.inkycal_calendar.Calendar">Calendar class
|
|
||||||
Create monthly calendar and show events from given icalendars</p>
|
|
||||||
<ul class="simple">
|
|
||||||
<li><p>Feeds Module (RSS & Atom)</p></li>
|
|
||||||
</ul>
|
|
||||||
<p id="module-inkycal.modules.inkycal_feeds.Feeds">RSS class
|
|
||||||
parses rss/atom feeds from given urls</p>
|
|
||||||
</section>
|
|
||||||
<section id="module-inkycal.custom.functions">
|
<section id="module-inkycal.custom.functions">
|
||||||
<span id="custom-functions"></span><h1>Custom functions<a class="headerlink" href="#module-inkycal.custom.functions" title="Link to this heading"></a></h1>
|
<span id="custom-functions"></span><h1>Custom functions<a class="headerlink" href="#module-inkycal.custom.functions" title="Link to this heading"></a></h1>
|
||||||
<p>Inkycal custom-functions for ease-of-use</p>
|
<p>Inkycal custom-functions for ease-of-use</p>
|
||||||
@ -567,6 +548,7 @@ white pixels.</p>
|
|||||||
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="s1">'bwr'</span> <span class="c1"># black-white-red</span>
|
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="s1">'bwr'</span> <span class="c1"># black-white-red</span>
|
||||||
<span class="gp">>>> </span><span class="s1">'bwy'</span> <span class="c1"># black-white-yellow</span>
|
<span class="gp">>>> </span><span class="s1">'bwy'</span> <span class="c1"># black-white-yellow</span>
|
||||||
<span class="gp">>>> </span><span class="s1">'bw'</span> <span class="c1"># black-white</span>
|
<span class="gp">>>> </span><span class="s1">'bw'</span> <span class="c1"># black-white</span>
|
||||||
|
<span class="gp">>>> </span><span class="s1">'16gray'</span> <span class="c1"># 16 shades of gray</span>
|
||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
</dd></dl>
|
</dd></dl>
|
||||||
|
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
@ -49,7 +49,6 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
||||||
@ -122,21 +121,6 @@
|
|||||||
<td>   
|
<td>   
|
||||||
<a href="inkycal.html#module-inkycal.modules.inky_image"><code class="xref">inkycal.modules.inky_image</code></a></td><td>
|
<a href="inkycal.html#module-inkycal.modules.inky_image"><code class="xref">inkycal.modules.inky_image</code></a></td><td>
|
||||||
<em></em></td></tr>
|
<em></em></td></tr>
|
||||||
<tr class="cg-1">
|
|
||||||
<td></td>
|
|
||||||
<td>   
|
|
||||||
<a href="inkycal.html#module-inkycal.modules.inkycal_agenda.Agenda"><code class="xref">inkycal.modules.inkycal_agenda.Agenda</code></a></td><td>
|
|
||||||
<em></em></td></tr>
|
|
||||||
<tr class="cg-1">
|
|
||||||
<td></td>
|
|
||||||
<td>   
|
|
||||||
<a href="inkycal.html#module-inkycal.modules.inkycal_calendar.Calendar"><code class="xref">inkycal.modules.inkycal_calendar.Calendar</code></a></td><td>
|
|
||||||
<em></em></td></tr>
|
|
||||||
<tr class="cg-1">
|
|
||||||
<td></td>
|
|
||||||
<td>   
|
|
||||||
<a href="inkycal.html#module-inkycal.modules.inkycal_feeds.Feeds"><code class="xref">inkycal.modules.inkycal_feeds.Feeds</code></a></td><td>
|
|
||||||
<em></em></td></tr>
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
<ul class="current">
|
<ul class="current">
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html">Inkycal</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.display.Display">Display</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#modules">Modules</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.custom.functions">Custom functions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="inkycal.html#module-inkycal.modules.ical_parser">Helper classes</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="about.html">About Inkycal</a></li>
|
||||||
|
File diff suppressed because one or more lines are too long
@ -13,23 +13,6 @@ Display
|
|||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|
||||||
Modules
|
|
||||||
===========================
|
|
||||||
- Agenda
|
|
||||||
|
|
||||||
.. automodule:: inkycal.modules.inkycal_agenda.Agenda
|
|
||||||
:members:
|
|
||||||
|
|
||||||
- Calendar
|
|
||||||
|
|
||||||
.. automodule:: inkycal.modules.inkycal_calendar.Calendar
|
|
||||||
:members:
|
|
||||||
|
|
||||||
- Feeds Module (RSS & Atom)
|
|
||||||
.. automodule:: inkycal.modules.inkycal_feeds.Feeds
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
||||||
Custom functions
|
Custom functions
|
||||||
===========================
|
===========================
|
||||||
.. automodule:: inkycal.custom.functions
|
.. automodule:: inkycal.custom.functions
|
||||||
|
@ -8,6 +8,7 @@ import os
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
import PIL
|
||||||
import requests
|
import requests
|
||||||
from PIL import ImageFont, ImageDraw, Image
|
from PIL import ImageFont, ImageDraw, Image
|
||||||
|
|
||||||
@ -335,7 +336,7 @@ def draw_border(image, xy, size, radius=5, thickness=1, shrinkage=(0.1, 0.1)):
|
|||||||
draw.arc((c7, c8), 90, 180, fill=colour, width=thickness)
|
draw.arc((c7, c8), 90, 180, fill=colour, width=thickness)
|
||||||
|
|
||||||
|
|
||||||
def draw_border_2(im: Image, xy: tuple, size: tuple, radius: int):
|
def draw_border_2(im: PIL.Image, xy: tuple, size: tuple, radius: int):
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
x, y = xy
|
x, y = xy
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#!python3
|
|
||||||
"""
|
"""
|
||||||
Inkycal custom Exceptions
|
Inkycal custom Exceptions
|
||||||
"""
|
"""
|
||||||
|
@ -2,18 +2,21 @@
|
|||||||
Inkycal ePaper driving functions
|
Inkycal ePaper driving functions
|
||||||
Copyright by aceisace
|
Copyright by aceisace
|
||||||
"""
|
"""
|
||||||
import os
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
||||||
|
import PIL
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from inkycal.custom import top_level
|
from inkycal.custom import top_level
|
||||||
import glob
|
|
||||||
|
|
||||||
def import_driver(model):
|
def import_driver(model):
|
||||||
return import_module(f'inkycal.display.drivers.{model}')
|
return import_module(f'inkycal.display.drivers.{model}')
|
||||||
|
|
||||||
|
|
||||||
class Display:
|
class Display:
|
||||||
"""Display class for inkycal
|
"""Display class for inkycal
|
||||||
|
|
||||||
@ -44,7 +47,14 @@ class Display:
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise Exception('SPI could not be found. Please check if SPI is enabled')
|
raise Exception('SPI could not be found. Please check if SPI is enabled')
|
||||||
|
|
||||||
def render(self, im_black: Image, im_colour:Image or None=None) -> None:
|
|
||||||
|
def test(self) -> None:
|
||||||
|
"""Test the display by showing a test image"""
|
||||||
|
# TODO implement test image
|
||||||
|
raise NotImplementedError("Devs were too lazy again, sorry, please try again later")
|
||||||
|
|
||||||
|
|
||||||
|
def render(self, im_black: PIL.Image, im_colour: PIL.Image or None=None) -> None:
|
||||||
"""Renders an image on the selected E-Paper display.
|
"""Renders an image on the selected E-Paper display.
|
||||||
|
|
||||||
Initlializes the E-Paper display, sends image data and executes command
|
Initlializes the E-Paper display, sends image data and executes command
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#!python3
|
|
||||||
"""
|
"""
|
||||||
10.3" driver class
|
10.3" driver class
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
from inkycal.custom import image_folder, top_level
|
|
||||||
from os.path import exists
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
from inkycal.custom import image_folder, top_level
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 1872
|
EPD_WIDTH = 1872
|
||||||
EPD_HEIGHT = 1404
|
EPD_HEIGHT = 1404
|
||||||
@ -19,6 +19,7 @@ driver_dir = top_level + '/inkycal/display/drivers/parallel_drivers/'
|
|||||||
|
|
||||||
command = f'sudo {driver_dir}epd -{VCOM} 0 {image_folder + "canvas.bmp"}'
|
command = f'sudo {driver_dir}epd -{VCOM} 0 {image_folder + "canvas.bmp"}'
|
||||||
|
|
||||||
|
|
||||||
class EPD:
|
class EPD:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -38,7 +39,7 @@ class EPD:
|
|||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
"""ad-hoc"""
|
"""ad-hoc"""
|
||||||
image = image.rotate(90, expand=True)
|
image = image.rotate(90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
image.convert('RGB').save(image_folder + 'canvas.bmp', 'BMP')
|
image.convert('RGB').save(image_folder + 'canvas.bmp', 'BMP')
|
||||||
command = f'sudo {driver_dir}epd -{VCOM} 0 {image_folder + "canvas.bmp"}'
|
command = f'sudo {driver_dir}epd -{VCOM} 0 {image_folder + "canvas.bmp"}'
|
||||||
print(command)
|
print(command)
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
#!python3
|
|
||||||
"""
|
"""
|
||||||
7.8" parallel driver class
|
7.8" parallel driver class
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
|
|
||||||
from inkycal.custom import image_folder, top_level
|
from inkycal.custom import image_folder, top_level
|
||||||
from os.path import exists
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 1872
|
EPD_WIDTH = 1872
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
#!python3
|
|
||||||
"""
|
"""
|
||||||
9.7" driver class
|
9.7" driver class
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
|
|
||||||
from inkycal.custom import image_folder, top_level
|
from inkycal.custom import image_folder, top_level
|
||||||
from os.path import exists
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 1200
|
EPD_WIDTH = 1200
|
||||||
|
@ -1,42 +1,43 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd5in83b_V2.py
|
* | File : epd5in83b_V2.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V1.1
|
* | This version: V1.1
|
||||||
# * | Date : 2022-08-10
|
* | Date : 2022-08-10
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from . import epdconfig
|
from . import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 648
|
EPD_WIDTH = 648
|
||||||
EPD_HEIGHT = 480
|
EPD_HEIGHT = 480
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class EPD:
|
class EPD:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reset_pin = epdconfig.RST_PIN
|
self.reset_pin = epdconfig.RST_PIN
|
||||||
@ -77,7 +78,7 @@ class EPD:
|
|||||||
def ReadBusy(self):
|
def ReadBusy(self):
|
||||||
logger.debug("e-Paper busy")
|
logger.debug("e-Paper busy")
|
||||||
self.send_command(0X71)
|
self.send_command(0X71)
|
||||||
while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
|
while (epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
|
||||||
self.send_command(0X71)
|
self.send_command(0X71)
|
||||||
epdconfig.delay_ms(200)
|
epdconfig.delay_ms(200)
|
||||||
logger.debug("e-Paper busy release")
|
logger.debug("e-Paper busy release")
|
||||||
@ -88,59 +89,59 @@ class EPD:
|
|||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
self.send_command(0x01) #POWER SETTING
|
self.send_command(0x01) # POWER SETTING
|
||||||
self.send_data (0x07)
|
self.send_data(0x07)
|
||||||
self.send_data (0x07) #VGH=20V,VGL=-20V
|
self.send_data(0x07) # VGH=20V,VGL=-20V
|
||||||
self.send_data (0x3f) #VDH=15V
|
self.send_data(0x3f) # VDH=15V
|
||||||
self.send_data (0x3f) #VDL=-15V
|
self.send_data(0x3f) # VDL=-15V
|
||||||
|
|
||||||
self.send_command(0x04) #POWER ON
|
self.send_command(0x04) # POWER ON
|
||||||
epdconfig.delay_ms(100)
|
epdconfig.delay_ms(100)
|
||||||
self.ReadBusy() #waiting for the electronic paper IC to release the idle signal
|
self.ReadBusy() # waiting for the electronic paper IC to release the idle signal
|
||||||
|
|
||||||
self.send_command(0X00) #PANNEL SETTING
|
self.send_command(0X00) # PANNEL SETTING
|
||||||
self.send_data(0x0F) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
self.send_data(0x0F) # KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
||||||
|
|
||||||
self.send_command(0x61) #tres
|
self.send_command(0x61) # tres
|
||||||
self.send_data (0x02) #source 648
|
self.send_data(0x02) # source 648
|
||||||
self.send_data (0x88)
|
self.send_data(0x88)
|
||||||
self.send_data (0x01) #gate 480
|
self.send_data(0x01) # gate 480
|
||||||
self.send_data (0xe0)
|
self.send_data(0xe0)
|
||||||
|
|
||||||
self.send_command(0X15)
|
self.send_command(0X15)
|
||||||
self.send_data(0x00)
|
self.send_data(0x00)
|
||||||
|
|
||||||
self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
|
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
|
||||||
self.send_data(0x11)
|
self.send_data(0x11)
|
||||||
self.send_data(0x07)
|
self.send_data(0x07)
|
||||||
|
|
||||||
self.send_command(0X60) #TCON SETTING
|
self.send_command(0X60) # TCON SETTING
|
||||||
self.send_data(0x22)
|
self.send_data(0x22)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
|
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||||
buf = [0xFF] * (int(self.width/8) * self.height)
|
buf = [0xFF] * (int(self.width / 8) * self.height)
|
||||||
image_monocolor = image.convert('1')
|
image_monocolor = image.convert('1')
|
||||||
imwidth, imheight = image_monocolor.size
|
imwidth, imheight = image_monocolor.size
|
||||||
pixels = image_monocolor.load()
|
pixels = image_monocolor.load()
|
||||||
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
||||||
if(imwidth == self.width and imheight == self.height):
|
if (imwidth == self.width and imheight == self.height):
|
||||||
logger.debug("Vertical")
|
logger.debug("Vertical")
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
# Set the bits for the column of pixels at the current position.
|
# Set the bits for the column of pixels at the current position.
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||||
elif(imwidth == self.height and imheight == self.width):
|
elif (imwidth == self.height and imheight == self.width):
|
||||||
logger.debug("Horizontal")
|
logger.debug("Horizontal")
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
newx = y
|
newx = y
|
||||||
newy = self.height - x - 1
|
newy = self.height - x - 1
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
|
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, imageblack, imagered):
|
def display(self, imageblack, imagered):
|
||||||
@ -170,9 +171,9 @@ class EPD:
|
|||||||
self.ReadBusy()
|
self.ReadBusy()
|
||||||
|
|
||||||
def sleep(self):
|
def sleep(self):
|
||||||
self.send_command(0X02) # power off
|
self.send_command(0X02) # power off
|
||||||
self.ReadBusy()
|
self.ReadBusy()
|
||||||
self.send_command(0X07) # deep sleep
|
self.send_command(0X07) # deep sleep
|
||||||
self.send_data(0xA5)
|
self.send_data(0xA5)
|
||||||
|
|
||||||
epdconfig.delay_ms(2000)
|
epdconfig.delay_ms(2000)
|
||||||
|
@ -1,57 +1,59 @@
|
|||||||
# /*****************************************************************************
|
"""
|
||||||
# * | File : epd12in48.py
|
* | File : epd12in48.py
|
||||||
# * | Author : Waveshare electrices
|
* | Author : Waveshare electrices
|
||||||
# * | Function : Hardware underlying interface
|
* | Function : Hardware underlying interface
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V1.0
|
* | This version: V1.0
|
||||||
# * | Date : 2019-11-01
|
* | Date : 2019-11-01
|
||||||
# * | Info :
|
* | Info :
|
||||||
# ******************************************************************************/
|
******************************************************************************/
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig_12_in_48 as epdconfig
|
from inkycal.display.drivers import epdconfig_12_in_48 as epdconfig
|
||||||
|
|
||||||
EPD_WIDTH = 1304
|
EPD_WIDTH = 1304
|
||||||
EPD_HEIGHT = 984
|
EPD_HEIGHT = 984
|
||||||
|
|
||||||
|
|
||||||
class EPD(object):
|
class EPD(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.width = EPD_WIDTH
|
self.width = EPD_WIDTH
|
||||||
self.height = EPD_HEIGHT
|
self.height = EPD_HEIGHT
|
||||||
|
|
||||||
self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN
|
self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN
|
||||||
self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN
|
self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN
|
||||||
self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN
|
self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN
|
||||||
self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN
|
self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN
|
||||||
|
|
||||||
self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN
|
self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN
|
||||||
self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN
|
self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN
|
||||||
|
|
||||||
self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN
|
self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN
|
||||||
self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN
|
self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN
|
||||||
|
|
||||||
self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN
|
self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN
|
||||||
self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN
|
self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN
|
||||||
self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN
|
self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN
|
||||||
self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN
|
self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
print("EPD init...")
|
print("EPD init...")
|
||||||
@ -63,9 +65,9 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
self.Reset()
|
self.Reset()
|
||||||
|
|
||||||
#panel setting
|
# panel setting
|
||||||
self.M1_SendCommand(0x00)
|
self.M1_SendCommand(0x00)
|
||||||
self.M1_SendData(0x1f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
self.M1_SendData(0x1f) # KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
||||||
self.S1_SendCommand(0x00)
|
self.S1_SendCommand(0x00)
|
||||||
self.S1_SendData(0x1f)
|
self.S1_SendData(0x1f)
|
||||||
self.M2_SendCommand(0x00)
|
self.M2_SendCommand(0x00)
|
||||||
@ -75,9 +77,9 @@ class EPD(object):
|
|||||||
|
|
||||||
# booster soft start
|
# booster soft start
|
||||||
self.M1_SendCommand(0x06)
|
self.M1_SendCommand(0x06)
|
||||||
self.M1_SendData(0x17) #A
|
self.M1_SendData(0x17) # A
|
||||||
self.M1_SendData(0x17) #B
|
self.M1_SendData(0x17) # B
|
||||||
self.M1_SendData(0x39) #C
|
self.M1_SendData(0x39) # C
|
||||||
self.M1_SendData(0x17)
|
self.M1_SendData(0x17)
|
||||||
self.M2_SendCommand(0x06)
|
self.M2_SendCommand(0x06)
|
||||||
self.M2_SendData(0x17)
|
self.M2_SendData(0x17)
|
||||||
@ -85,123 +87,124 @@ class EPD(object):
|
|||||||
self.M2_SendData(0x39)
|
self.M2_SendData(0x39)
|
||||||
self.M2_SendData(0x17)
|
self.M2_SendData(0x17)
|
||||||
|
|
||||||
#resolution setting
|
# resolution setting
|
||||||
self.M1_SendCommand(0x61)
|
self.M1_SendCommand(0x61)
|
||||||
self.M1_SendData(0x02)
|
self.M1_SendData(0x02)
|
||||||
self.M1_SendData(0x88) #source 648
|
self.M1_SendData(0x88) # source 648
|
||||||
self.M1_SendData(0x01) #gate 492
|
self.M1_SendData(0x01) # gate 492
|
||||||
self.M1_SendData(0xEC)
|
self.M1_SendData(0xEC)
|
||||||
self.S1_SendCommand(0x61)
|
self.S1_SendCommand(0x61)
|
||||||
self.S1_SendData(0x02)
|
self.S1_SendData(0x02)
|
||||||
self.S1_SendData(0x90) #source 656
|
self.S1_SendData(0x90) # source 656
|
||||||
self.S1_SendData(0x01) #gate 492
|
self.S1_SendData(0x01) # gate 492
|
||||||
self.S1_SendData(0xEC)
|
self.S1_SendData(0xEC)
|
||||||
self.M2_SendCommand(0x61)
|
self.M2_SendCommand(0x61)
|
||||||
self.M2_SendData(0x02)
|
self.M2_SendData(0x02)
|
||||||
self.M2_SendData(0x90) #source 656
|
self.M2_SendData(0x90) # source 656
|
||||||
self.M2_SendData(0x01) #gate 492
|
self.M2_SendData(0x01) # gate 492
|
||||||
self.M2_SendData(0xEC)
|
self.M2_SendData(0xEC)
|
||||||
self.S2_SendCommand(0x61)
|
self.S2_SendCommand(0x61)
|
||||||
self.S2_SendData(0x02)
|
self.S2_SendData(0x02)
|
||||||
self.S2_SendData(0x88) #source 648
|
self.S2_SendData(0x88) # source 648
|
||||||
self.S2_SendData(0x01) #gate 492
|
self.S2_SendData(0x01) # gate 492
|
||||||
self.S2_SendData(0xEC)
|
self.S2_SendData(0xEC)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x15) #DUSPI
|
self.M1S1M2S2_SendCommand(0x15) # DUSPI
|
||||||
self.M1S1M2S2_SendData(0x20)
|
self.M1S1M2S2_SendData(0x20)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting
|
self.M1S1M2S2_SendCommand(0x50) # Vcom and data interval setting
|
||||||
self.M1S1M2S2_SendData(0x21) #Border KW
|
self.M1S1M2S2_SendData(0x21) # Border KW
|
||||||
self.M1S1M2S2_SendData(0x07)
|
self.M1S1M2S2_SendData(0x07)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x60) #TCON
|
self.M1S1M2S2_SendCommand(0x60) # TCON
|
||||||
self.M1S1M2S2_SendData(0x22)
|
self.M1S1M2S2_SendData(0x22)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0xE3)
|
self.M1S1M2S2_SendCommand(0xE3)
|
||||||
self.M1S1M2S2_SendData(0x00)
|
self.M1S1M2S2_SendData(0x00)
|
||||||
|
|
||||||
#temperature
|
# temperature
|
||||||
temp = self.M1_ReadTemperature()
|
temp = self.M1_ReadTemperature()
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0xe0) #Cascade setting
|
self.M1S1M2S2_SendCommand(0xe0) # Cascade setting
|
||||||
self.M1S1M2S2_SendData(0x03)
|
self.M1S1M2S2_SendData(0x03)
|
||||||
self.M1S1M2S2_SendCommand(0xe5) #Force temperature
|
self.M1S1M2S2_SendCommand(0xe5) # Force temperature
|
||||||
self.M1S1M2S2_SendData(temp)
|
self.M1S1M2S2_SendData(temp)
|
||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||||
buf = [0xFF] * (int(self.width/8) * self.height)
|
buf = [0xFF] * (int(self.width / 8) * self.height)
|
||||||
image_monocolor = image.convert('1')
|
image_monocolor = image.convert('1')
|
||||||
imwidth, imheight = image_monocolor.size
|
imwidth, imheight = image_monocolor.size
|
||||||
pixels = image_monocolor.load()
|
pixels = image_monocolor.load()
|
||||||
|
|
||||||
if(imwidth == self.width and imheight == self.height):
|
if (imwidth == self.width and imheight == self.height):
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
# Set the bits for the column of pixels at the current position.
|
# Set the bits for the column of pixels at the current position.
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||||
elif(imwidth == self.height and imheight == self.width):
|
elif (imwidth == self.height and imheight == self.width):
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
newx = y
|
newx = y
|
||||||
newy = self.height - x - 1
|
newy = self.height - x - 1
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
|
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, buf):
|
def display(self, buf):
|
||||||
|
|
||||||
#M1 part 648*492
|
# M1 part 648*492
|
||||||
self.M1_SendCommand(0x13)
|
self.M1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(buf[y*163 + x])
|
self.M1_SendData(buf[y * 163 + x])
|
||||||
|
|
||||||
#S1 part 656*492
|
# S1 part 656*492
|
||||||
self.S1_SendCommand(0x13)
|
self.S1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(buf[y*163 + x])
|
self.S1_SendData(buf[y * 163 + x])
|
||||||
|
|
||||||
#M2 part 656*492
|
# M2 part 656*492
|
||||||
self.M2_SendCommand(0x13)
|
self.M2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(buf[y*163 + x])
|
self.M2_SendData(buf[y * 163 + x])
|
||||||
|
|
||||||
#S2 part 648*492
|
# S2 part 648*492
|
||||||
self.S2_SendCommand(0x13)
|
self.S2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(buf[y*163 + x])
|
self.S2_SendData(buf[y * 163 + x])
|
||||||
|
|
||||||
self.TurnOnDisplay()
|
self.TurnOnDisplay()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""Clear contents of image buffer"""
|
"""Clear contents of image buffer"""
|
||||||
self.M1_SendCommand(0x13)
|
self.M1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(0xff)
|
self.M1_SendData(0xff)
|
||||||
|
|
||||||
self.S1_SendCommand(0x13)
|
self.S1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(0xff)
|
self.S1_SendData(0xff)
|
||||||
|
|
||||||
self.M2_SendCommand(0x13)
|
self.M2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(0xff)
|
self.M2_SendData(0xff)
|
||||||
|
|
||||||
self.S2_SendCommand(0x13)
|
self.S2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(0xff)
|
self.S2_SendData(0xff)
|
||||||
self.TurnOnDisplay()
|
self.TurnOnDisplay()
|
||||||
|
|
||||||
""" M1S1M2S2 Write register address and data """
|
""" M1S1M2S2 Write register address and data """
|
||||||
|
|
||||||
def M1S1M2S2_SendCommand(self, cmd):
|
def M1S1M2S2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
@ -231,6 +234,7 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
""" M1M2 Write register address and data """
|
""" M1M2 Write register address and data """
|
||||||
|
|
||||||
def M1M2_SendCommand(self, cmd):
|
def M1M2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
@ -250,13 +254,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
""" S2 Write register address and data """
|
""" S2 Write register address and data """
|
||||||
|
|
||||||
def S2_SendCommand(self, cmd):
|
def S2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
|
|
||||||
def S2_SendData(self, val):
|
def S2_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
||||||
@ -264,6 +268,7 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
""" M2 Write register address and data """
|
""" M2 Write register address and data """
|
||||||
|
|
||||||
def M2_SendCommand(self, cmd):
|
def M2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
||||||
@ -277,6 +282,7 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
""" S1 Write register address and data """
|
""" S1 Write register address and data """
|
||||||
|
|
||||||
def S1_SendCommand(self, cmd):
|
def S1_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
||||||
@ -290,6 +296,7 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
||||||
|
|
||||||
""" M1 Write register address and data """
|
""" M1 Write register address and data """
|
||||||
|
|
||||||
def M1_SendCommand(self, cmd):
|
def M1_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
||||||
@ -323,7 +330,6 @@ class EPD(object):
|
|||||||
print("module_exit")
|
print("module_exit")
|
||||||
epdconfig.module_exit()
|
epdconfig.module_exit()
|
||||||
|
|
||||||
|
|
||||||
def TurnOnDisplay(self):
|
def TurnOnDisplay(self):
|
||||||
self.M1M2_SendCommand(0x04)
|
self.M1M2_SendCommand(0x04)
|
||||||
time.sleep(0.3)
|
time.sleep(0.3)
|
||||||
@ -333,49 +339,49 @@ class EPD(object):
|
|||||||
self.M2_ReadBusy()
|
self.M2_ReadBusy()
|
||||||
self.S2_ReadBusy()
|
self.S2_ReadBusy()
|
||||||
|
|
||||||
#Busy
|
# Busy
|
||||||
def M1_ReadBusy(self):
|
def M1_ReadBusy(self):
|
||||||
self.M1_SendCommand(0x71)
|
self.M1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
print("M1_ReadBusy")
|
print("M1_ReadBusy")
|
||||||
while(busy):
|
while (busy):
|
||||||
self.M1_SendCommand(0x71)
|
self.M1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def M2_ReadBusy(self):
|
def M2_ReadBusy(self):
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
print("M2_ReadBusy")
|
print("M2_ReadBusy")
|
||||||
while(busy):
|
while (busy):
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
||||||
busy =not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def S1_ReadBusy(self):
|
def S1_ReadBusy(self):
|
||||||
self.S1_SendCommand(0x71)
|
self.S1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
print("s1_ReadBusy")
|
print("s1_ReadBusy")
|
||||||
while(busy):
|
while (busy):
|
||||||
self.S1_SendCommand(0x71)
|
self.S1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def S2_ReadBusy(self):
|
def S2_ReadBusy(self):
|
||||||
self.S2_SendCommand(0x71)
|
self.S2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
print("S2_ReadBusy")
|
print("S2_ReadBusy")
|
||||||
while(busy):
|
while (busy):
|
||||||
self.S2_SendCommand(0x71)
|
self.S2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def M1_ReadTemperature(self):
|
def M1_ReadTemperature(self):
|
||||||
@ -393,7 +399,7 @@ class EPD(object):
|
|||||||
|
|
||||||
# temp = epdconfig.spi_readbyte(0x00)
|
# temp = epdconfig.spi_readbyte(0x00)
|
||||||
temp = 25
|
temp = 25
|
||||||
print("Read Temperature Reg:%d"%temp)
|
print("Read Temperature Reg:%d" % temp)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
||||||
# temp =0x29
|
# temp =0x29
|
||||||
return temp
|
return temp
|
||||||
|
@ -1,57 +1,59 @@
|
|||||||
# /*****************************************************************************
|
"""
|
||||||
# * | File : epd12in48.py
|
* | File : epd12in48.py
|
||||||
# * | Author : Waveshare electrices
|
* | Author : Waveshare electrices
|
||||||
# * | Function : Hardware underlying interface
|
* | Function : Hardware underlying interface
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V1.0
|
* | This version: V1.0
|
||||||
# * | Date : 2019-11-01
|
* | Date : 2019-11-01
|
||||||
# * | Info :
|
* | Info :
|
||||||
# ******************************************************************************/
|
******************************************************************************/
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig_12_in_48 as epdconfig
|
from inkycal.display.drivers import epdconfig_12_in_48 as epdconfig
|
||||||
|
|
||||||
EPD_WIDTH = 1304
|
EPD_WIDTH = 1304
|
||||||
EPD_HEIGHT = 984
|
EPD_HEIGHT = 984
|
||||||
|
|
||||||
|
|
||||||
class EPD(object):
|
class EPD(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.width = EPD_WIDTH
|
self.width = EPD_WIDTH
|
||||||
self.height = EPD_HEIGHT
|
self.height = EPD_HEIGHT
|
||||||
|
|
||||||
self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN
|
self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN
|
||||||
self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN
|
self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN
|
||||||
self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN
|
self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN
|
||||||
self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN
|
self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN
|
||||||
|
|
||||||
self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN
|
self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN
|
||||||
self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN
|
self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN
|
||||||
|
|
||||||
self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN
|
self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN
|
||||||
self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN
|
self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN
|
||||||
|
|
||||||
self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN
|
self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN
|
||||||
self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN
|
self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN
|
||||||
self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN
|
self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN
|
||||||
self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN
|
self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
print("EPD init...")
|
print("EPD init...")
|
||||||
@ -63,9 +65,9 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
self.Reset()
|
self.Reset()
|
||||||
|
|
||||||
#panel setting
|
# panel setting
|
||||||
self.M1_SendCommand(0x00)
|
self.M1_SendCommand(0x00)
|
||||||
self.M1_SendData(0x2f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
self.M1_SendData(0x2f) # KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
||||||
self.S1_SendCommand(0x00)
|
self.S1_SendCommand(0x00)
|
||||||
self.S1_SendData(0x2f)
|
self.S1_SendData(0x2f)
|
||||||
self.M2_SendCommand(0x00)
|
self.M2_SendCommand(0x00)
|
||||||
@ -76,22 +78,22 @@ class EPD(object):
|
|||||||
# POWER SETTING
|
# POWER SETTING
|
||||||
self.M1_SendCommand(0x01)
|
self.M1_SendCommand(0x01)
|
||||||
self.M1_SendData(0x07)
|
self.M1_SendData(0x07)
|
||||||
self.M1_SendData(0x17) # VGH=20V,VGL=-20V
|
self.M1_SendData(0x17) # VGH=20V,VGL=-20V
|
||||||
self.M1_SendData(0x3F) # VDH=15V
|
self.M1_SendData(0x3F) # VDH=15V
|
||||||
self.M1_SendData(0x3F) # VDL=-15V
|
self.M1_SendData(0x3F) # VDL=-15V
|
||||||
self.M1_SendData(0x0d)
|
self.M1_SendData(0x0d)
|
||||||
self.M2_SendCommand(0x01)
|
self.M2_SendCommand(0x01)
|
||||||
self.M2_SendData(0x07)
|
self.M2_SendData(0x07)
|
||||||
self.M2_SendData(0x17) # VGH=20V,VGL=-20V
|
self.M2_SendData(0x17) # VGH=20V,VGL=-20V
|
||||||
self.M2_SendData(0x3F) # VDH=15V
|
self.M2_SendData(0x3F) # VDH=15V
|
||||||
self.M2_SendData(0x3F) # VDL=-15V
|
self.M2_SendData(0x3F) # VDL=-15V
|
||||||
self.M2_SendData(0x0d)
|
self.M2_SendData(0x0d)
|
||||||
|
|
||||||
# booster soft start
|
# booster soft start
|
||||||
self.M1_SendCommand(0x06)
|
self.M1_SendCommand(0x06)
|
||||||
self.M1_SendData(0x17) #A
|
self.M1_SendData(0x17) # A
|
||||||
self.M1_SendData(0x17) #B
|
self.M1_SendData(0x17) # B
|
||||||
self.M1_SendData(0x39) #C
|
self.M1_SendData(0x39) # C
|
||||||
self.M1_SendData(0x17)
|
self.M1_SendData(0x17)
|
||||||
self.M2_SendCommand(0x06)
|
self.M2_SendCommand(0x06)
|
||||||
self.M2_SendData(0x17)
|
self.M2_SendData(0x17)
|
||||||
@ -99,44 +101,44 @@ class EPD(object):
|
|||||||
self.M2_SendData(0x39)
|
self.M2_SendData(0x39)
|
||||||
self.M2_SendData(0x17)
|
self.M2_SendData(0x17)
|
||||||
|
|
||||||
#resolution setting
|
# resolution setting
|
||||||
self.M1_SendCommand(0x61)
|
self.M1_SendCommand(0x61)
|
||||||
self.M1_SendData(0x02)
|
self.M1_SendData(0x02)
|
||||||
self.M1_SendData(0x88) #source 648
|
self.M1_SendData(0x88) # source 648
|
||||||
self.M1_SendData(0x01) #gate 492
|
self.M1_SendData(0x01) # gate 492
|
||||||
self.M1_SendData(0xEC)
|
self.M1_SendData(0xEC)
|
||||||
self.S1_SendCommand(0x61)
|
self.S1_SendCommand(0x61)
|
||||||
self.S1_SendData(0x02)
|
self.S1_SendData(0x02)
|
||||||
self.S1_SendData(0x90) #source 656
|
self.S1_SendData(0x90) # source 656
|
||||||
self.S1_SendData(0x01) #gate 492
|
self.S1_SendData(0x01) # gate 492
|
||||||
self.S1_SendData(0xEC)
|
self.S1_SendData(0xEC)
|
||||||
self.M2_SendCommand(0x61)
|
self.M2_SendCommand(0x61)
|
||||||
self.M2_SendData(0x02)
|
self.M2_SendData(0x02)
|
||||||
self.M2_SendData(0x90) #source 656
|
self.M2_SendData(0x90) # source 656
|
||||||
self.M2_SendData(0x01) #gate 492
|
self.M2_SendData(0x01) # gate 492
|
||||||
self.M2_SendData(0xEC)
|
self.M2_SendData(0xEC)
|
||||||
self.S2_SendCommand(0x61)
|
self.S2_SendCommand(0x61)
|
||||||
self.S2_SendData(0x02)
|
self.S2_SendData(0x02)
|
||||||
self.S2_SendData(0x88) #source 648
|
self.S2_SendData(0x88) # source 648
|
||||||
self.S2_SendData(0x01) #gate 492
|
self.S2_SendData(0x01) # gate 492
|
||||||
self.S2_SendData(0xEC)
|
self.S2_SendData(0xEC)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x15) #DUSPI
|
self.M1S1M2S2_SendCommand(0x15) # DUSPI
|
||||||
self.M1S1M2S2_SendData(0x20)
|
self.M1S1M2S2_SendData(0x20)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x30) # PLL
|
self.M1S1M2S2_SendCommand(0x30) # PLL
|
||||||
self.M1S1M2S2_SendData(0x08)
|
self.M1S1M2S2_SendData(0x08)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting
|
self.M1S1M2S2_SendCommand(0x50) # Vcom and data interval setting
|
||||||
self.M1S1M2S2_SendData(0x31)
|
self.M1S1M2S2_SendData(0x31)
|
||||||
self.M1S1M2S2_SendData(0x07)
|
self.M1S1M2S2_SendData(0x07)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x60)#TCON
|
self.M1S1M2S2_SendCommand(0x60) # TCON
|
||||||
self.M1S1M2S2_SendData(0x22)
|
self.M1S1M2S2_SendData(0x22)
|
||||||
|
|
||||||
self.M1_SendCommand(0xE0) #POWER SETTING
|
self.M1_SendCommand(0xE0) # POWER SETTING
|
||||||
self.M1_SendData(0x01)
|
self.M1_SendData(0x01)
|
||||||
self.M2_SendCommand(0xE0) #POWER SETTING
|
self.M2_SendCommand(0xE0) # POWER SETTING
|
||||||
self.M2_SendData(0x01)
|
self.M2_SendData(0x01)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0xE3)
|
self.M1S1M2S2_SendCommand(0xE3)
|
||||||
@ -151,106 +153,106 @@ class EPD(object):
|
|||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||||
buf = [0xFF] * (int(self.width/8) * self.height)
|
buf = [0xFF] * (int(self.width / 8) * self.height)
|
||||||
image_monocolor = image.convert('1')
|
image_monocolor = image.convert('1')
|
||||||
imwidth, imheight = image_monocolor.size
|
imwidth, imheight = image_monocolor.size
|
||||||
pixels = image_monocolor.load()
|
pixels = image_monocolor.load()
|
||||||
|
|
||||||
if(imwidth == self.width and imheight == self.height):
|
if (imwidth == self.width and imheight == self.height):
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
# Set the bits for the column of pixels at the current position.
|
# Set the bits for the column of pixels at the current position.
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||||
elif(imwidth == self.height and imheight == self.width):
|
elif (imwidth == self.height and imheight == self.width):
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
newx = y
|
newx = y
|
||||||
newy = self.height - x - 1
|
newy = self.height - x - 1
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
|
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, blackbuf, redbuf):
|
def display(self, blackbuf, redbuf):
|
||||||
|
|
||||||
#S2 part 648*492
|
# S2 part 648*492
|
||||||
self.S2_SendCommand(0x10)
|
self.S2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(blackbuf[y*163 + x])
|
self.S2_SendData(blackbuf[y * 163 + x])
|
||||||
self.S2_SendCommand(0x13)
|
self.S2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(~redbuf[y*163 + x])
|
self.S2_SendData(~redbuf[y * 163 + x])
|
||||||
|
|
||||||
#M2 part 656*492
|
# M2 part 656*492
|
||||||
self.M2_SendCommand(0x10)
|
self.M2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(blackbuf[y*163 + x])
|
self.M2_SendData(blackbuf[y * 163 + x])
|
||||||
self.M2_SendCommand(0x13)
|
self.M2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(~redbuf[y*163 + x])
|
self.M2_SendData(~redbuf[y * 163 + x])
|
||||||
|
|
||||||
#M1 part 648*492
|
# M1 part 648*492
|
||||||
self.M1_SendCommand(0x10)
|
self.M1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(blackbuf[y*163 + x])
|
self.M1_SendData(blackbuf[y * 163 + x])
|
||||||
self.M1_SendCommand(0x13)
|
self.M1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(~redbuf[y*163 + x])
|
self.M1_SendData(~redbuf[y * 163 + x])
|
||||||
|
|
||||||
#S1 part 656*492
|
# S1 part 656*492
|
||||||
self.S1_SendCommand(0x10)
|
self.S1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(blackbuf[y*163 + x])
|
self.S1_SendData(blackbuf[y * 163 + x])
|
||||||
self.S1_SendCommand(0x13)
|
self.S1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(~redbuf[y*163 + x])
|
self.S1_SendData(~redbuf[y * 163 + x])
|
||||||
self.TurnOnDisplay()
|
self.TurnOnDisplay()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""Clear contents of image buffer"""
|
"""Clear contents of image buffer"""
|
||||||
|
|
||||||
self.S2_SendCommand(0x10)
|
self.S2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(0xff)
|
self.S2_SendData(0xff)
|
||||||
self.S2_SendCommand(0x13)
|
self.S2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(0x00)
|
self.S2_SendData(0x00)
|
||||||
|
|
||||||
self.M2_SendCommand(0x10)
|
self.M2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(0xff)
|
self.M2_SendData(0xff)
|
||||||
self.M2_SendCommand(0x13)
|
self.M2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(0x00)
|
self.M2_SendData(0x00)
|
||||||
|
|
||||||
self.M1_SendCommand(0x10)
|
self.M1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(0xff)
|
self.M1_SendData(0xff)
|
||||||
self.M1_SendCommand(0x13)
|
self.M1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(0x00)
|
self.M1_SendData(0x00)
|
||||||
|
|
||||||
self.S1_SendCommand(0x10)
|
self.S1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(0xff)
|
self.S1_SendData(0xff)
|
||||||
self.S1_SendCommand(0x13)
|
self.S1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(0x00)
|
self.S1_SendData(0x00)
|
||||||
|
|
||||||
self.TurnOnDisplay()
|
self.TurnOnDisplay()
|
||||||
@ -286,6 +288,7 @@ class EPD(object):
|
|||||||
self.S2_ReadBusy()
|
self.S2_ReadBusy()
|
||||||
|
|
||||||
""" M1S1M2S2 Write register address and data """
|
""" M1S1M2S2 Write register address and data """
|
||||||
|
|
||||||
def M1S1M2S2_SendCommand(self, cmd):
|
def M1S1M2S2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
@ -315,6 +318,7 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
""" M1M2 Write register address and data """
|
""" M1M2 Write register address and data """
|
||||||
|
|
||||||
def M1M2_SendCommand(self, cmd):
|
def M1M2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
@ -334,11 +338,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
""" S2 Write register address and data """
|
""" S2 Write register address and data """
|
||||||
|
|
||||||
def S2_SendCommand(self, cmd):
|
def S2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
def S2_SendData(self, val):
|
def S2_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
||||||
@ -346,11 +352,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
""" M2 Write register address and data """
|
""" M2 Write register address and data """
|
||||||
|
|
||||||
def M2_SendCommand(self, cmd):
|
def M2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
def M2_SendData(self, val):
|
def M2_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
||||||
@ -358,11 +366,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
""" S1 Write register address and data """
|
""" S1 Write register address and data """
|
||||||
|
|
||||||
def S1_SendCommand(self, cmd):
|
def S1_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
||||||
|
|
||||||
def S1_SendData(self, val):
|
def S1_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
||||||
@ -370,138 +380,143 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
||||||
|
|
||||||
""" M1 Write register address and data """
|
""" M1 Write register address and data """
|
||||||
|
|
||||||
def M1_SendCommand(self, cmd):
|
def M1_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
||||||
|
|
||||||
def M1_SendData(self, val):
|
def M1_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(val)
|
epdconfig.spi_writebyte(val)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
||||||
|
|
||||||
#Busy
|
# Busy
|
||||||
def M1_ReadBusy(self):
|
def M1_ReadBusy(self):
|
||||||
self.M1_SendCommand(0x71)
|
self.M1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.M1_SendCommand(0x71)
|
self.M1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def M2_ReadBusy(self):
|
def M2_ReadBusy(self):
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
||||||
busy =not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def S1_ReadBusy(self):
|
def S1_ReadBusy(self):
|
||||||
self.S1_SendCommand(0x71)
|
self.S1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.S1_SendCommand(0x71)
|
self.S1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def S2_ReadBusy(self):
|
def S2_ReadBusy(self):
|
||||||
self.S2_SendCommand(0x71)
|
self.S2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.S2_SendCommand(0x71)
|
self.S2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
lut_vcom1 = [
|
lut_vcom1 = [
|
||||||
0x00, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x00, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x00, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x00, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x00, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_ww1 = [
|
lut_ww1 = [
|
||||||
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_bw1 = [
|
lut_bw1 = [
|
||||||
0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x84, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x84, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x86, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x86, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_wb1 = [
|
lut_wb1 = [
|
||||||
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_bb1 = [
|
lut_bb1 = [
|
||||||
0x92, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x92, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x01, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x01, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
|
|
||||||
def SetLut(self):
|
def SetLut(self):
|
||||||
self.M1S1M2S2_SendCommand(0x20) #vcom
|
self.M1S1M2S2_SendCommand(0x20) # vcom
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_vcom1[count])
|
self.M1S1M2S2_SendData(self.lut_vcom1[count])
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x21) #red not use
|
self.M1S1M2S2_SendCommand(0x21) # red not use
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_ww1[count])
|
self.M1S1M2S2_SendData(self.lut_ww1[count])
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x22) #bw r
|
self.M1S1M2S2_SendCommand(0x22) # bw r
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r
|
self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x23) #wb w
|
self.M1S1M2S2_SendCommand(0x23) # wb w
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w
|
self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x24) #bb b
|
self.M1S1M2S2_SendCommand(0x24) # bb b
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b
|
self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x25) #bb b
|
self.M1S1M2S2_SendCommand(0x25) # bb b
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b
|
self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b
|
||||||
|
@ -1,57 +1,60 @@
|
|||||||
# /*****************************************************************************
|
"""
|
||||||
# * | File : epd_12_in_48_colour.py
|
* | File : epd_12_in_48_colour.py
|
||||||
# * | Author : Waveshare electrices, modified by Sebastien Harnist
|
* | Author : Waveshare electrices, modified by Sebastien Harnist
|
||||||
# * | Function : Hardware underlying interface
|
* | Function : Hardware underlying interface
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V1.1
|
* | This version: V1.1
|
||||||
# * | Date : 2022-11-23
|
* | Date : 2022-11-23
|
||||||
# * | Info :
|
* | Info :
|
||||||
# ******************************************************************************/
|
******************************************************************************/
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig_12_in_48 as epdconfig
|
from inkycal.display.drivers import epdconfig_12_in_48 as epdconfig
|
||||||
|
|
||||||
EPD_WIDTH = 1304
|
EPD_WIDTH = 1304
|
||||||
EPD_HEIGHT = 984
|
EPD_HEIGHT = 984
|
||||||
|
|
||||||
|
|
||||||
class EPD(object):
|
class EPD(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.width = EPD_WIDTH
|
self.width = EPD_WIDTH
|
||||||
self.height = EPD_HEIGHT
|
self.height = EPD_HEIGHT
|
||||||
|
|
||||||
self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN
|
self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN
|
||||||
self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN
|
self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN
|
||||||
self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN
|
self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN
|
||||||
self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN
|
self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN
|
||||||
|
|
||||||
self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN
|
self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN
|
||||||
self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN
|
self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN
|
||||||
|
|
||||||
self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN
|
self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN
|
||||||
self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN
|
self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN
|
||||||
|
|
||||||
self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN
|
self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN
|
||||||
self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN
|
self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN
|
||||||
self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN
|
self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN
|
||||||
self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN
|
self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
print("EPD init...")
|
print("EPD init...")
|
||||||
@ -65,7 +68,7 @@ class EPD(object):
|
|||||||
|
|
||||||
# panel setting for Display
|
# panel setting for Display
|
||||||
self.M1_SendCommand(0x00)
|
self.M1_SendCommand(0x00)
|
||||||
self.M1_SendData(0x0f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
self.M1_SendData(0x0f) # KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
||||||
self.S1_SendCommand(0x00)
|
self.S1_SendCommand(0x00)
|
||||||
self.S1_SendData(0x0f)
|
self.S1_SendData(0x0f)
|
||||||
self.M2_SendCommand(0x00)
|
self.M2_SendCommand(0x00)
|
||||||
@ -75,9 +78,9 @@ class EPD(object):
|
|||||||
|
|
||||||
# booster soft start
|
# booster soft start
|
||||||
self.M1_SendCommand(0x06)
|
self.M1_SendCommand(0x06)
|
||||||
self.M1_SendData(0x17) #A
|
self.M1_SendData(0x17) # A
|
||||||
self.M1_SendData(0x17) #B
|
self.M1_SendData(0x17) # B
|
||||||
self.M1_SendData(0x39) #C
|
self.M1_SendData(0x39) # C
|
||||||
self.M1_SendData(0x17)
|
self.M1_SendData(0x17)
|
||||||
self.M2_SendCommand(0x06)
|
self.M2_SendCommand(0x06)
|
||||||
self.M2_SendData(0x17)
|
self.M2_SendData(0x17)
|
||||||
@ -85,36 +88,36 @@ class EPD(object):
|
|||||||
self.M2_SendData(0x39)
|
self.M2_SendData(0x39)
|
||||||
self.M2_SendData(0x17)
|
self.M2_SendData(0x17)
|
||||||
|
|
||||||
#resolution setting
|
# resolution setting
|
||||||
self.M1_SendCommand(0x61)
|
self.M1_SendCommand(0x61)
|
||||||
self.M1_SendData(0x02)
|
self.M1_SendData(0x02)
|
||||||
self.M1_SendData(0x88) #source 648
|
self.M1_SendData(0x88) # source 648
|
||||||
self.M1_SendData(0x01) #gate 492
|
self.M1_SendData(0x01) # gate 492
|
||||||
self.M1_SendData(0xEC)
|
self.M1_SendData(0xEC)
|
||||||
self.S1_SendCommand(0x61)
|
self.S1_SendCommand(0x61)
|
||||||
self.S1_SendData(0x02)
|
self.S1_SendData(0x02)
|
||||||
self.S1_SendData(0x90) #source 656
|
self.S1_SendData(0x90) # source 656
|
||||||
self.S1_SendData(0x01) #gate 492
|
self.S1_SendData(0x01) # gate 492
|
||||||
self.S1_SendData(0xEC)
|
self.S1_SendData(0xEC)
|
||||||
self.M2_SendCommand(0x61)
|
self.M2_SendCommand(0x61)
|
||||||
self.M2_SendData(0x02)
|
self.M2_SendData(0x02)
|
||||||
self.M2_SendData(0x90) #source 656
|
self.M2_SendData(0x90) # source 656
|
||||||
self.M2_SendData(0x01) #gate 492
|
self.M2_SendData(0x01) # gate 492
|
||||||
self.M2_SendData(0xEC)
|
self.M2_SendData(0xEC)
|
||||||
self.S2_SendCommand(0x61)
|
self.S2_SendCommand(0x61)
|
||||||
self.S2_SendData(0x02)
|
self.S2_SendData(0x02)
|
||||||
self.S2_SendData(0x88) #source 648
|
self.S2_SendData(0x88) # source 648
|
||||||
self.S2_SendData(0x01) #gate 492
|
self.S2_SendData(0x01) # gate 492
|
||||||
self.S2_SendData(0xEC)
|
self.S2_SendData(0xEC)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x15) #DUSPI
|
self.M1S1M2S2_SendCommand(0x15) # DUSPI
|
||||||
self.M1S1M2S2_SendData(0x20)
|
self.M1S1M2S2_SendData(0x20)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting
|
self.M1S1M2S2_SendCommand(0x50) # Vcom and data interval setting
|
||||||
self.M1S1M2S2_SendData(0x11)
|
self.M1S1M2S2_SendData(0x11)
|
||||||
self.M1S1M2S2_SendData(0x07)
|
self.M1S1M2S2_SendData(0x07)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x60)#TCON
|
self.M1S1M2S2_SendCommand(0x60) # TCON
|
||||||
self.M1S1M2S2_SendData(0x22)
|
self.M1S1M2S2_SendData(0x22)
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0xE3)
|
self.M1S1M2S2_SendCommand(0xE3)
|
||||||
@ -126,106 +129,106 @@ class EPD(object):
|
|||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||||
buf = [0xFF] * (int(self.width/8) * self.height)
|
buf = [0xFF] * (int(self.width / 8) * self.height)
|
||||||
image_monocolor = image.convert('1')
|
image_monocolor = image.convert('1')
|
||||||
imwidth, imheight = image_monocolor.size
|
imwidth, imheight = image_monocolor.size
|
||||||
pixels = image_monocolor.load()
|
pixels = image_monocolor.load()
|
||||||
|
|
||||||
if(imwidth == self.width and imheight == self.height):
|
if (imwidth == self.width and imheight == self.height):
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
# Set the bits for the column of pixels at the current position.
|
# Set the bits for the column of pixels at the current position.
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||||
elif(imwidth == self.height and imheight == self.width):
|
elif (imwidth == self.height and imheight == self.width):
|
||||||
for y in range(imheight):
|
for y in range(imheight):
|
||||||
for x in range(imwidth):
|
for x in range(imwidth):
|
||||||
newx = y
|
newx = y
|
||||||
newy = self.height - x - 1
|
newy = self.height - x - 1
|
||||||
if pixels[x, y] == 0:
|
if pixels[x, y] == 0:
|
||||||
buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
|
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, blackbuf, redbuf):
|
def display(self, blackbuf, redbuf):
|
||||||
|
|
||||||
#S2 part 648*492
|
# S2 part 648*492
|
||||||
self.S2_SendCommand(0x10)
|
self.S2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(blackbuf[y*163 + x])
|
self.S2_SendData(blackbuf[y * 163 + x])
|
||||||
self.S2_SendCommand(0x13)
|
self.S2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(~redbuf[y*163 + x])
|
self.S2_SendData(~redbuf[y * 163 + x])
|
||||||
|
|
||||||
#M2 part 656*492
|
# M2 part 656*492
|
||||||
self.M2_SendCommand(0x10)
|
self.M2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(blackbuf[y*163 + x])
|
self.M2_SendData(blackbuf[y * 163 + x])
|
||||||
self.M2_SendCommand(0x13)
|
self.M2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(~redbuf[y*163 + x])
|
self.M2_SendData(~redbuf[y * 163 + x])
|
||||||
|
|
||||||
#M1 part 648*492
|
# M1 part 648*492
|
||||||
self.M1_SendCommand(0x10)
|
self.M1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(blackbuf[y*163 + x])
|
self.M1_SendData(blackbuf[y * 163 + x])
|
||||||
self.M1_SendCommand(0x13)
|
self.M1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(~redbuf[y*163 + x])
|
self.M1_SendData(~redbuf[y * 163 + x])
|
||||||
|
|
||||||
#S1 part 656*492
|
# S1 part 656*492
|
||||||
self.S1_SendCommand(0x10)
|
self.S1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(blackbuf[y*163 + x])
|
self.S1_SendData(blackbuf[y * 163 + x])
|
||||||
self.S1_SendCommand(0x13)
|
self.S1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(~redbuf[y*163 + x])
|
self.S1_SendData(~redbuf[y * 163 + x])
|
||||||
self.TurnOnDisplay()
|
self.TurnOnDisplay()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""Clear contents of image buffer"""
|
"""Clear contents of image buffer"""
|
||||||
|
|
||||||
self.S2_SendCommand(0x10)
|
self.S2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(0xff)
|
self.S2_SendData(0xff)
|
||||||
self.S2_SendCommand(0x13)
|
self.S2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.S2_SendData(0x00)
|
self.S2_SendData(0x00)
|
||||||
|
|
||||||
self.M2_SendCommand(0x10)
|
self.M2_SendCommand(0x10)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(0xff)
|
self.M2_SendData(0xff)
|
||||||
self.M2_SendCommand(0x13)
|
self.M2_SendCommand(0x13)
|
||||||
for y in range(0, 492):
|
for y in range(0, 492):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.M2_SendData(0x00)
|
self.M2_SendData(0x00)
|
||||||
|
|
||||||
self.M1_SendCommand(0x10)
|
self.M1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(0xff)
|
self.M1_SendData(0xff)
|
||||||
self.M1_SendCommand(0x13)
|
self.M1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(0, 81):
|
for x in range(0, 81):
|
||||||
self.M1_SendData(0x00)
|
self.M1_SendData(0x00)
|
||||||
|
|
||||||
self.S1_SendCommand(0x10)
|
self.S1_SendCommand(0x10)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(0xff)
|
self.S1_SendData(0xff)
|
||||||
self.S1_SendCommand(0x13)
|
self.S1_SendCommand(0x13)
|
||||||
for y in range(492, 984):
|
for y in range(492, 984):
|
||||||
for x in range(81, 163):
|
for x in range(81, 163):
|
||||||
self.S1_SendData(0x00)
|
self.S1_SendData(0x00)
|
||||||
|
|
||||||
self.TurnOnDisplay()
|
self.TurnOnDisplay()
|
||||||
@ -261,6 +264,7 @@ class EPD(object):
|
|||||||
self.S2_ReadBusy()
|
self.S2_ReadBusy()
|
||||||
|
|
||||||
""" M1S1M2S2 Write register address and data """
|
""" M1S1M2S2 Write register address and data """
|
||||||
|
|
||||||
def M1S1M2S2_SendCommand(self, cmd):
|
def M1S1M2S2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
@ -290,6 +294,7 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
""" M1M2 Write register address and data """
|
""" M1M2 Write register address and data """
|
||||||
|
|
||||||
def M1M2_SendCommand(self, cmd):
|
def M1M2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
@ -309,11 +314,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
""" S2 Write register address and data """
|
""" S2 Write register address and data """
|
||||||
|
|
||||||
def S2_SendCommand(self, cmd):
|
def S2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
def S2_SendData(self, val):
|
def S2_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)
|
||||||
@ -321,11 +328,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)
|
||||||
|
|
||||||
""" M2 Write register address and data """
|
""" M2 Write register address and data """
|
||||||
|
|
||||||
def M2_SendCommand(self, cmd):
|
def M2_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
def M2_SendData(self, val):
|
def M2_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)
|
||||||
@ -333,11 +342,13 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)
|
||||||
|
|
||||||
""" S1 Write register address and data """
|
""" S1 Write register address and data """
|
||||||
|
|
||||||
def S1_SendCommand(self, cmd):
|
def S1_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
||||||
|
|
||||||
def S1_SendData(self, val):
|
def S1_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)
|
||||||
@ -345,141 +356,146 @@ class EPD(object):
|
|||||||
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)
|
||||||
|
|
||||||
""" M1 Write register address and data """
|
""" M1 Write register address and data """
|
||||||
|
|
||||||
def M1_SendCommand(self, cmd):
|
def M1_SendCommand(self, cmd):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(cmd)
|
epdconfig.spi_writebyte(cmd)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
||||||
|
|
||||||
def M1_SendData(self, val):
|
def M1_SendData(self, val):
|
||||||
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)
|
||||||
epdconfig.spi_writebyte(val)
|
epdconfig.spi_writebyte(val)
|
||||||
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)
|
||||||
|
|
||||||
#Busy
|
# Busy
|
||||||
def M1_ReadBusy(self):
|
def M1_ReadBusy(self):
|
||||||
self.M1_SendCommand(0x71)
|
self.M1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.M1_SendCommand(0x71)
|
self.M1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def M2_ReadBusy(self):
|
def M2_ReadBusy(self):
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.M2_SendCommand(0x71)
|
self.M2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN)
|
||||||
busy =not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def S1_ReadBusy(self):
|
def S1_ReadBusy(self):
|
||||||
self.S1_SendCommand(0x71)
|
self.S1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.S1_SendCommand(0x71)
|
self.S1_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
def S2_ReadBusy(self):
|
def S2_ReadBusy(self):
|
||||||
self.S2_SendCommand(0x71)
|
self.S2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
while(busy):
|
while (busy):
|
||||||
self.S2_SendCommand(0x71)
|
self.S2_SendCommand(0x71)
|
||||||
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN)
|
||||||
busy = not(busy & 0x01)
|
busy = not (busy & 0x01)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
lut_vcom1 = [
|
lut_vcom1 = [
|
||||||
0x00, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x00, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x00, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x00, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x00, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x00, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_ww1 = [
|
lut_ww1 = [
|
||||||
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_bw1 = [
|
lut_bw1 = [
|
||||||
0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x84, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x84, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x86, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x86, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_wb1 = [
|
lut_wb1 = [
|
||||||
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x91, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x08, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
lut_bb1 = [
|
lut_bb1 = [
|
||||||
0x92, 0x10, 0x10, 0x01, 0x08, 0x01,
|
0x92, 0x10, 0x10, 0x01, 0x08, 0x01,
|
||||||
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x80, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
0x84, 0x08, 0x01, 0x08, 0x01, 0x06,
|
||||||
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
0x04, 0x06, 0x01, 0x06, 0x01, 0x05,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,
|
||||||
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,
|
||||||
0x01, 0x04, 0x05, 0x08, 0x08, 0x01,
|
0x01, 0x04, 0x05, 0x08, 0x08, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
]
|
]
|
||||||
|
|
||||||
def SetLut(self):
|
def SetLut(self):
|
||||||
self.M1S1M2S2_SendCommand(0x20) #vcom
|
self.M1S1M2S2_SendCommand(0x20) # vcom
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_vcom1[count])
|
self.M1S1M2S2_SendData(self.lut_vcom1[count])
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x21) #red not use
|
self.M1S1M2S2_SendCommand(0x21) # red not use
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_ww1[count])
|
self.M1S1M2S2_SendData(self.lut_ww1[count])
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x22) #bw r
|
self.M1S1M2S2_SendCommand(0x22) # bw r
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r
|
self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x23) #wb w
|
self.M1S1M2S2_SendCommand(0x23) # wb w
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w
|
self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x24) #bb b
|
self.M1S1M2S2_SendCommand(0x24) # bb b
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b
|
self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b
|
||||||
|
|
||||||
self.M1S1M2S2_SendCommand(0x25) #bb b
|
self.M1S1M2S2_SendCommand(0x25) # bb b
|
||||||
for count in range(0, 60):
|
for count in range(0, 60):
|
||||||
self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b
|
self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b
|
||||||
|
|
||||||
def M1_ReadTemperature(self):
|
def M1_ReadTemperature(self):
|
||||||
self.M1_SendCommand(0x40)
|
self.M1_SendCommand(0x40)
|
||||||
|
@ -1,37 +1,35 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd4in2.py
|
* | File : epd4in2.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
from PIL import Image
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 400
|
EPD_WIDTH = 400
|
||||||
@ -354,8 +352,8 @@ class EPD:
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
if (i % 4 == 0):
|
if (i % 4 == 0):
|
||||||
buf[int((x + (y * self.width)) / 4)] = (
|
buf[int((x + (y * self.width)) / 4)] = (
|
||||||
(pixels[x - 3, y] & 0xc0) | (pixels[x - 2, y] & 0xc0) >> 2 | (
|
(pixels[x - 3, y] & 0xc0) | (pixels[x - 2, y] & 0xc0) >> 2 | (
|
||||||
pixels[x - 1, y] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
pixels[x - 1, y] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
||||||
|
|
||||||
elif (imwidth == self.height and imheight == self.width):
|
elif (imwidth == self.height and imheight == self.width):
|
||||||
logging.debug("Horizontal")
|
logging.debug("Horizontal")
|
||||||
@ -370,8 +368,8 @@ class EPD:
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
if (i % 4 == 0):
|
if (i % 4 == 0):
|
||||||
buf[int((newx + (newy * self.width)) / 4)] = (
|
buf[int((newx + (newy * self.width)) / 4)] = (
|
||||||
(pixels[x, y - 3] & 0xc0) | (pixels[x, y - 2] & 0xc0) >> 2 | (
|
(pixels[x, y - 3] & 0xc0) | (pixels[x, y - 2] & 0xc0) >> 2 | (
|
||||||
pixels[x, y - 1] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
pixels[x, y - 1] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
||||||
|
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
@ -1,33 +1,34 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd4in2bc.py
|
* | File : epd4in2bc.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd5in83.py
|
* | File : epd5in83.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd5in83b.py
|
* | File : epd5in83b.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd7in5.py
|
* | File : epd7in5.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd7in5bc.py
|
* | File : epd7in5bc.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd7in5.py
|
* | File : epd7in5.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from inkycal.display.drivers import epdconfig
|
from inkycal.display.drivers import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# *****************************************************************************
|
# *****************************************************************************
|
||||||
# * | File : epd7in5bc.py
|
# * | File : epd7in5b_V2.py
|
||||||
# * | Author : Waveshare team
|
# * | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
# * | Function : Electronic paper driver
|
||||||
# * | Info :
|
# * | Info :
|
||||||
# *----------------
|
# *----------------
|
||||||
# * | This version: V4.0
|
# * | This version: V4.2
|
||||||
# * | Date : 2019-06-20
|
# * | Date : 2022-01-08
|
||||||
# # | Info : python demo
|
# # | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
# in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
@ -29,12 +29,15 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from inkycal.display.drivers import epdconfig
|
|
||||||
|
from . import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 800
|
EPD_WIDTH = 800
|
||||||
EPD_HEIGHT = 480
|
EPD_HEIGHT = 480
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class EPD:
|
class EPD:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -66,97 +69,107 @@ class EPD:
|
|||||||
epdconfig.spi_writebyte([data])
|
epdconfig.spi_writebyte([data])
|
||||||
epdconfig.digital_write(self.cs_pin, 1)
|
epdconfig.digital_write(self.cs_pin, 1)
|
||||||
|
|
||||||
|
def send_data2(self, data): # faster
|
||||||
|
epdconfig.digital_write(self.dc_pin, 1)
|
||||||
|
epdconfig.digital_write(self.cs_pin, 0)
|
||||||
|
epdconfig.spi_writebyte2(data)
|
||||||
|
epdconfig.digital_write(self.cs_pin, 1)
|
||||||
|
|
||||||
def ReadBusy(self):
|
def ReadBusy(self):
|
||||||
logging.debug("e-Paper busy")
|
logger.debug("e-Paper busy")
|
||||||
self.send_command(0x71)
|
self.send_command(0x71)
|
||||||
busy = epdconfig.digital_read(self.busy_pin)
|
busy = epdconfig.digital_read(self.busy_pin)
|
||||||
while (busy == 0):
|
while (busy == 0):
|
||||||
self.send_command(0x71)
|
self.send_command(0x71)
|
||||||
busy = epdconfig.digital_read(self.busy_pin)
|
busy = epdconfig.digital_read(self.busy_pin)
|
||||||
epdconfig.delay_ms(200)
|
epdconfig.delay_ms(200)
|
||||||
|
logger.debug("e-Paper busy release")
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
if (epdconfig.module_init() != 0):
|
if epdconfig.module_init() != 0:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
self.send_command(0x01); # POWER SETTING
|
self.send_command(0x01) # POWER SETTING
|
||||||
self.send_data(0x07);
|
self.send_data(0x07)
|
||||||
self.send_data(0x07); # VGH=20V,VGL=-20V
|
self.send_data(0x07) # VGH=20V,VGL=-20V
|
||||||
self.send_data(0x3f); # VDH=15V
|
self.send_data(0x3f) # VDH=15V
|
||||||
self.send_data(0x3f); # VDL=-15V
|
self.send_data(0x3f) # VDL=-15V
|
||||||
|
|
||||||
self.send_command(0x04); # POWER ON
|
self.send_command(0x04) # POWER ON
|
||||||
epdconfig.delay_ms(100);
|
epdconfig.delay_ms(100)
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
self.send_command(0X00); # PANNEL SETTING
|
self.send_command(0X00) # PANNEL SETTING
|
||||||
self.send_data(0x0F); # KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
self.send_data(0x0F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
|
||||||
|
|
||||||
self.send_command(0x61); # tres
|
self.send_command(0x61) # tres
|
||||||
self.send_data(0x03); # source 800
|
self.send_data(0x03) # source 800
|
||||||
self.send_data(0x20);
|
self.send_data(0x20)
|
||||||
self.send_data(0x01); # gate 480
|
self.send_data(0x01) # gate 480
|
||||||
self.send_data(0xE0);
|
self.send_data(0xE0)
|
||||||
|
|
||||||
self.send_command(0X15);
|
self.send_command(0X15)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
|
|
||||||
self.send_command(0X50); # VCOM AND DATA INTERVAL SETTING
|
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
|
||||||
self.send_data(0x11);
|
self.send_data(0x11)
|
||||||
self.send_data(0x07);
|
self.send_data(0x07)
|
||||||
|
|
||||||
self.send_command(0X60); # TCON SETTING
|
self.send_command(0X60) # TCON SETTING
|
||||||
self.send_data(0x22);
|
self.send_data(0x22)
|
||||||
|
|
||||||
|
self.send_command(0x65)
|
||||||
|
self.send_data(0x00)
|
||||||
|
self.send_data(0x00)
|
||||||
|
self.send_data(0x00)
|
||||||
|
self.send_data(0x00)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def getbuffer(self, image):
|
def getbuffer(self, image):
|
||||||
# logging.debug("bufsiz = ",int(self.width/8) * self.height)
|
img = image
|
||||||
buf = [0xFF] * (int(self.width / 8) * self.height)
|
imwidth, imheight = img.size
|
||||||
image_monocolor = image.convert('1')
|
if imwidth == self.width and imheight == self.height:
|
||||||
imwidth, imheight = image_monocolor.size
|
img = img.convert('1')
|
||||||
pixels = image_monocolor.load()
|
elif imwidth == self.height and imheight == self.width:
|
||||||
logging.debug('imwidth = %d imheight = %d ', imwidth, imheight)
|
# image has correct dimensions, but needs to be rotated
|
||||||
if (imwidth == self.width and imheight == self.height):
|
img = img.rotate(90, expand=True).convert('1')
|
||||||
logging.debug("Horizontal")
|
else:
|
||||||
for y in range(imheight):
|
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
|
||||||
for x in range(imwidth):
|
# return a blank buffer
|
||||||
# Set the bits for the column of pixels at the current position.
|
return [0x00] * (int(self.width / 8) * self.height)
|
||||||
if pixels[x, y] == 0:
|
|
||||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
buf = bytearray(img.tobytes('raw'))
|
||||||
elif (imwidth == self.height and imheight == self.width):
|
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
|
||||||
logging.debug("Vertical")
|
# in the e-paper world 0=white and 1=black.
|
||||||
for y in range(imheight):
|
for i in range(len(buf)):
|
||||||
for x in range(imwidth):
|
buf[i] ^= 0xFF
|
||||||
newx = y
|
|
||||||
newy = self.height - x - 1
|
|
||||||
if pixels[x, y] == 0:
|
|
||||||
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, imageblack, imagered):
|
def display(self, imageblack, imagered):
|
||||||
self.send_command(0x10)
|
self.send_command(0x10)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
# The black bytes need to be inverted back from what getbuffer did
|
||||||
self.send_data(imageblack[i]);
|
for i in range(len(imageblack)):
|
||||||
|
imageblack[i] ^= 0xFF
|
||||||
|
self.send_data2(imageblack)
|
||||||
|
|
||||||
self.send_command(0x13)
|
self.send_command(0x13)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
self.send_data2(imagered)
|
||||||
self.send_data(~imagered[i]);
|
|
||||||
|
|
||||||
self.send_command(0x12)
|
self.send_command(0x12)
|
||||||
epdconfig.delay_ms(100)
|
epdconfig.delay_ms(100)
|
||||||
self.ReadBusy()
|
self.ReadBusy()
|
||||||
|
|
||||||
def Clear(self):
|
def Clear(self):
|
||||||
|
buf = [0x00] * (int(self.width / 8) * self.height)
|
||||||
|
buf2 = [0xff] * (int(self.width / 8) * self.height)
|
||||||
self.send_command(0x10)
|
self.send_command(0x10)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
self.send_data2(buf2)
|
||||||
self.send_data(0xff)
|
|
||||||
|
|
||||||
self.send_command(0x13)
|
self.send_command(0x13)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
self.send_data2(buf)
|
||||||
self.send_data(0x00)
|
|
||||||
|
|
||||||
self.send_command(0x12)
|
self.send_command(0x12)
|
||||||
epdconfig.delay_ms(100)
|
epdconfig.delay_ms(100)
|
||||||
@ -169,5 +182,5 @@ class EPD:
|
|||||||
self.send_command(0x07) # DEEP_SLEEP
|
self.send_command(0x07) # DEEP_SLEEP
|
||||||
self.send_data(0XA5)
|
self.send_data(0XA5)
|
||||||
|
|
||||||
|
epdconfig.delay_ms(2000)
|
||||||
epdconfig.module_exit()
|
epdconfig.module_exit()
|
||||||
### END OF FILE ###
|
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd7in5.py
|
* | File : epd7in5.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -79,60 +79,60 @@ class EPD:
|
|||||||
# EPD hardware init start
|
# EPD hardware init start
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
self.send_command(0x12); # SWRESET
|
self.send_command(0x12) # SWRESET
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
self.send_command(0x46); # Auto Write Red RAM
|
self.send_command(0x46) # Auto Write Red RAM
|
||||||
self.send_data(0xf7);
|
self.send_data(0xf7)
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
self.send_command(0x47); # Auto Write B/W RAM
|
self.send_command(0x47) # Auto Write B/W RAM
|
||||||
self.send_data(0xf7);
|
self.send_data(0xf7)
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
self.send_command(0x0C); # Soft start setting
|
self.send_command(0x0C) # Soft start setting
|
||||||
self.send_data(0xAE);
|
self.send_data(0xAE)
|
||||||
self.send_data(0xC7);
|
self.send_data(0xC7)
|
||||||
self.send_data(0xC3);
|
self.send_data(0xC3)
|
||||||
self.send_data(0xC0);
|
self.send_data(0xC0)
|
||||||
self.send_data(0x40);
|
self.send_data(0x40)
|
||||||
|
|
||||||
self.send_command(0x01); # Set MUX as 527
|
self.send_command(0x01) # Set MUX as 527
|
||||||
self.send_data(0xAF);
|
self.send_data(0xAF)
|
||||||
self.send_data(0x02);
|
self.send_data(0x02)
|
||||||
self.send_data(0x01); # 0x01
|
self.send_data(0x01) # 0x01
|
||||||
|
|
||||||
self.send_command(0x11); # Data entry mode
|
self.send_command(0x11) # Data entry mode
|
||||||
self.send_data(0x01);
|
self.send_data(0x01)
|
||||||
|
|
||||||
self.send_command(0x44);
|
self.send_command(0x44)
|
||||||
self.send_data(0x00); # RAM x address start at 0
|
self.send_data(0x00) # RAM x address start at 0
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x6F);
|
self.send_data(0x6F)
|
||||||
self.send_data(0x03);
|
self.send_data(0x03)
|
||||||
self.send_command(0x45);
|
self.send_command(0x45)
|
||||||
self.send_data(0xAF);
|
self.send_data(0xAF)
|
||||||
self.send_data(0x02);
|
self.send_data(0x02)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
|
|
||||||
self.send_command(0x3C); # VBD
|
self.send_command(0x3C) # VBD
|
||||||
self.send_data(0x05); # LUT1, for white
|
self.send_data(0x05) # LUT1, for white
|
||||||
|
|
||||||
self.send_command(0x18);
|
self.send_command(0x18)
|
||||||
self.send_data(0X80);
|
self.send_data(0X80)
|
||||||
|
|
||||||
self.send_command(0x22);
|
self.send_command(0x22)
|
||||||
self.send_data(0XB1); # Load Temperature and waveform setting.
|
self.send_data(0XB1) # Load Temperature and waveform setting.
|
||||||
self.send_command(0x20);
|
self.send_command(0x20)
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
self.send_command(0x4E); # set RAM x address count to 0;
|
self.send_command(0x4E) # set RAM x address count to 0
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_command(0x4F);
|
self.send_command(0x4F)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
# EPD hardware init end
|
# EPD hardware init end
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -161,23 +161,23 @@ class EPD:
|
|||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, image):
|
def display(self, image):
|
||||||
self.send_command(0x4F);
|
self.send_command(0x4F)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_command(0x24);
|
self.send_command(0x24)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(image[i]);
|
self.send_data(image[i])
|
||||||
|
|
||||||
self.send_command(0x22);
|
self.send_command(0x22)
|
||||||
self.send_data(0xF7); # Load LUT from MCU(0x32)
|
self.send_data(0xF7) # Load LUT from MCU(0x32)
|
||||||
self.send_command(0x20);
|
self.send_command(0x20)
|
||||||
epdconfig.delay_ms(10);
|
epdconfig.delay_ms(10)
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
def Clear(self):
|
def Clear(self):
|
||||||
self.send_command(0x4F);
|
self.send_command(0x4F)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_command(0x24)
|
self.send_command(0x24)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(0xff)
|
self.send_data(0xff)
|
||||||
@ -186,15 +186,15 @@ class EPD:
|
|||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(0xff)
|
self.send_data(0xff)
|
||||||
|
|
||||||
self.send_command(0x22);
|
self.send_command(0x22)
|
||||||
self.send_data(0xF7); # Load LUT from MCU(0x32)
|
self.send_data(0xF7) # Load LUT from MCU(0x32)
|
||||||
self.send_command(0x20);
|
self.send_command(0x20)
|
||||||
epdconfig.delay_ms(10);
|
epdconfig.delay_ms(10)
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
def sleep(self):
|
def sleep(self):
|
||||||
self.send_command(0x10);
|
self.send_command(0x10)
|
||||||
self.send_data(0x01);
|
self.send_data(0x01)
|
||||||
|
|
||||||
epdconfig.module_exit()
|
epdconfig.module_exit()
|
||||||
### END OF FILE ###
|
### END OF FILE ###
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
# *****************************************************************************
|
"""
|
||||||
# * | File : epd7in5bc.py
|
* | File : epd7in5bc.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Electronic paper driver
|
* | Function : Electronic paper driver
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V4.0
|
* | This version: V4.0
|
||||||
# * | Date : 2019-06-20
|
* | Date : 2019-06-20
|
||||||
# # | Info : python demo
|
# | Info : python demo
|
||||||
# -----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -79,59 +79,59 @@ class EPD:
|
|||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
self.send_command(0x12); # SWRESET
|
self.send_command(0x12) # SWRESET
|
||||||
self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal
|
self.ReadBusy() # waiting for the electronic paper IC to release the idle signal
|
||||||
|
|
||||||
self.send_command(0x46); # Auto Write RAM
|
self.send_command(0x46) # Auto Write RAM
|
||||||
self.send_data(0xF7);
|
self.send_data(0xF7)
|
||||||
self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal
|
self.ReadBusy() # waiting for the electronic paper IC to release the idle signal
|
||||||
|
|
||||||
self.send_command(0x47); # Auto Write RAM
|
self.send_command(0x47) # Auto Write RAM
|
||||||
self.send_data(0xF7);
|
self.send_data(0xF7)
|
||||||
self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal
|
self.ReadBusy() # waiting for the electronic paper IC to release the idle signal
|
||||||
|
|
||||||
self.send_command(0x0C); # Soft start setting
|
self.send_command(0x0C) # Soft start setting
|
||||||
self.send_data(0xAE);
|
self.send_data(0xAE)
|
||||||
self.send_data(0xC7);
|
self.send_data(0xC7)
|
||||||
self.send_data(0xC3);
|
self.send_data(0xC3)
|
||||||
self.send_data(0xC0);
|
self.send_data(0xC0)
|
||||||
self.send_data(0x40);
|
self.send_data(0x40)
|
||||||
|
|
||||||
self.send_command(0x01); # Set MUX as 527
|
self.send_command(0x01) # Set MUX as 527
|
||||||
self.send_data(0xAF);
|
self.send_data(0xAF)
|
||||||
self.send_data(0x02);
|
self.send_data(0x02)
|
||||||
self.send_data(0x01);
|
self.send_data(0x01)
|
||||||
|
|
||||||
self.send_command(0x11); # Data entry mode
|
self.send_command(0x11) # Data entry mode
|
||||||
self.send_data(0x01);
|
self.send_data(0x01)
|
||||||
|
|
||||||
self.send_command(0x44);
|
self.send_command(0x44)
|
||||||
self.send_data(0x00); # RAM x address start at 0
|
self.send_data(0x00) # RAM x address start at 0
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x6F); # RAM x address end at 36Fh -> 879
|
self.send_data(0x6F) # RAM x address end at 36Fh -> 879
|
||||||
self.send_data(0x03);
|
self.send_data(0x03)
|
||||||
self.send_command(0x45);
|
self.send_command(0x45)
|
||||||
self.send_data(0xAF); # RAM y address start at 20Fh;
|
self.send_data(0xAF) # RAM y address start at 20Fh
|
||||||
self.send_data(0x02);
|
self.send_data(0x02)
|
||||||
self.send_data(0x00); # RAM y address end at 00h;
|
self.send_data(0x00) # RAM y address end at 00h
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
|
|
||||||
self.send_command(0x3C); # VBD
|
self.send_command(0x3C) # VBD
|
||||||
self.send_data(0x01); # LUT1, for white
|
self.send_data(0x01) # LUT1, for white
|
||||||
|
|
||||||
self.send_command(0x18);
|
self.send_command(0x18)
|
||||||
self.send_data(0X80);
|
self.send_data(0X80)
|
||||||
self.send_command(0x22);
|
self.send_command(0x22)
|
||||||
self.send_data(0XB1); # Load Temperature and waveform setting.
|
self.send_data(0XB1) # Load Temperature and waveform setting.
|
||||||
self.send_command(0x20);
|
self.send_command(0x20)
|
||||||
self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal
|
self.ReadBusy() # waiting for the electronic paper IC to release the idle signal
|
||||||
|
|
||||||
self.send_command(0x4E);
|
self.send_command(0x4E)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
self.send_command(0x4F);
|
self.send_command(0x4F)
|
||||||
self.send_data(0xAF);
|
self.send_data(0xAF)
|
||||||
self.send_data(0x02);
|
self.send_data(0x02)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -160,44 +160,44 @@ class EPD:
|
|||||||
return buf
|
return buf
|
||||||
|
|
||||||
def display(self, imageblack, imagered):
|
def display(self, imageblack, imagered):
|
||||||
self.send_command(0x4F);
|
self.send_command(0x4F)
|
||||||
self.send_data(0xAf);
|
self.send_data(0xAf)
|
||||||
|
|
||||||
self.send_command(0x24)
|
self.send_command(0x24)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(imageblack[i]);
|
self.send_data(imageblack[i])
|
||||||
|
|
||||||
self.send_command(0x26)
|
self.send_command(0x26)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(~imagered[i]);
|
self.send_data(~imagered[i])
|
||||||
|
|
||||||
self.send_command(0x22);
|
self.send_command(0x22)
|
||||||
self.send_data(0xC7); # Load LUT from MCU(0x32)
|
self.send_data(0xC7) # Load LUT from MCU(0x32)
|
||||||
self.send_command(0x20);
|
self.send_command(0x20)
|
||||||
epdconfig.delay_ms(200); # !!!The delay here is necessary, 200uS at least!!!
|
epdconfig.delay_ms(200) # !!!The delay here is necessary, 200uS at least!!!
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
def Clear(self):
|
def Clear(self):
|
||||||
self.send_command(0x4F);
|
self.send_command(0x4F)
|
||||||
self.send_data(0xAf);
|
self.send_data(0xAf)
|
||||||
|
|
||||||
self.send_command(0x24)
|
self.send_command(0x24)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(0xff);
|
self.send_data(0xff)
|
||||||
|
|
||||||
self.send_command(0x26)
|
self.send_command(0x26)
|
||||||
for i in range(0, int(self.width * self.height / 8)):
|
for i in range(0, int(self.width * self.height / 8)):
|
||||||
self.send_data(0x00);
|
self.send_data(0x00)
|
||||||
|
|
||||||
self.send_command(0x22);
|
self.send_command(0x22)
|
||||||
self.send_data(0xC7); # Load LUT from MCU(0x32)
|
self.send_data(0xC7) # Load LUT from MCU(0x32)
|
||||||
self.send_command(0x20);
|
self.send_command(0x20)
|
||||||
epdconfig.delay_ms(200); # !!!The delay here is necessary, 200uS at least!!!
|
epdconfig.delay_ms(200) # !!!The delay here is necessary, 200uS at least!!!
|
||||||
self.ReadBusy();
|
self.ReadBusy()
|
||||||
|
|
||||||
def sleep(self):
|
def sleep(self):
|
||||||
self.send_command(0x10); # deep sleep
|
self.send_command(0x10) # deep sleep
|
||||||
self.send_data(0x01);
|
self.send_data(0x01)
|
||||||
|
|
||||||
epdconfig.module_exit()
|
epdconfig.module_exit()
|
||||||
### END OF FILE ###
|
### END OF FILE ###
|
||||||
|
@ -1,34 +1,35 @@
|
|||||||
# /*****************************************************************************
|
"""
|
||||||
# * | File : epdconfig.py
|
* | File : epdconfig.py
|
||||||
# * | Author : Waveshare team
|
* | Author : Waveshare team
|
||||||
# * | Function : Hardware underlying interface
|
* | Function : Hardware underlying interface
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V1.0
|
* | This version: V1.2
|
||||||
# * | Date : 2019-06-21
|
* | Date : 2022-10-29
|
||||||
# * | Info :
|
* | Info :
|
||||||
# ******************************************************************************
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
#
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@ -41,21 +42,52 @@ class RaspberryPi:
|
|||||||
DC_PIN = 25
|
DC_PIN = 25
|
||||||
CS_PIN = 8
|
CS_PIN = 8
|
||||||
BUSY_PIN = 24
|
BUSY_PIN = 24
|
||||||
|
PWR_PIN = 18
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
import spidev
|
import spidev
|
||||||
import RPi.GPIO
|
import gpiozero
|
||||||
|
|
||||||
self.GPIO = RPi.GPIO
|
self.SPI = spidev.SpiDev()
|
||||||
|
self.GPIO_RST_PIN = gpiozero.LED(self.RST_PIN)
|
||||||
# SPI device, bus = 0, device = 0
|
self.GPIO_DC_PIN = gpiozero.LED(self.DC_PIN)
|
||||||
self.SPI = spidev.SpiDev(0, 0)
|
# self.GPIO_CS_PIN = gpiozero.LED(self.CS_PIN)
|
||||||
|
self.GPIO_PWR_PIN = gpiozero.LED(self.PWR_PIN)
|
||||||
|
self.GPIO_BUSY_PIN = gpiozero.Button(self.BUSY_PIN, pull_up=False)
|
||||||
|
|
||||||
def digital_write(self, pin, value):
|
def digital_write(self, pin, value):
|
||||||
self.GPIO.output(pin, value)
|
if pin == self.RST_PIN:
|
||||||
|
if value:
|
||||||
|
self.GPIO_RST_PIN.on()
|
||||||
|
else:
|
||||||
|
self.GPIO_RST_PIN.off()
|
||||||
|
elif pin == self.DC_PIN:
|
||||||
|
if value:
|
||||||
|
self.GPIO_DC_PIN.on()
|
||||||
|
else:
|
||||||
|
self.GPIO_DC_PIN.off()
|
||||||
|
# elif pin == self.CS_PIN:
|
||||||
|
# if value:
|
||||||
|
# self.GPIO_CS_PIN.on()
|
||||||
|
# else:
|
||||||
|
# self.GPIO_CS_PIN.off()
|
||||||
|
elif pin == self.PWR_PIN:
|
||||||
|
if value:
|
||||||
|
self.GPIO_PWR_PIN.on()
|
||||||
|
else:
|
||||||
|
self.GPIO_PWR_PIN.off()
|
||||||
|
|
||||||
def digital_read(self, pin):
|
def digital_read(self, pin):
|
||||||
return self.GPIO.input(pin)
|
if pin == self.BUSY_PIN:
|
||||||
|
return self.GPIO_BUSY_PIN.value
|
||||||
|
elif pin == self.RST_PIN:
|
||||||
|
return self.RST_PIN.value
|
||||||
|
elif pin == self.DC_PIN:
|
||||||
|
return self.DC_PIN.value
|
||||||
|
# elif pin == self.CS_PIN:
|
||||||
|
# return self.CS_PIN.value
|
||||||
|
elif pin == self.PWR_PIN:
|
||||||
|
return self.PWR_PIN.value
|
||||||
|
|
||||||
def delay_ms(self, delaytime):
|
def delay_ms(self, delaytime):
|
||||||
time.sleep(delaytime / 1000.0)
|
time.sleep(delaytime / 1000.0)
|
||||||
@ -63,26 +95,33 @@ class RaspberryPi:
|
|||||||
def spi_writebyte(self, data):
|
def spi_writebyte(self, data):
|
||||||
self.SPI.writebytes(data)
|
self.SPI.writebytes(data)
|
||||||
|
|
||||||
|
def spi_writebyte2(self, data):
|
||||||
|
self.SPI.writebytes2(data)
|
||||||
|
|
||||||
def module_init(self):
|
def module_init(self):
|
||||||
self.GPIO.setmode(self.GPIO.BCM)
|
self.GPIO_PWR_PIN.on()
|
||||||
self.GPIO.setwarnings(False)
|
|
||||||
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
|
# SPI device, bus = 0, device = 0
|
||||||
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
|
self.SPI.open(0, 0)
|
||||||
self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
|
|
||||||
self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
|
|
||||||
self.SPI.max_speed_hz = 4000000
|
self.SPI.max_speed_hz = 4000000
|
||||||
self.SPI.mode = 0b00
|
self.SPI.mode = 0b00
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def module_exit(self):
|
def module_exit(self):
|
||||||
logger.debug("spi end")
|
logger.debug("spi end")
|
||||||
# self.SPI.close() #removed as it causes some problems
|
self.SPI.close()
|
||||||
|
|
||||||
|
self.GPIO_RST_PIN.off()
|
||||||
|
self.GPIO_DC_PIN.off()
|
||||||
|
self.GPIO_PWR_PIN.off()
|
||||||
|
|
||||||
|
self.GPIO_RST_PIN.close()
|
||||||
|
self.GPIO_DC_PIN.close()
|
||||||
|
# self.GPIO_CS_PIN.close()
|
||||||
|
self.GPIO_PWR_PIN.close()
|
||||||
|
self.GPIO_BUSY_PIN.close()
|
||||||
|
|
||||||
logger.debug("close 5V, Module enters 0 power consumption ...")
|
logger.debug("close 5V, Module enters 0 power consumption ...")
|
||||||
self.GPIO.output(self.RST_PIN, 0)
|
|
||||||
self.GPIO.output(self.DC_PIN, 0)
|
|
||||||
|
|
||||||
self.GPIO.cleanup()
|
|
||||||
|
|
||||||
|
|
||||||
class JetsonNano:
|
class JetsonNano:
|
||||||
@ -91,6 +130,7 @@ class JetsonNano:
|
|||||||
DC_PIN = 25
|
DC_PIN = 25
|
||||||
CS_PIN = 8
|
CS_PIN = 8
|
||||||
BUSY_PIN = 24
|
BUSY_PIN = 24
|
||||||
|
PWR_PIN = 18
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
import ctypes
|
import ctypes
|
||||||
@ -123,13 +163,21 @@ class JetsonNano:
|
|||||||
def spi_writebyte(self, data):
|
def spi_writebyte(self, data):
|
||||||
self.SPI.SYSFS_software_spi_transfer(data[0])
|
self.SPI.SYSFS_software_spi_transfer(data[0])
|
||||||
|
|
||||||
|
def spi_writebyte2(self, data):
|
||||||
|
for i in range(len(data)):
|
||||||
|
self.SPI.SYSFS_software_spi_transfer(data[i])
|
||||||
|
|
||||||
def module_init(self):
|
def module_init(self):
|
||||||
self.GPIO.setmode(self.GPIO.BCM)
|
self.GPIO.setmode(self.GPIO.BCM)
|
||||||
self.GPIO.setwarnings(False)
|
self.GPIO.setwarnings(False)
|
||||||
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
|
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
|
||||||
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
|
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
|
||||||
self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
|
self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
|
||||||
|
self.GPIO.setup(self.PWR_PIN, self.GPIO.OUT)
|
||||||
self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
|
self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
|
||||||
|
|
||||||
|
self.GPIO.output(self.PWR_PIN, 1)
|
||||||
|
|
||||||
self.SPI.SYSFS_software_spi_begin()
|
self.SPI.SYSFS_software_spi_begin()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -140,16 +188,93 @@ class JetsonNano:
|
|||||||
logger.debug("close 5V, Module enters 0 power consumption ...")
|
logger.debug("close 5V, Module enters 0 power consumption ...")
|
||||||
self.GPIO.output(self.RST_PIN, 0)
|
self.GPIO.output(self.RST_PIN, 0)
|
||||||
self.GPIO.output(self.DC_PIN, 0)
|
self.GPIO.output(self.DC_PIN, 0)
|
||||||
|
self.GPIO.output(self.PWR_PIN, 0)
|
||||||
|
|
||||||
self.GPIO.cleanup()
|
self.GPIO.cleanup([self.RST_PIN, self.DC_PIN, self.CS_PIN, self.BUSY_PIN, self.PWR_PIN])
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'):
|
class SunriseX3:
|
||||||
|
# Pin definition
|
||||||
|
RST_PIN = 17
|
||||||
|
DC_PIN = 25
|
||||||
|
CS_PIN = 8
|
||||||
|
BUSY_PIN = 24
|
||||||
|
PWR_PIN = 18
|
||||||
|
Flag = 0
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
import spidev
|
||||||
|
import Hobot.GPIO
|
||||||
|
|
||||||
|
self.GPIO = Hobot.GPIO
|
||||||
|
self.SPI = spidev.SpiDev()
|
||||||
|
|
||||||
|
def digital_write(self, pin, value):
|
||||||
|
self.GPIO.output(pin, value)
|
||||||
|
|
||||||
|
def digital_read(self, pin):
|
||||||
|
return self.GPIO.input(pin)
|
||||||
|
|
||||||
|
def delay_ms(self, delaytime):
|
||||||
|
time.sleep(delaytime / 1000.0)
|
||||||
|
|
||||||
|
def spi_writebyte(self, data):
|
||||||
|
self.SPI.writebytes(data)
|
||||||
|
|
||||||
|
def spi_writebyte2(self, data):
|
||||||
|
# for i in range(len(data)):
|
||||||
|
# self.SPI.writebytes([data[i]])
|
||||||
|
self.SPI.xfer3(data)
|
||||||
|
|
||||||
|
def module_init(self):
|
||||||
|
if self.Flag == 0:
|
||||||
|
self.Flag = 1
|
||||||
|
self.GPIO.setmode(self.GPIO.BCM)
|
||||||
|
self.GPIO.setwarnings(False)
|
||||||
|
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
|
||||||
|
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
|
||||||
|
self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
|
||||||
|
self.GPIO.setup(self.PWR_PIN, self.GPIO.OUT)
|
||||||
|
self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
|
||||||
|
|
||||||
|
self.GPIO.output(self.PWR_PIN, 1)
|
||||||
|
|
||||||
|
# SPI device, bus = 0, device = 0
|
||||||
|
self.SPI.open(2, 0)
|
||||||
|
self.SPI.max_speed_hz = 4000000
|
||||||
|
self.SPI.mode = 0b00
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def module_exit(self):
|
||||||
|
logger.debug("spi end")
|
||||||
|
self.SPI.close()
|
||||||
|
|
||||||
|
logger.debug("close 5V, Module enters 0 power consumption ...")
|
||||||
|
self.Flag = 0
|
||||||
|
self.GPIO.output(self.RST_PIN, 0)
|
||||||
|
self.GPIO.output(self.DC_PIN, 0)
|
||||||
|
self.GPIO.output(self.PWR_PIN, 0)
|
||||||
|
|
||||||
|
self.GPIO.cleanup([self.RST_PIN, self.DC_PIN, self.CS_PIN, self.BUSY_PIN], self.PWR_PIN)
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info[0] == 2:
|
||||||
|
process = subprocess.Popen("cat /proc/cpuinfo | grep Raspberry", shell=True, stdout=subprocess.PIPE)
|
||||||
|
else:
|
||||||
|
process = subprocess.Popen("cat /proc/cpuinfo | grep Raspberry", shell=True, stdout=subprocess.PIPE, text=True)
|
||||||
|
output, _ = process.communicate()
|
||||||
|
if sys.version_info[0] == 2:
|
||||||
|
output = output.decode(sys.stdout.encoding)
|
||||||
|
|
||||||
|
if "Raspberry" in output:
|
||||||
implementation = RaspberryPi()
|
implementation = RaspberryPi()
|
||||||
|
elif os.path.exists('/sys/bus/platform/drivers/gpio-x3'):
|
||||||
|
implementation = SunriseX3()
|
||||||
else:
|
else:
|
||||||
implementation = JetsonNano()
|
implementation = JetsonNano()
|
||||||
|
|
||||||
for func in [x for x in dir(implementation) if not x.startswith('_')]:
|
for func in [x for x in dir(implementation) if not x.startswith('_')]:
|
||||||
setattr(sys.modules[__name__], func, getattr(implementation, func))
|
setattr(sys.modules[__name__], func, getattr(implementation, func))
|
||||||
|
|
||||||
### END OF FILE ###
|
|
||||||
|
@ -1,39 +1,38 @@
|
|||||||
# /*****************************************************************************
|
"""
|
||||||
# * | File : epdconfig.py
|
* | File : epdconfig.py
|
||||||
# * | Author : Waveshare electrices
|
* | Author : Waveshare electrices
|
||||||
# * | Function : Hardware underlying interface
|
* | Function : Hardware underlying interface
|
||||||
# * | Info :
|
* | Info :
|
||||||
# *----------------
|
*----------------
|
||||||
# * | This version: V1.0
|
* | This version: V1.0
|
||||||
# * | Date : 2019-11-01
|
* | Date : 2019-11-01
|
||||||
# * | Info :
|
* | Info :
|
||||||
# ******************************************************************************/
|
******************************************************************************/
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documnetation files (the "Software"), to deal
|
of this software and associated documnetation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
# furished to do so, subject to the following conditions:
|
furished to do so, subject to the following conditions:
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
EPD_SCK_PIN = 11
|
EPD_SCK_PIN = 11
|
||||||
EPD_MOSI_PIN = 10
|
EPD_MOSI_PIN = 10
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
"""Image file driver for testing"""
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 800
|
EPD_WIDTH = 800
|
||||||
EPD_HEIGHT = 480
|
EPD_HEIGHT = 480
|
||||||
|
|
||||||
|
|
||||||
class EPD:
|
class EPD:
|
||||||
def init(self):
|
def init(self):
|
||||||
|
@ -98,6 +98,8 @@ class Inkycal:
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise SettingsFileNotFoundError
|
raise SettingsFileNotFoundError
|
||||||
|
|
||||||
|
self.disable_calibration = self.settings.get('disable_calibration', False)
|
||||||
|
|
||||||
if not os.path.exists(image_folder):
|
if not os.path.exists(image_folder):
|
||||||
os.mkdir(image_folder)
|
os.mkdir(image_folder)
|
||||||
|
|
||||||
@ -541,11 +543,16 @@ class Inkycal:
|
|||||||
|
|
||||||
def _calibration_check(self):
|
def _calibration_check(self):
|
||||||
"""Calibration scheduler
|
"""Calibration scheduler
|
||||||
uses calibration hours from settings file to check if calibration is due"""
|
uses calibration hours from settings file to check if calibration is due.
|
||||||
|
If no calibration hours are set, calibration is skipped."""
|
||||||
|
|
||||||
|
# Check if calibration hours are not set or the list is empty
|
||||||
|
if not self._calibration_hours:
|
||||||
|
print("No calibration hours set. Skipping calibration.")
|
||||||
|
return
|
||||||
|
|
||||||
now = arrow.now()
|
now = arrow.now()
|
||||||
# print('hour:', now.hour, 'hours:', self._calibration_hours)
|
if now.hour in self._calibration_hours and not self._calibration_state:
|
||||||
# print('state:', self._calibration_state)
|
|
||||||
if now.hour in self._calibration_hours and self._calibration_state == False:
|
|
||||||
self.calibrate()
|
self.calibrate()
|
||||||
self._calibration_state = True
|
self._calibration_state = True
|
||||||
else:
|
else:
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#!python3
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Third party module template (inkycal-compatible module)
|
Third party module template (inkycal-compatible module)
|
||||||
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#!python3
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Custom image class for Inkycal Project
|
Custom image class for Inkycal Project
|
||||||
Takes care of handling images. Made to be used by other modules to handle
|
Takes care of handling images. Made to be used by other modules to handle
|
||||||
@ -10,9 +7,10 @@ Copyright by aceinnolab
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import PIL
|
||||||
import numpy
|
import numpy
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -114,7 +112,7 @@ class Inkyimage:
|
|||||||
self.image = image
|
self.image = image
|
||||||
logger.info(f'flipped image by {angle} degrees')
|
logger.info(f'flipped image by {angle} degrees')
|
||||||
|
|
||||||
def autoflip(self, layout:str) -> None:
|
def autoflip(self, layout: str) -> None:
|
||||||
"""flips the image automatically to the given layout.
|
"""flips the image automatically to the given layout.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -215,7 +213,7 @@ class Inkyimage:
|
|||||||
|
|
||||||
return image1
|
return image1
|
||||||
|
|
||||||
def to_palette(self, palette, dither=True) -> (Image, Image):
|
def to_palette(self, palette, dither=True) -> (PIL.Image, PIL.Image):
|
||||||
"""Maps an image to a given colour palette.
|
"""Maps an image to a given colour palette.
|
||||||
|
|
||||||
Maps each pixel from the image to a colour from the palette.
|
Maps each pixel from the image to a colour from the palette.
|
||||||
@ -235,6 +233,7 @@ class Inkyimage:
|
|||||||
>>> 'bwr' # black-white-red
|
>>> 'bwr' # black-white-red
|
||||||
>>> 'bwy' # black-white-yellow
|
>>> 'bwy' # black-white-yellow
|
||||||
>>> 'bw' # black-white
|
>>> 'bw' # black-white
|
||||||
|
>>> '16gray' # 16 shades of gray
|
||||||
"""
|
"""
|
||||||
# Check if an image is loaded
|
# Check if an image is loaded
|
||||||
if self._image_loaded():
|
if self._image_loaded():
|
||||||
@ -252,6 +251,9 @@ class Inkyimage:
|
|||||||
|
|
||||||
elif palette == 'bw':
|
elif palette == 'bw':
|
||||||
pal = None
|
pal = None
|
||||||
|
elif palette == '16gray':
|
||||||
|
pal = [x for x in range(0, 256, 16)] * 3
|
||||||
|
pal.sort()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error('The given palette is unsupported.')
|
logger.error('The given palette is unsupported.')
|
||||||
@ -329,4 +331,3 @@ class Inkyimage:
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(f'running {__name__} in standalone/debug mode')
|
print(f'running {__name__} in standalone/debug mode')
|
||||||
|
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
#!python3
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Inkycal Image Module
|
Inkycal Image Module
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from inkycal.modules.template import inkycal_module
|
|
||||||
from inkycal.custom import *
|
from inkycal.custom import *
|
||||||
|
|
||||||
from inkycal.modules.inky_image import Inkyimage as Images
|
from inkycal.modules.inky_image import Inkyimage as Images
|
||||||
|
from inkycal.modules.template import inkycal_module
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -63,6 +60,9 @@ class Inkyimage(inkycal_module):
|
|||||||
self.palette = config['palette']
|
self.palette = config['palette']
|
||||||
self.autoflip = config['autoflip']
|
self.autoflip = config['autoflip']
|
||||||
self.orientation = config['orientation']
|
self.orientation = config['orientation']
|
||||||
|
self.dither = True
|
||||||
|
if 'dither' in config and config["dither"] == False:
|
||||||
|
self.dither = False
|
||||||
|
|
||||||
# give an OK message
|
# give an OK message
|
||||||
print(f'{__name__} loaded')
|
print(f'{__name__} loaded')
|
||||||
@ -94,7 +94,7 @@ class Inkyimage(inkycal_module):
|
|||||||
im.resize(width=im_width, height=im_height)
|
im.resize(width=im_width, height=im_height)
|
||||||
|
|
||||||
# convert images according to specified palette
|
# convert images according to specified palette
|
||||||
im_black, im_colour = im.to_palette(self.palette)
|
im_black, im_colour = im.to_palette(self.palette, self.dither)
|
||||||
|
|
||||||
# with the images now send, clear the current image
|
# with the images now send, clear the current image
|
||||||
im.clear()
|
im.clear()
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
#!python3
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Inkycal-server module for Inkycal Project
|
Inkycal-server module for Inkycal Project
|
||||||
by Aterju (https://inkycal.robertsirre.nl/)
|
by Aterju (https://inkycal.robertsirre.nl/)
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from inkycal.modules.template import inkycal_module
|
|
||||||
from inkycal.custom import *
|
from inkycal.custom import *
|
||||||
|
|
||||||
from inkycal.modules.inky_image import Inkyimage as Images
|
from inkycal.modules.inky_image import Inkyimage as Images
|
||||||
|
from inkycal.modules.template import inkycal_module
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
#!python3
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Inkycal Slideshow Module
|
Inkycal Slideshow Module
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
import glob
|
import glob
|
||||||
|
|
||||||
from inkycal.modules.template import inkycal_module
|
|
||||||
from inkycal.custom import *
|
from inkycal.custom import *
|
||||||
|
|
||||||
# PIL has a class named Image, use alias for Inkyimage -> Images
|
# PIL has a class named Image, use alias for Inkyimage -> Images
|
||||||
from inkycal.modules.inky_image import Inkyimage as Images
|
from inkycal.modules.inky_image import Inkyimage as Images
|
||||||
|
from inkycal.modules.template import inkycal_module
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
#!python3
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Inkycal weather module
|
Inkycal weather module
|
||||||
Copyright by aceinnolab
|
Copyright by aceinnolab
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from inkycal.modules.template import inkycal_module
|
|
||||||
from inkycal.custom import *
|
|
||||||
|
|
||||||
import math
|
|
||||||
import decimal
|
import decimal
|
||||||
|
import math
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
|
|
||||||
|
from inkycal.custom import *
|
||||||
from inkycal.custom import OpenWeatherMap
|
from inkycal.custom import OpenWeatherMap
|
||||||
|
from inkycal.modules.template import inkycal_module
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -95,7 +93,7 @@ class Weather(inkycal_module):
|
|||||||
self.use_beaufort = config['use_beaufort']
|
self.use_beaufort = config['use_beaufort']
|
||||||
|
|
||||||
# additional configuration
|
# additional configuration
|
||||||
self.owm = OpenWeatherMap(api_key=self.api_key, city_id=self.location, units=config['units'])
|
self.owm = OpenWeatherMap(api_key=self.api_key, city_id=self.location, units=config['units'])
|
||||||
self.timezone = get_system_tz()
|
self.timezone = get_system_tz()
|
||||||
self.locale = config['language']
|
self.locale = config['language']
|
||||||
self.weatherfont = ImageFont.truetype(
|
self.weatherfont = ImageFont.truetype(
|
||||||
@ -104,9 +102,8 @@ class Weather(inkycal_module):
|
|||||||
# give an OK message
|
# give an OK message
|
||||||
print(f"{__name__} loaded")
|
print(f"{__name__} loaded")
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def mps_to_beaufort(meters_per_second:float) -> int:
|
def mps_to_beaufort(meters_per_second: float) -> int:
|
||||||
"""Map meters per second to the beaufort scale.
|
"""Map meters per second to the beaufort scale.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -120,7 +117,7 @@ class Weather(inkycal_module):
|
|||||||
return next((i for i, threshold in enumerate(thresholds) if meters_per_second < threshold), 11)
|
return next((i for i, threshold in enumerate(thresholds) if meters_per_second < threshold), 11)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def mps_to_mph(meters_per_second:float) -> float:
|
def mps_to_mph(meters_per_second: float) -> float:
|
||||||
"""Map meters per second to miles per hour, rounded to one decimal place.
|
"""Map meters per second to miles per hour, rounded to one decimal place.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -135,7 +132,7 @@ class Weather(inkycal_module):
|
|||||||
return round(miles_per_hour, 1)
|
return round(miles_per_hour, 1)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def celsius_to_fahrenheit(celsius:int or float):
|
def celsius_to_fahrenheit(celsius: int or float):
|
||||||
"""Converts the given temperate from degrees Celsius to Fahrenheit."""
|
"""Converts the given temperate from degrees Celsius to Fahrenheit."""
|
||||||
fahrenheit = (celsius * 9 / 5) + 32
|
fahrenheit = (celsius * 9 / 5) + 32
|
||||||
return fahrenheit
|
return fahrenheit
|
||||||
@ -180,7 +177,8 @@ class Weather(inkycal_module):
|
|||||||
4: '\uf0a3',
|
4: '\uf0a3',
|
||||||
5: '\uf0a7',
|
5: '\uf0a7',
|
||||||
6: '\uf0aa',
|
6: '\uf0aa',
|
||||||
7: '\uf0ae'}[int(index) & 7]
|
7: '\uf0ae'
|
||||||
|
}[int(index) & 7]
|
||||||
|
|
||||||
def is_negative(temp):
|
def is_negative(temp):
|
||||||
"""Check if temp is below freezing point of water (0°C/30°F)
|
"""Check if temp is below freezing point of water (0°C/30°F)
|
||||||
@ -458,8 +456,9 @@ class Weather(inkycal_module):
|
|||||||
# Create a list containing time-objects for every 3rd hour of the day
|
# Create a list containing time-objects for every 3rd hour of the day
|
||||||
time_range = list(
|
time_range = list(
|
||||||
arrow.Arrow.range('hour',
|
arrow.Arrow.range('hour',
|
||||||
now.shift(days=days_from_today).floor('day'),now.shift(days=days_from_today).ceil('day')
|
now.shift(days=days_from_today).floor('day'),
|
||||||
))[::3]
|
now.shift(days=days_from_today).ceil('day')
|
||||||
|
))[::3]
|
||||||
|
|
||||||
# Get forecasts for each time-object
|
# Get forecasts for each time-object
|
||||||
forecasts = [_ for _ in forecast if arrow.get(_["dt"]) in time_range]
|
forecasts = [_ for _ in forecast if arrow.get(_["dt"]) in time_range]
|
||||||
@ -493,7 +492,7 @@ class Weather(inkycal_module):
|
|||||||
if dec_temp != 0:
|
if dec_temp != 0:
|
||||||
temperature = f"{round(weather['main']['temp'])}°"
|
temperature = f"{round(weather['main']['temp'])}°"
|
||||||
else:
|
else:
|
||||||
temperature = f"{round(weather['main']['temp'],ndigits=dec_temp)}°"
|
temperature = f"{round(weather['main']['temp'], ndigits=dec_temp)}°"
|
||||||
|
|
||||||
weather_icon = weather["weather"][0]["icon"]
|
weather_icon = weather["weather"][0]["icon"]
|
||||||
humidity = str(weather["main"]["humidity"])
|
humidity = str(weather["main"]["humidity"])
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!python3
|
"""Inkycal module template"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
from inkycal.custom import *
|
from inkycal.custom import *
|
||||||
|
|
||||||
|
|
||||||
|
3
setup.py
3
setup.py
@ -1,7 +1,6 @@
|
|||||||
#!python3
|
from os import path
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from os import path
|
|
||||||
|
|
||||||
this_directory = path.abspath(path.dirname(__file__))
|
this_directory = path.abspath(path.dirname(__file__))
|
||||||
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
|
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
|
||||||
|
@ -14,7 +14,7 @@ from tests import Config
|
|||||||
preview = Inkyimage.preview
|
preview = Inkyimage.preview
|
||||||
merge = Inkyimage.merge
|
merge = Inkyimage.merge
|
||||||
|
|
||||||
url = "https://github.com/aceinnolab/Inkycal/raw/assets/Repo/coffee.png"
|
url ="https://raw.githubusercontent.com/aceinnolab/Inkycal/assets/tests/mark-harpur-unsplash.jpg"
|
||||||
|
|
||||||
im = Image.open(requests.get(url, stream=True).raw)
|
im = Image.open(requests.get(url, stream=True).raw)
|
||||||
im.save("test.png", "PNG")
|
im.save("test.png", "PNG")
|
||||||
@ -27,9 +27,9 @@ tests = [
|
|||||||
{
|
{
|
||||||
"name": "Inkyimage",
|
"name": "Inkyimage",
|
||||||
"config": {
|
"config": {
|
||||||
"size": [400, 200],
|
"size": [800, 600],
|
||||||
"path": test_path,
|
"path": test_path,
|
||||||
"palette": "bwr",
|
"palette": "16gray",
|
||||||
"autoflip": True,
|
"autoflip": True,
|
||||||
"orientation": "vertical",
|
"orientation": "vertical",
|
||||||
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en"
|
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en"
|
||||||
|
Loading…
Reference in New Issue
Block a user