plop
This commit is contained in:
parent
ce52a1d155
commit
3fb3c4f63f
10 changed files with 1079 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
.venv/
|
||||||
|
*.png
|
||||||
|
*.bpm
|
||||||
|
*.json
|
||||||
18
display.py
Normal file
18
display.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
from lib import epd4in2
|
||||||
|
import os
|
||||||
|
#picdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),'pic'
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
epd = epd4in2.EPD()
|
||||||
|
epd.init()
|
||||||
|
|
||||||
|
image = Image.open('./document_ready.bmp')
|
||||||
|
image = image.convert('L')
|
||||||
|
epd.display_4Gray(epd.getbuffer_4Gray(image))
|
||||||
|
epd.sleep()
|
||||||
|
|
||||||
|
## version grayscale
|
||||||
|
#epd.Init_4Gray()
|
||||||
|
#Himage = Image.open(os.path.join(picdir, 'book_base.bmp'))
|
||||||
|
#epd.display_4Gray(epd.getbuffer_4Gray(Himage))
|
||||||
|
|
||||||
43
document.typ
Normal file
43
document.typ
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#set page(width: 86mm, height: 65mm)
|
||||||
|
|
||||||
|
#let weekdays = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
|
||||||
|
#let today = datetime.today()
|
||||||
|
#let weather = json("weather.json")
|
||||||
|
|
||||||
|
#align(center)[
|
||||||
|
#text(size:2em)[#today.display("[weekday] [month repr:long] [year]")]
|
||||||
|
|
||||||
|
#box(
|
||||||
|
stroke: 0.2em+black
|
||||||
|
)[
|
||||||
|
#grid(
|
||||||
|
columns: (1fr,1fr,1fr,1fr,1fr,1fr,1fr),
|
||||||
|
inset:0.5em,
|
||||||
|
rows:1,
|
||||||
|
align:center,
|
||||||
|
fill: (x, _) =>
|
||||||
|
if x>4 { luma(240) }
|
||||||
|
else { white },
|
||||||
|
|
||||||
|
stroke: (x, _) =>
|
||||||
|
if x== weekdays.position(it => {it == today.display("[weekday repr:short]")}) {0.15em+black}
|
||||||
|
else { none},
|
||||||
|
[Lun],[Mar],[Mer],[Jeu],[Ven],[Sam],[Dim]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
#let icon = none
|
||||||
|
#if weather.current.weather_code == 0{
|
||||||
|
icon = image("icons/sun.svg", width:3em)
|
||||||
|
}
|
||||||
|
|
||||||
|
#grid(
|
||||||
|
columns: (1fr,4fr),
|
||||||
|
align: (center+horizon, left+horizon),
|
||||||
|
[#icon],[#text(size:3em)[#weather.current.temperature_2m #weather.current_units.temperature_2m]]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
1
icons/sun.svg
Normal file
1
icons/sun.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M210.2 53.9C217.6 50.8 226 51.7 232.7 56.1L320.5 114.3L408.3 56.1C415 51.7 423.4 50.9 430.8 53.9C438.2 56.9 443.4 63.5 445 71.3L465.9 174.5L569.1 195.4C576.9 197 583.5 202.4 586.5 209.7C589.5 217 588.7 225.5 584.3 232.2L526.1 320L584.3 407.8C588.7 414.5 589.5 422.9 586.5 430.3C583.5 437.7 576.9 443.1 569.1 444.6L465.8 465.4L445 568.7C443.4 576.5 438 583.1 430.7 586.1C423.4 589.1 414.9 588.3 408.2 583.9L320.4 525.7L232.6 583.9C225.9 588.3 217.5 589.1 210.1 586.1C202.7 583.1 197.3 576.5 195.8 568.7L175 465.4L71.7 444.5C63.9 442.9 57.3 437.5 54.3 430.2C51.3 422.9 52.1 414.4 56.5 407.7L114.7 320L56.5 232.2C52.1 225.5 51.3 217.1 54.3 209.7C57.3 202.3 63.9 196.9 71.7 195.4L175 174.6L195.9 71.3C197.5 63.5 202.9 56.9 210.2 53.9zM239.6 320C239.6 275.6 275.6 239.6 320 239.6C364.4 239.6 400.4 275.6 400.4 320C400.4 364.4 364.4 400.4 320 400.4C275.6 400.4 239.6 364.4 239.6 320zM448.4 320C448.4 249.1 390.9 191.6 320 191.6C249.1 191.6 191.6 249.1 191.6 320C191.6 390.9 249.1 448.4 320 448.4C390.9 448.4 448.4 390.9 448.4 320z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
BIN
lib/__pycache__/epd4in2.cpython-311.pyc
Normal file
BIN
lib/__pycache__/epd4in2.cpython-311.pyc
Normal file
Binary file not shown.
BIN
lib/__pycache__/epdconfig.cpython-311.pyc
Normal file
BIN
lib/__pycache__/epdconfig.cpython-311.pyc
Normal file
Binary file not shown.
678
lib/epd4in2.py
Normal file
678
lib/epd4in2.py
Normal file
|
|
@ -0,0 +1,678 @@
|
||||||
|
# *****************************************************************************
|
||||||
|
# * | File : epd4in2.py
|
||||||
|
# * | Author : Waveshare team
|
||||||
|
# * | Function : Electronic paper driver
|
||||||
|
# * | Info :
|
||||||
|
# *----------------
|
||||||
|
# * | This version: V4.2
|
||||||
|
# * | Date : 2022-10-29
|
||||||
|
# # | Info : python demo
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documnetation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# 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 logging
|
||||||
|
from . import epdconfig
|
||||||
|
from PIL import Image
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
|
# Display resolution
|
||||||
|
EPD_WIDTH = 400
|
||||||
|
EPD_HEIGHT = 300
|
||||||
|
|
||||||
|
GRAY1 = 0xff # white
|
||||||
|
GRAY2 = 0xC0
|
||||||
|
GRAY3 = 0x80 # gray
|
||||||
|
GRAY4 = 0x00 # Blackest
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class EPD:
|
||||||
|
def __init__(self):
|
||||||
|
self.reset_pin = epdconfig.RST_PIN
|
||||||
|
self.dc_pin = epdconfig.DC_PIN
|
||||||
|
self.busy_pin = epdconfig.BUSY_PIN
|
||||||
|
self.cs_pin = epdconfig.CS_PIN
|
||||||
|
self.width = EPD_WIDTH
|
||||||
|
self.height = EPD_HEIGHT
|
||||||
|
self.GRAY1 = GRAY1 # white
|
||||||
|
self.GRAY2 = GRAY2
|
||||||
|
self.GRAY3 = GRAY3 # gray
|
||||||
|
self.GRAY4 = GRAY4 # Blackest
|
||||||
|
self.DATA = [0x00] * 15000
|
||||||
|
|
||||||
|
lut_vcom0 = [
|
||||||
|
0x00, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
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_ww = [
|
||||||
|
0x50, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
|
||||||
|
0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
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_bw = [
|
||||||
|
0x50, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
|
||||||
|
0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
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_wb = [
|
||||||
|
0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
|
||||||
|
0x50, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
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_bb = [
|
||||||
|
0x20, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
|
||||||
|
0x10, 0x08, 0x08, 0x00, 0x00, 0x02,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
# ******************************partial screen update LUT*********************************/
|
||||||
|
EPD_4IN2_Partial_lut_vcom1 = [
|
||||||
|
0x00, 0x01, 0x20, 0x01, 0x00, 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,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
|
||||||
|
EPD_4IN2_Partial_lut_ww1 = [
|
||||||
|
0x00, 0x01, 0x20, 0x01, 0x00, 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,
|
||||||
|
]
|
||||||
|
|
||||||
|
EPD_4IN2_Partial_lut_bw1 = [
|
||||||
|
0x20, 0x01, 0x20, 0x01, 0x00, 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,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
|
||||||
|
EPD_4IN2_Partial_lut_wb1 = [
|
||||||
|
0x10, 0x01, 0x20, 0x01, 0x00, 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,
|
||||||
|
]
|
||||||
|
|
||||||
|
EPD_4IN2_Partial_lut_bb1 = [
|
||||||
|
0x00, 0x01, 0x20, 0x01, 0x00, 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,
|
||||||
|
]
|
||||||
|
|
||||||
|
# ******************************gray*********************************/
|
||||||
|
# 0~3 gray
|
||||||
|
EPD_4IN2_4Gray_lut_vcom = [
|
||||||
|
0x00, 0x0A, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x60, 0x14, 0x14, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x13, 0x0A, 0x01, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
]
|
||||||
|
# R21
|
||||||
|
EPD_4IN2_4Gray_lut_ww = [
|
||||||
|
0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
|
||||||
|
0x10, 0x14, 0x0A, 0x00, 0x00, 0x01,
|
||||||
|
0xA0, 0x13, 0x01, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
# R22H r
|
||||||
|
EPD_4IN2_4Gray_lut_bw = [
|
||||||
|
0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x14, 0x0A, 0x00, 0x00, 0x01,
|
||||||
|
0x99, 0x0C, 0x01, 0x03, 0x04, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
# R23H w
|
||||||
|
EPD_4IN2_4Gray_lut_wb = [
|
||||||
|
0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x14, 0x0A, 0x00, 0x00, 0x01,
|
||||||
|
0x99, 0x0B, 0x04, 0x04, 0x01, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
# R24H b
|
||||||
|
EPD_4IN2_4Gray_lut_bb = [
|
||||||
|
0x80, 0x0A, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
|
||||||
|
0x20, 0x14, 0x0A, 0x00, 0x00, 0x01,
|
||||||
|
0x50, 0x13, 0x01, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Hardware reset
|
||||||
|
def reset(self):
|
||||||
|
epdconfig.digital_write(self.reset_pin, 1)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
epdconfig.digital_write(self.reset_pin, 0)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
epdconfig.digital_write(self.reset_pin, 1)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
epdconfig.digital_write(self.reset_pin, 0)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
epdconfig.digital_write(self.reset_pin, 1)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
epdconfig.digital_write(self.reset_pin, 0)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
epdconfig.digital_write(self.reset_pin, 1)
|
||||||
|
epdconfig.delay_ms(10)
|
||||||
|
|
||||||
|
def send_command(self, command):
|
||||||
|
epdconfig.digital_write(self.dc_pin, 0)
|
||||||
|
epdconfig.digital_write(self.cs_pin, 0)
|
||||||
|
epdconfig.spi_writebyte([command])
|
||||||
|
epdconfig.digital_write(self.cs_pin, 1)
|
||||||
|
|
||||||
|
def send_data(self, data):
|
||||||
|
epdconfig.digital_write(self.dc_pin, 1)
|
||||||
|
epdconfig.digital_write(self.cs_pin, 0)
|
||||||
|
epdconfig.spi_writebyte([data])
|
||||||
|
epdconfig.digital_write(self.cs_pin, 1)
|
||||||
|
|
||||||
|
# send a lot of data
|
||||||
|
def send_data2(self, data):
|
||||||
|
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):
|
||||||
|
self.send_command(0x71)
|
||||||
|
while epdconfig.digital_read(self.busy_pin) == 0: # 0: idle, 1: busy
|
||||||
|
self.send_command(0x71)
|
||||||
|
epdconfig.delay_ms(100)
|
||||||
|
|
||||||
|
def set_lut(self):
|
||||||
|
self.send_command(0x20) # vcom
|
||||||
|
self.send_data2(self.lut_vcom0)
|
||||||
|
|
||||||
|
self.send_command(0x21) # ww --
|
||||||
|
self.send_data2(self.lut_ww)
|
||||||
|
|
||||||
|
self.send_command(0x22) # bw r
|
||||||
|
self.send_data2(self.lut_bw)
|
||||||
|
|
||||||
|
self.send_command(0x23) # wb w
|
||||||
|
self.send_data2(self.lut_bb)
|
||||||
|
|
||||||
|
self.send_command(0x24) # bb b
|
||||||
|
self.send_data2(self.lut_wb)
|
||||||
|
|
||||||
|
def Partial_SetLut(self):
|
||||||
|
self.send_command(0x20)
|
||||||
|
self.send_data2(self.EPD_4IN2_Partial_lut_vcom1)
|
||||||
|
|
||||||
|
self.send_command(0x21)
|
||||||
|
self.send_data2(self.EPD_4IN2_Partial_lut_ww1)
|
||||||
|
|
||||||
|
self.send_command(0x22)
|
||||||
|
self.send_data2(self.EPD_4IN2_Partial_lut_bw1)
|
||||||
|
|
||||||
|
self.send_command(0x23)
|
||||||
|
self.send_data2(self.EPD_4IN2_Partial_lut_wb1)
|
||||||
|
|
||||||
|
self.send_command(0x24)
|
||||||
|
self.send_data2(self.EPD_4IN2_Partial_lut_bb1)
|
||||||
|
|
||||||
|
def Gray_SetLut(self):
|
||||||
|
self.send_command(0x20) # vcom
|
||||||
|
self.send_data2(self.EPD_4IN2_4Gray_lut_vcom)
|
||||||
|
|
||||||
|
self.send_command(0x21) # red not use
|
||||||
|
self.send_data2(self.EPD_4IN2_4Gray_lut_ww)
|
||||||
|
|
||||||
|
self.send_command(0x22) # bw r
|
||||||
|
self.send_data2(self.EPD_4IN2_4Gray_lut_bw)
|
||||||
|
|
||||||
|
self.send_command(0x23) # wb w
|
||||||
|
self.send_data2(self.EPD_4IN2_4Gray_lut_wb)
|
||||||
|
|
||||||
|
self.send_command(0x24) # bb b
|
||||||
|
self.send_data2(self.EPD_4IN2_4Gray_lut_bb)
|
||||||
|
|
||||||
|
self.send_command(0x25) # vcom
|
||||||
|
self.send_data2(self.EPD_4IN2_4Gray_lut_ww)
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
if epdconfig.module_init() != 0:
|
||||||
|
return -1
|
||||||
|
# EPD hardware init start
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
self.send_command(0x01) # POWER SETTING
|
||||||
|
self.send_data(0x03) # VDS_EN, VDG_EN
|
||||||
|
self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
|
||||||
|
self.send_data(0x2b) # VDH
|
||||||
|
self.send_data(0x2b) # VDL
|
||||||
|
|
||||||
|
self.send_command(0x06) # boost soft start
|
||||||
|
self.send_data(0x17)
|
||||||
|
self.send_data(0x17)
|
||||||
|
self.send_data(0x17)
|
||||||
|
|
||||||
|
self.send_command(0x04) # POWER_ON
|
||||||
|
self.ReadBusy()
|
||||||
|
|
||||||
|
self.send_command(0x00) # panel setting
|
||||||
|
self.send_data(0xbf) # KW-BF KWR-AF BWROTP 0f
|
||||||
|
|
||||||
|
self.send_command(0x30) # PLL setting
|
||||||
|
self.send_data(0x3c) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
|
||||||
|
|
||||||
|
self.send_command(0x61) # resolution setting
|
||||||
|
self.send_data(0x01)
|
||||||
|
self.send_data(0x90) # 128
|
||||||
|
self.send_data(0x01)
|
||||||
|
self.send_data(0x2c)
|
||||||
|
|
||||||
|
self.send_command(0x82) # vcom_DC setting
|
||||||
|
self.send_data(0x12)
|
||||||
|
|
||||||
|
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
|
||||||
|
self.send_data(
|
||||||
|
0x97) # 97white border 77black border VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
|
||||||
|
|
||||||
|
self.set_lut()
|
||||||
|
# EPD hardware init end
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def init_Partial(self):
|
||||||
|
if epdconfig.module_init() != 0:
|
||||||
|
return -1
|
||||||
|
# EPD hardware init start
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
self.send_command(0x01) # POWER SETTING
|
||||||
|
self.send_data(0x03) # VDS_EN, VDG_EN
|
||||||
|
self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
|
||||||
|
self.send_data(0x2b) # VDH
|
||||||
|
self.send_data(0x2b) # VDL
|
||||||
|
|
||||||
|
self.send_command(0x06) # boost soft start
|
||||||
|
self.send_data(0x17)
|
||||||
|
self.send_data(0x17)
|
||||||
|
self.send_data(0x17)
|
||||||
|
|
||||||
|
self.send_command(0x04) # POWER_ON
|
||||||
|
self.ReadBusy()
|
||||||
|
|
||||||
|
self.send_command(0x00) # panel setting
|
||||||
|
self.send_data(0xbf) # KW-BF KWR-AF BWROTP 0f
|
||||||
|
|
||||||
|
self.send_command(0x30) # PLL setting
|
||||||
|
self.send_data(0x3c) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
|
||||||
|
|
||||||
|
self.send_command(0x61) # resolution setting
|
||||||
|
self.send_data(0x01)
|
||||||
|
self.send_data(0x90) # 128
|
||||||
|
self.send_data(0x01)
|
||||||
|
self.send_data(0x2c)
|
||||||
|
|
||||||
|
self.send_command(0x82) # vcom_DC setting
|
||||||
|
self.send_data(0x12)
|
||||||
|
|
||||||
|
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
|
||||||
|
self.send_data(
|
||||||
|
0x07) # 97white border 77black border VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
|
||||||
|
|
||||||
|
self.Partial_SetLut()
|
||||||
|
# EPD hardware init end
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def Init_4Gray(self):
|
||||||
|
if epdconfig.module_init() != 0:
|
||||||
|
return -1
|
||||||
|
# EPD hardware init start
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
self.send_command(0x01) # POWER SETTING
|
||||||
|
self.send_data(0x03)
|
||||||
|
self.send_data(0x00) # VGH=20V,VGL=-20V
|
||||||
|
self.send_data(0x2b) # VDH=15V
|
||||||
|
self.send_data(0x2b) # VDL=-15V
|
||||||
|
self.send_data(0x13)
|
||||||
|
|
||||||
|
self.send_command(0x06) # booster soft start
|
||||||
|
self.send_data(0x17) # A
|
||||||
|
self.send_data(0x17) # B
|
||||||
|
self.send_data(0x17) # C
|
||||||
|
|
||||||
|
self.send_command(0x04)
|
||||||
|
self.ReadBusy()
|
||||||
|
|
||||||
|
self.send_command(0x00) # panel setting
|
||||||
|
self.send_data(0x3f) # KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
||||||
|
|
||||||
|
self.send_command(0x30) # PLL setting
|
||||||
|
self.send_data(0x3c) # 100hz
|
||||||
|
|
||||||
|
self.send_command(0x61) # resolution setting
|
||||||
|
self.send_data(0x01) # 400
|
||||||
|
self.send_data(0x90)
|
||||||
|
self.send_data(0x01) # 300
|
||||||
|
self.send_data(0x2c)
|
||||||
|
|
||||||
|
self.send_command(0x82) # vcom_DC setting
|
||||||
|
self.send_data(0x12)
|
||||||
|
|
||||||
|
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
|
||||||
|
self.send_data(0x97)
|
||||||
|
|
||||||
|
def getbuffer(self, image):
|
||||||
|
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||||
|
buf = [0xFF] * (int(self.width / 8) * self.height)
|
||||||
|
image_monocolor = image.convert('1')
|
||||||
|
imwidth, imheight = image_monocolor.size
|
||||||
|
pixels = image_monocolor.load()
|
||||||
|
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
||||||
|
if imwidth == self.width and imheight == self.height:
|
||||||
|
logger.debug("Horizontal")
|
||||||
|
for y in range(imheight):
|
||||||
|
for x in range(imwidth):
|
||||||
|
# Set the bits for the column of pixels at the current position.
|
||||||
|
if pixels[x, y] == 0:
|
||||||
|
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||||
|
elif imwidth == self.height and imheight == self.width:
|
||||||
|
logger.debug("Vertical")
|
||||||
|
for y in range(imheight):
|
||||||
|
for x in range(imwidth):
|
||||||
|
newx = y
|
||||||
|
newy = self.height - x - 1
|
||||||
|
if pixels[x, y] == 0:
|
||||||
|
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def getbuffer_4Gray(self, image):
|
||||||
|
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||||
|
buf = [0xFF] * (int(self.width / 4) * self.height)
|
||||||
|
image_monocolor = image.convert('L')
|
||||||
|
imwidth, imheight = image_monocolor.size
|
||||||
|
pixels = image_monocolor.load()
|
||||||
|
i = 0
|
||||||
|
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
||||||
|
if imwidth == self.width and imheight == self.height:
|
||||||
|
logger.debug("Vertical")
|
||||||
|
for y in range(imheight):
|
||||||
|
for x in range(imwidth):
|
||||||
|
# Set the bits for the column of pixels at the current position.
|
||||||
|
if pixels[x, y] == 0xC0:
|
||||||
|
pixels[x, y] = 0x80
|
||||||
|
elif pixels[x, y] == 0x80:
|
||||||
|
pixels[x, y] = 0x40
|
||||||
|
i = i + 1
|
||||||
|
if i % 4 == 0:
|
||||||
|
buf[int((x + (y * self.width)) / 4)] = (
|
||||||
|
(pixels[x - 3, y] & 0xc0) | (pixels[x - 2, y] & 0xc0) >> 2 | (
|
||||||
|
pixels[x - 1, y] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
||||||
|
|
||||||
|
elif imwidth == self.height and imheight == self.width:
|
||||||
|
logger.debug("Horizontal")
|
||||||
|
for x in range(imwidth):
|
||||||
|
for y in range(imheight):
|
||||||
|
newx = y
|
||||||
|
newy = x
|
||||||
|
if pixels[x, y] == 0xC0:
|
||||||
|
pixels[x, y] = 0x80
|
||||||
|
elif pixels[x, y] == 0x80:
|
||||||
|
pixels[x, y] = 0x40
|
||||||
|
i = i + 1
|
||||||
|
if i % 4 == 0:
|
||||||
|
buf[int((newx + (newy * self.width)) / 4)] = (
|
||||||
|
(pixels[x, y - 3] & 0xc0) | (pixels[x, y - 2] & 0xc0) >> 2 | (
|
||||||
|
pixels[x, y - 1] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
||||||
|
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def display(self, image):
|
||||||
|
if self.width % 8 == 0:
|
||||||
|
linewidth = int(self.width / 8)
|
||||||
|
else:
|
||||||
|
linewidth = int(self.width / 8) + 1
|
||||||
|
|
||||||
|
self.send_command(0x92)
|
||||||
|
self.set_lut()
|
||||||
|
self.send_command(0x10)
|
||||||
|
self.send_data2([0xFF] * int(self.width * linewidth))
|
||||||
|
|
||||||
|
self.send_command(0x13)
|
||||||
|
self.send_data2(image)
|
||||||
|
|
||||||
|
self.send_command(0x12)
|
||||||
|
self.ReadBusy()
|
||||||
|
|
||||||
|
def EPD_4IN2_PartialDisplay(self, X_start, Y_start, X_end, Y_end, Image):
|
||||||
|
# EPD_WIDTH = 400
|
||||||
|
# EPD_HEIGHT = 300
|
||||||
|
|
||||||
|
if EPD_WIDTH % 8 != 0:
|
||||||
|
Width = int(EPD_WIDTH / 8) + 1
|
||||||
|
else:
|
||||||
|
Width = int(EPD_WIDTH / 8)
|
||||||
|
Height = EPD_HEIGHT
|
||||||
|
|
||||||
|
if X_start % 8 != 0:
|
||||||
|
X_start = int(X_start / 8) + 1
|
||||||
|
else:
|
||||||
|
X_start = int(X_start / 8)
|
||||||
|
if X_end % 8 != 0:
|
||||||
|
X_end = int(X_end / 8) + 1
|
||||||
|
else:
|
||||||
|
X_end = int(X_end / 8)
|
||||||
|
|
||||||
|
buf = [0x00] * (Y_end - Y_start) * (X_end - X_start)
|
||||||
|
|
||||||
|
self.send_command(0x91) # This command makes the display enter partial mode
|
||||||
|
self.send_command(0x90) # resolution setting
|
||||||
|
self.send_data(int(X_start * 8 / 256))
|
||||||
|
self.send_data(int(X_start * 8 % 256)) # x-start
|
||||||
|
|
||||||
|
self.send_data(int(X_end * 8 / 256))
|
||||||
|
self.send_data(int(X_end * 8 % 256) - 1) # x-end
|
||||||
|
|
||||||
|
self.send_data(int(Y_start / 256))
|
||||||
|
self.send_data(int(Y_start % 256)) # y-start
|
||||||
|
|
||||||
|
self.send_data(int(Y_end / 256))
|
||||||
|
self.send_data(int(Y_end % 256) - 1) # y-end
|
||||||
|
self.send_data(0x28)
|
||||||
|
|
||||||
|
self.send_command(0x10) # writes Old data to SRAM for programming
|
||||||
|
for j in range(0, Y_end - Y_start):
|
||||||
|
for i in range(0, X_end - X_start):
|
||||||
|
buf[j * (X_end - X_start) + i] = self.DATA[(Y_start + j) * Width + X_start + i]
|
||||||
|
self.send_data2(buf)
|
||||||
|
|
||||||
|
self.send_command(0x13) # writes New data to SRAM.
|
||||||
|
for j in range(0, Y_end - Y_start):
|
||||||
|
for i in range(0, X_end - X_start):
|
||||||
|
buf[j * (X_end - X_start) + i] = ~Image[(Y_start + j) * Width + X_start + i]
|
||||||
|
self.DATA[(Y_start + j) * Width + X_start + i] = ~Image[(Y_start + j) * Width + X_start / 8 + i]
|
||||||
|
self.send_data2(buf)
|
||||||
|
|
||||||
|
self.send_command(0x12) # DISPLAY REFRESH
|
||||||
|
epdconfig.delay_ms(200) # The delay here is necessary, 200uS at least!!!
|
||||||
|
self.ReadBusy()
|
||||||
|
|
||||||
|
def display_4Gray(self, image):
|
||||||
|
self.send_command(0x92)
|
||||||
|
self.set_lut()
|
||||||
|
self.send_command(0x10)
|
||||||
|
|
||||||
|
if self.width % 8 == 0:
|
||||||
|
linewidth = int(self.width / 8)
|
||||||
|
else:
|
||||||
|
linewidth = int(self.width / 8) + 1
|
||||||
|
|
||||||
|
buf = [0x00] * self.height * linewidth
|
||||||
|
|
||||||
|
for i in range(0, int(EPD_WIDTH * EPD_HEIGHT / 8)): # EPD_WIDTH * EPD_HEIGHT / 4
|
||||||
|
temp3 = 0
|
||||||
|
for j in range(0, 2):
|
||||||
|
temp1 = image[i * 2 + j]
|
||||||
|
for k in range(0, 2):
|
||||||
|
temp2 = temp1 & 0xC0
|
||||||
|
if temp2 == 0xC0:
|
||||||
|
temp3 |= 0x01 # white
|
||||||
|
elif temp2 == 0x00:
|
||||||
|
temp3 |= 0x00 # black
|
||||||
|
elif temp2 == 0x80:
|
||||||
|
temp3 |= 0x01 # gray1
|
||||||
|
else: # 0x40
|
||||||
|
temp3 |= 0x00 # gray2
|
||||||
|
temp3 <<= 1
|
||||||
|
|
||||||
|
temp1 <<= 2
|
||||||
|
temp2 = temp1 & 0xC0
|
||||||
|
if temp2 == 0xC0: # white
|
||||||
|
temp3 |= 0x01
|
||||||
|
elif temp2 == 0x00: # black
|
||||||
|
temp3 |= 0x00
|
||||||
|
elif temp2 == 0x80:
|
||||||
|
temp3 |= 0x01 # gray1
|
||||||
|
else: # 0x40
|
||||||
|
temp3 |= 0x00 # gray2
|
||||||
|
if j != 1 or k != 1:
|
||||||
|
temp3 <<= 1
|
||||||
|
temp1 <<= 2
|
||||||
|
buf[i] = temp3
|
||||||
|
self.send_data2(buf)
|
||||||
|
|
||||||
|
self.send_command(0x13)
|
||||||
|
|
||||||
|
for i in range(0, int(EPD_WIDTH * EPD_HEIGHT / 8)): # 5808*4 46464
|
||||||
|
temp3 = 0
|
||||||
|
for j in range(0, 2):
|
||||||
|
temp1 = image[i * 2 + j]
|
||||||
|
for k in range(0, 2):
|
||||||
|
temp2 = temp1 & 0xC0
|
||||||
|
if temp2 == 0xC0:
|
||||||
|
temp3 |= 0x01 # white
|
||||||
|
elif temp2 == 0x00:
|
||||||
|
temp3 |= 0x00 # black
|
||||||
|
elif temp2 == 0x80:
|
||||||
|
temp3 |= 0x00 # gray1
|
||||||
|
else: # 0x40
|
||||||
|
temp3 |= 0x01 # gray2
|
||||||
|
temp3 <<= 1
|
||||||
|
|
||||||
|
temp1 <<= 2
|
||||||
|
temp2 = temp1 & 0xC0
|
||||||
|
if temp2 == 0xC0: # white
|
||||||
|
temp3 |= 0x01
|
||||||
|
elif temp2 == 0x00: # black
|
||||||
|
temp3 |= 0x00
|
||||||
|
elif temp2 == 0x80:
|
||||||
|
temp3 |= 0x00 # gray1
|
||||||
|
else: # 0x40
|
||||||
|
temp3 |= 0x01 # gray2
|
||||||
|
if j != 1 or k != 1:
|
||||||
|
temp3 <<= 1
|
||||||
|
temp1 <<= 2
|
||||||
|
buf[i] = temp3
|
||||||
|
self.send_data2(buf)
|
||||||
|
|
||||||
|
self.Gray_SetLut()
|
||||||
|
self.send_command(0x12)
|
||||||
|
epdconfig.delay_ms(200)
|
||||||
|
self.ReadBusy()
|
||||||
|
# pass
|
||||||
|
|
||||||
|
def Clear(self):
|
||||||
|
if self.width % 8 == 0:
|
||||||
|
linewidth = int(self.width / 8)
|
||||||
|
else:
|
||||||
|
linewidth = int(self.width / 8) + 1
|
||||||
|
|
||||||
|
self.send_command(0x10)
|
||||||
|
self.send_data2([0xff] * int(self.height * linewidth))
|
||||||
|
|
||||||
|
self.send_command(0x13)
|
||||||
|
self.send_data2([0xff] * int(self.height * linewidth))
|
||||||
|
|
||||||
|
self.send_command(0x12)
|
||||||
|
self.ReadBusy()
|
||||||
|
|
||||||
|
def sleep(self):
|
||||||
|
self.send_command(0x02) # POWER_OFF
|
||||||
|
self.ReadBusy()
|
||||||
|
self.send_command(0x07) # DEEP_SLEEP
|
||||||
|
self.send_data(0XA5)
|
||||||
|
|
||||||
|
epdconfig.delay_ms(2000)
|
||||||
|
epdconfig.module_exit()
|
||||||
|
|
||||||
|
### END OF FILE ###
|
||||||
322
lib/epdconfig.py
Normal file
322
lib/epdconfig.py
Normal file
|
|
@ -0,0 +1,322 @@
|
||||||
|
# /*****************************************************************************
|
||||||
|
# * | File : epdconfig.py
|
||||||
|
# * | Author : Waveshare team
|
||||||
|
# * | Function : Hardware underlying interface
|
||||||
|
# * | Info :
|
||||||
|
# *----------------
|
||||||
|
# * | This version: V1.2
|
||||||
|
# * | Date : 2022-10-29
|
||||||
|
# * | Info :
|
||||||
|
# ******************************************************************************
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documnetation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# 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 os
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from ctypes import *
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class RaspberryPi:
|
||||||
|
# Pin definition
|
||||||
|
RST_PIN = 17
|
||||||
|
DC_PIN = 25
|
||||||
|
CS_PIN = 8
|
||||||
|
BUSY_PIN = 24
|
||||||
|
PWR_PIN = 18
|
||||||
|
MOSI_PIN = 10
|
||||||
|
SCLK_PIN = 11
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
import spidev
|
||||||
|
import gpiozero
|
||||||
|
|
||||||
|
self.SPI = spidev.SpiDev()
|
||||||
|
self.GPIO_RST_PIN = gpiozero.LED(self.RST_PIN)
|
||||||
|
self.GPIO_DC_PIN = gpiozero.LED(self.DC_PIN)
|
||||||
|
# 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):
|
||||||
|
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):
|
||||||
|
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):
|
||||||
|
time.sleep(delaytime / 1000.0)
|
||||||
|
|
||||||
|
def spi_writebyte(self, data):
|
||||||
|
self.SPI.writebytes(data)
|
||||||
|
|
||||||
|
def spi_writebyte2(self, data):
|
||||||
|
self.SPI.writebytes2(data)
|
||||||
|
|
||||||
|
def DEV_SPI_write(self, data):
|
||||||
|
self.DEV_SPI.DEV_SPI_SendData(data)
|
||||||
|
|
||||||
|
def DEV_SPI_nwrite(self, data):
|
||||||
|
self.DEV_SPI.DEV_SPI_SendnData(data)
|
||||||
|
|
||||||
|
def DEV_SPI_read(self):
|
||||||
|
return self.DEV_SPI.DEV_SPI_ReadData()
|
||||||
|
|
||||||
|
def module_init(self, cleanup=False):
|
||||||
|
self.GPIO_PWR_PIN.on()
|
||||||
|
|
||||||
|
if cleanup:
|
||||||
|
find_dirs = [
|
||||||
|
os.path.dirname(os.path.realpath(__file__)),
|
||||||
|
'/usr/local/lib',
|
||||||
|
'/usr/lib',
|
||||||
|
]
|
||||||
|
self.DEV_SPI = None
|
||||||
|
for find_dir in find_dirs:
|
||||||
|
val = int(os.popen('getconf LONG_BIT').read())
|
||||||
|
logging.debug("System is %d bit"%val)
|
||||||
|
if val == 64:
|
||||||
|
so_filename = os.path.join(find_dir, 'DEV_Config_64.so')
|
||||||
|
else:
|
||||||
|
so_filename = os.path.join(find_dir, 'DEV_Config_32.so')
|
||||||
|
if os.path.exists(so_filename):
|
||||||
|
self.DEV_SPI = CDLL(so_filename)
|
||||||
|
break
|
||||||
|
if self.DEV_SPI is None:
|
||||||
|
RuntimeError('Cannot find DEV_Config.so')
|
||||||
|
|
||||||
|
self.DEV_SPI.DEV_Module_Init()
|
||||||
|
|
||||||
|
else:
|
||||||
|
# SPI device, bus = 0, device = 0
|
||||||
|
self.SPI.open(0, 0)
|
||||||
|
self.SPI.max_speed_hz = 4000000
|
||||||
|
self.SPI.mode = 0b00
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def module_exit(self, cleanup=False):
|
||||||
|
logger.debug("spi end")
|
||||||
|
self.SPI.close()
|
||||||
|
|
||||||
|
self.GPIO_RST_PIN.off()
|
||||||
|
self.GPIO_DC_PIN.off()
|
||||||
|
self.GPIO_PWR_PIN.off()
|
||||||
|
logger.debug("close 5V, Module enters 0 power consumption ...")
|
||||||
|
|
||||||
|
if cleanup:
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class JetsonNano:
|
||||||
|
# Pin definition
|
||||||
|
RST_PIN = 17
|
||||||
|
DC_PIN = 25
|
||||||
|
CS_PIN = 8
|
||||||
|
BUSY_PIN = 24
|
||||||
|
PWR_PIN = 18
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
import ctypes
|
||||||
|
find_dirs = [
|
||||||
|
os.path.dirname(os.path.realpath(__file__)),
|
||||||
|
'/usr/local/lib',
|
||||||
|
'/usr/lib',
|
||||||
|
]
|
||||||
|
self.SPI = None
|
||||||
|
for find_dir in find_dirs:
|
||||||
|
so_filename = os.path.join(find_dir, 'sysfs_software_spi.so')
|
||||||
|
if os.path.exists(so_filename):
|
||||||
|
self.SPI = ctypes.cdll.LoadLibrary(so_filename)
|
||||||
|
break
|
||||||
|
if self.SPI is None:
|
||||||
|
raise RuntimeError('Cannot find sysfs_software_spi.so')
|
||||||
|
|
||||||
|
import Jetson.GPIO
|
||||||
|
self.GPIO = Jetson.GPIO
|
||||||
|
|
||||||
|
def digital_write(self, pin, value):
|
||||||
|
self.GPIO.output(pin, value)
|
||||||
|
|
||||||
|
def digital_read(self, pin):
|
||||||
|
return self.GPIO.input(self.BUSY_PIN)
|
||||||
|
|
||||||
|
def delay_ms(self, delaytime):
|
||||||
|
time.sleep(delaytime / 1000.0)
|
||||||
|
|
||||||
|
def spi_writebyte(self, data):
|
||||||
|
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):
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.SPI.SYSFS_software_spi_begin()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def module_exit(self):
|
||||||
|
logger.debug("spi end")
|
||||||
|
self.SPI.SYSFS_software_spi_end()
|
||||||
|
|
||||||
|
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.output(self.PWR_PIN, 0)
|
||||||
|
|
||||||
|
self.GPIO.cleanup([self.RST_PIN, self.DC_PIN, self.CS_PIN, self.BUSY_PIN, self.PWR_PIN])
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
elif os.path.exists('/sys/bus/platform/drivers/gpio-x3'):
|
||||||
|
implementation = SunriseX3()
|
||||||
|
else:
|
||||||
|
implementation = JetsonNano()
|
||||||
|
|
||||||
|
for func in [x for x in dir(implementation) if not x.startswith('_')]:
|
||||||
|
setattr(sys.modules[__name__], func, getattr(implementation, func))
|
||||||
|
|
||||||
|
### END OF FILE ###
|
||||||
6
requirements.txt
Normal file
6
requirements.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
colorzero==2.0
|
||||||
|
gpiozero==2.0.1
|
||||||
|
lgpio==0.2.2.0
|
||||||
|
pillow==11.3.0
|
||||||
|
rpi-lgpio==0.6
|
||||||
|
spidev==3.7
|
||||||
7
update.sh
Executable file
7
update.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
||||||
|
echo "Generate document..."
|
||||||
|
./typst compile --format png document.typ
|
||||||
|
echo "Convert to image..."
|
||||||
|
mogrify -resize 400x300^ -gravity center -extent 400x300 document_ready.png document_ready.bmp
|
||||||
|
echo "Update display..."
|
||||||
|
python3 display.py
|
||||||
|
echo "Done."
|
||||||
Loading…
Add table
Add a link
Reference in a new issue