Added library and example for the 7.5 inches Version 2 (7in5_V2) screen
rodzic
24c454cdd0
commit
b5d20249d8
|
@ -0,0 +1,183 @@
|
||||||
|
"""
|
||||||
|
MicroPython Waveshare 7.5" Black/White GDEW075T8 e-paper display driver
|
||||||
|
https://github.com/mcauser/micropython-waveshare-epaper
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2017 Waveshare
|
||||||
|
Copyright (c) 2018 Mike Causer
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation 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
|
||||||
|
furnished 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 FOR 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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from micropython import const
|
||||||
|
from time import sleep_ms
|
||||||
|
import ustruct
|
||||||
|
|
||||||
|
# Display resolution
|
||||||
|
EPD_WIDTH = const(800)
|
||||||
|
EPD_HEIGHT = const(480)
|
||||||
|
|
||||||
|
# Display commands
|
||||||
|
PANEL_SETTING = const(0x00)
|
||||||
|
POWER_SETTING = const(0x01)
|
||||||
|
POWER_OFF = const(0x02)
|
||||||
|
#POWER_OFF_SEQUENCE_SETTING = const(0x03)
|
||||||
|
POWER_ON = const(0x04)
|
||||||
|
#POWER_ON_MEASURE = const(0x05)
|
||||||
|
BOOSTER_SOFT_START = const(0x06)
|
||||||
|
DEEP_SLEEP = const(0x07)
|
||||||
|
DATA_START_TRANSMISSION_1 = const(0x10)
|
||||||
|
#DATA_STOP = const(0x11)
|
||||||
|
DISPLAY_REFRESH = const(0x12)
|
||||||
|
DATA_START_TRANSMISSION_2 = const(0x13)
|
||||||
|
DUAL_SPI = const(0x15)
|
||||||
|
#AUTO_SEQUENCE = const(0x17)
|
||||||
|
#KW_LUT_OPTION = const(0x2B)
|
||||||
|
PLL_CONTROL = const(0x30)
|
||||||
|
TEMPERATURE_CALIBRATION = const(0x40)
|
||||||
|
#TEMPERATURE_SENSOR_SELECTION = const(0x41)
|
||||||
|
#TEMPERATURE_SENSOR_WRITE = const(0x42)
|
||||||
|
#TEMPERATURE_SENSOR_READ = const(0x43)
|
||||||
|
#PANEL_BREAK_CHECK = const(0x44)
|
||||||
|
VCOM_AND_DATA_INTERVAL_SETTING = const(0x50)
|
||||||
|
#LOW_POWER_DETECTION = const(0x51)
|
||||||
|
TCON_SETTING = const(0x60)
|
||||||
|
RESOLUTION_SETTING = const(0x61)
|
||||||
|
#GATE_SOURCE_START_SETTING = const(0x65)
|
||||||
|
#REVISION = const(0x70)
|
||||||
|
GET_STATUS = const(0x71)
|
||||||
|
#AUTO_MEASUREMENT_VCOM = const(0x80)
|
||||||
|
#READ_VCOM_VALUE = const(0x81)
|
||||||
|
VCM_DC_SETTING = const(0x82)
|
||||||
|
#PARTIAL_WINDOW = const(0x90)
|
||||||
|
#PARTIAL_IN = const(0x91)
|
||||||
|
#PARTIAL_OUT = const(0x92)
|
||||||
|
#PROGRAM_MODE = const(0xA0)
|
||||||
|
#ACTIVE_PROGRAMMING = const(0xA1)
|
||||||
|
#READ_OTP = const(0xA2)
|
||||||
|
#CASCADE_SETTING = const(0xE0)
|
||||||
|
#POWER_SAVING = const(0xE3)
|
||||||
|
#LVD_VOLTAGE_SELECT = const(0xE4)
|
||||||
|
#FORCE_TEMPERATURE = const(0xE5)
|
||||||
|
#TEMPERATURE_BOUNDARY = const(0xE7)
|
||||||
|
|
||||||
|
BUSY = const(0) # 0=busy, 1=idle
|
||||||
|
|
||||||
|
class EPD:
|
||||||
|
def __init__(self, spi, cs, dc, rst, busy):
|
||||||
|
self.spi = spi
|
||||||
|
self.cs = cs
|
||||||
|
self.dc = dc
|
||||||
|
self.rst = rst
|
||||||
|
self.busy = busy
|
||||||
|
self.cs.init(self.cs.OUT, value=1)
|
||||||
|
self.dc.init(self.dc.OUT, value=0)
|
||||||
|
self.rst.init(self.rst.OUT, value=0)
|
||||||
|
self.busy.init(self.busy.IN)
|
||||||
|
self.width = EPD_WIDTH
|
||||||
|
self.height = EPD_HEIGHT
|
||||||
|
|
||||||
|
def _command(self, command):
|
||||||
|
self.dc(0)
|
||||||
|
self.cs(0)
|
||||||
|
self.spi.write(bytearray([command]))
|
||||||
|
self.cs(1)
|
||||||
|
|
||||||
|
def _data(self, data):
|
||||||
|
self.dc(1)
|
||||||
|
self.cs(0)
|
||||||
|
self.spi.write(bytearray([data]))
|
||||||
|
self.cs(1)
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
self._command(POWER_SETTING)
|
||||||
|
self._data(0x07) #VGH=20V
|
||||||
|
self._data(0x07) #VGL=-20V
|
||||||
|
self._data(0x3f) #VDH=15V
|
||||||
|
self._data(0x3f) #VDL=-15V
|
||||||
|
|
||||||
|
self._command(POWER_ON)
|
||||||
|
sleep_ms(100)
|
||||||
|
self.wait_until_idle()
|
||||||
|
|
||||||
|
self._command(PANEL_SETTING)
|
||||||
|
self._data(0x1F)
|
||||||
|
|
||||||
|
self._command(RESOLUTION_SETTING)
|
||||||
|
self._data(0x03)
|
||||||
|
self._data(0x20)
|
||||||
|
self._data(0x01)
|
||||||
|
self._data(0xE0)
|
||||||
|
|
||||||
|
self._command(DUAL_SPI)
|
||||||
|
self._data(0x00)
|
||||||
|
|
||||||
|
self._command(VCOM_AND_DATA_INTERVAL_SETTING)
|
||||||
|
self._data(0x10)
|
||||||
|
self._data(0x07)
|
||||||
|
|
||||||
|
self._command(TCON_SETTING)
|
||||||
|
self._data(0x22)
|
||||||
|
|
||||||
|
def wait_until_idle(self):
|
||||||
|
self._command(GET_STATUS)
|
||||||
|
while self.busy.value() == BUSY:
|
||||||
|
self._command(GET_STATUS)
|
||||||
|
sleep_ms(200)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.rst(1)
|
||||||
|
sleep_ms(200)
|
||||||
|
self.rst(0)
|
||||||
|
sleep_ms(2)
|
||||||
|
self.rst(1)
|
||||||
|
sleep_ms(200)
|
||||||
|
|
||||||
|
# draw the current frame memory
|
||||||
|
def display_frame(self, frame_buffer):
|
||||||
|
self._command(DATA_START_TRANSMISSION_2)
|
||||||
|
for i in range(0, self.width * self.height // 8):
|
||||||
|
self._data(~frame_buffer[i])
|
||||||
|
|
||||||
|
self._command(DISPLAY_REFRESH)
|
||||||
|
sleep_ms(100)
|
||||||
|
self.wait_until_idle()
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self._command(DATA_START_TRANSMISSION_1)
|
||||||
|
for i in range(self.width * self.height // 8):
|
||||||
|
self._data(0x00)
|
||||||
|
|
||||||
|
self._command(DATA_START_TRANSMISSION_2)
|
||||||
|
for i in range(self.width * self.height // 8):
|
||||||
|
self._data(0x00)
|
||||||
|
|
||||||
|
self._command(DISPLAY_REFRESH)
|
||||||
|
sleep_ms(100)
|
||||||
|
self.wait_until_idle()
|
||||||
|
|
||||||
|
def sleep(self):
|
||||||
|
self._command(POWER_OFF)
|
||||||
|
self.wait_until_idle()
|
||||||
|
self._command(DEEP_SLEEP)
|
||||||
|
self._data(0xA5)
|
||||||
|
self.rst(0)
|
||||||
|
self.dc(0)
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,130 @@
|
||||||
|
"""
|
||||||
|
Example for 7.5 inch black & white Waveshare E-ink screen, V2
|
||||||
|
Run on ESP32
|
||||||
|
"""
|
||||||
|
|
||||||
|
import epaper7in5_V2
|
||||||
|
from machine import Pin, SPI
|
||||||
|
|
||||||
|
# SPIV on ESP32
|
||||||
|
sck = Pin(18)
|
||||||
|
miso = Pin(19)
|
||||||
|
mosi = Pin(23)
|
||||||
|
dc = Pin(32)
|
||||||
|
cs = Pin(33)
|
||||||
|
rst = Pin(19)
|
||||||
|
busy = Pin(35)
|
||||||
|
spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=sck, miso=miso, mosi=mosi)
|
||||||
|
|
||||||
|
e = epaper7in5_V2.EPD(spi, cs, dc, rst, busy)
|
||||||
|
e.init()
|
||||||
|
|
||||||
|
w = 800
|
||||||
|
h = 480
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
# use a frame buffer
|
||||||
|
# 400 * 300 / 8 = 15000 - thats a lot of pixels
|
||||||
|
import framebuf
|
||||||
|
buf = bytearray(w * h // 8)
|
||||||
|
fb = framebuf.FrameBuffer(buf, w, h, framebuf.MONO_HLSB)
|
||||||
|
black = 0
|
||||||
|
white = 1
|
||||||
|
fb.fill(white)
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
# write hello world with black bg and white text
|
||||||
|
from image_dark import hello_world_dark
|
||||||
|
from image_light import hello_world_light
|
||||||
|
print('Image dark')
|
||||||
|
bufImage = hello_world_dark
|
||||||
|
fbImage = framebuf.FrameBuffer(bufImage, 128, 296, framebuf.MONO_HLSB)
|
||||||
|
fb.blit(fbImage, 20, 2)
|
||||||
|
bufImage = hello_world_light
|
||||||
|
fbImage = framebuf.FrameBuffer(bufImage, 128, 296, framebuf.MONO_HLSB)
|
||||||
|
fb.blit(fbImage, 168, 2)
|
||||||
|
e.display_frame(buf)
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
# write hello world with white bg and black text
|
||||||
|
print('Image light')
|
||||||
|
#e.display_frame(hello_world_light)
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
|
||||||
|
print('Frame buffer things')
|
||||||
|
fb.fill(white)
|
||||||
|
fb.text('Hello World',30,0,black)
|
||||||
|
fb.pixel(30, 10, black)
|
||||||
|
fb.hline(30, 30, 10, black)
|
||||||
|
fb.vline(30, 50, 10, black)
|
||||||
|
fb.line(30, 70, 40, 80, black)
|
||||||
|
fb.rect(30, 90, 10, 10, black)
|
||||||
|
fb.fill_rect(30, 110, 10, 10, black)
|
||||||
|
for row in range(0,36):
|
||||||
|
fb.text(str(row),0,row*8,black)
|
||||||
|
fb.text('Line 36',0,288,black)
|
||||||
|
e.display_frame(buf)
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
# wrap text inside a box
|
||||||
|
black = 0
|
||||||
|
white = 1
|
||||||
|
# clear
|
||||||
|
fb.fill(white)
|
||||||
|
# display as much as this as fits in the box
|
||||||
|
str = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vel neque in elit tristique vulputate at et dui. Maecenas nec felis lectus. Pellentesque sit amet facilisis dui. Maecenas ac arcu euismod, tempor massa quis, ultricies est.'
|
||||||
|
|
||||||
|
# this could be useful as a new method in FrameBuffer
|
||||||
|
def text_wrap(str,x,y,color,w,h,border=None):
|
||||||
|
# optional box border
|
||||||
|
if border is not None:
|
||||||
|
fb.rect(x, y, w, h, border)
|
||||||
|
cols = w // 8
|
||||||
|
# for each row
|
||||||
|
j = 0
|
||||||
|
for i in range(0, len(str), cols):
|
||||||
|
# draw as many chars fit on the line
|
||||||
|
fb.text(str[i:i+cols], x, y + j, color)
|
||||||
|
j += 8
|
||||||
|
# dont overflow text outside the box
|
||||||
|
if j >= h:
|
||||||
|
break
|
||||||
|
|
||||||
|
# clear
|
||||||
|
fb.fill(white)
|
||||||
|
|
||||||
|
# draw text box 1
|
||||||
|
# box position and dimensions
|
||||||
|
print('Box 1')
|
||||||
|
bx = 8
|
||||||
|
by = 8
|
||||||
|
bw = 112 # = 14 cols
|
||||||
|
bh = 112 # = 14 rows (196 chars in total)
|
||||||
|
text_wrap(str,bx,by,black,bw,bh,black)
|
||||||
|
e.display_frame(buf)
|
||||||
|
|
||||||
|
# draw text box 2
|
||||||
|
print('Box 2 & 3')
|
||||||
|
bx = 0
|
||||||
|
by = 128
|
||||||
|
bw = w # 128 = 16 cols
|
||||||
|
bh = 6 * 8 # 48 = 6 rows (96 chars in total)
|
||||||
|
text_wrap(str,bx,by,black,bw,bh,black)
|
||||||
|
|
||||||
|
# draw text box 3
|
||||||
|
bx = 0
|
||||||
|
by = 184
|
||||||
|
bw = w//2 # 64 = 8 cols
|
||||||
|
bh = 8 * 8 # 64 = 8 rows (64 chars in total)
|
||||||
|
text_wrap(str,bx,by,black,bw,bh,None)
|
||||||
|
e.display_frame(buf)
|
||||||
|
|
||||||
|
# --------------------
|
Ładowanie…
Reference in New Issue