Couple updated displays from Waveshare, not 213g.

166c012cde
This commit is contained in:
Jeroen Oudshoorn
2024-01-23 10:59:25 +01:00
parent 57f03f4359
commit f89ba85f73
9 changed files with 531 additions and 193 deletions

View File

@ -264,11 +264,11 @@ class EPD:
def display(self, image): def display(self, image):
if (image == None): if (image == None):
return return
# Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) # Width = (self.width % 8 == 0)? (self.width // 8 ): (self.width // 8 + 1)
if (self.width % 8 == 0): if (self.width % 8 == 0):
Width = self.width / 8 Width = self.width // 8
else: else:
Width = self.width / 8 + 1 Width = self.width // 8 + 1
self.send_command(0x10) self.send_command(0x10)
for j in range(0, self.height): for j in range(0, self.height):
@ -282,11 +282,11 @@ class EPD:
self.TurnOnDisplay() self.TurnOnDisplay()
def Clear(self): def Clear(self):
# Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) # Width = (self.width % 8 == 0)? (self.width // 8 ): (self.width // 8 + 1)
if (self.width % 8 == 0): if (self.width % 8 == 0):
Width = self.width / 8 Width = self.width // 8
else: else:
Width = self.width / 8 + 1 Width = self.width // 8 + 1
Height = self.height Height = self.height
@ -313,11 +313,11 @@ class EPD:
self.send_data(127) # y-end self.send_data(127) # y-end
self.send_data(0x00) self.send_data(0x00)
# Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) # Width = (self.width % 8 == 0)? (self.width // 8 ): (self.width // 8 + 1)
if (self.width % 8 == 0): if (self.width % 8 == 0):
Width = self.width / 8 Width = self.width // 8
else: else:
Width = self.width / 8 + 1 Width = self.width // 8 + 1
Height = self.height Height = self.height
# send data # send data

View File

@ -100,7 +100,7 @@ class EPD:
def ReadBusy(self): def ReadBusy(self):
logger.debug("e-Paper busy") logger.debug("e-Paper busy")
while epdconfig.digital_read(self.busy_pin) == 1: # 1: idle, 0: busy while (epdconfig.digital_read(self.busy_pin) == 1): # 1: idle, 0: busy
epdconfig.delay_ms(20) epdconfig.delay_ms(20)
logger.debug("e-Paper busy release") logger.debug("e-Paper busy release")
@ -134,7 +134,7 @@ class EPD:
self.send_data(self.LUT_DATA_4Gray[i]) self.send_data(self.LUT_DATA_4Gray[i])
def init(self): def init(self):
if epdconfig.module_init() != 0: if (epdconfig.module_init() != 0):
return -1 return -1
# EPD hardware init start # EPD hardware init start
@ -159,7 +159,7 @@ class EPD:
return 0 return 0
def init_Fast(self): def init_Fast(self):
if epdconfig.module_init() != 0: if (epdconfig.module_init() != 0):
return -1 return -1
# EPD hardware init start # EPD hardware init start
@ -204,12 +204,12 @@ class EPD:
return 0 return 0
def Init_4Gray(self): def Init_4Gray(self):
if epdconfig.module_init() != 0: if (epdconfig.module_init() != 0):
return -1 return -1
self.reset() self.reset()
self.send_command(0x12) # soft reset self.send_command(0x12) # soft reset
self.ReadBusy() self.ReadBusy();
self.send_command(0x74) # set analog block control self.send_command(0x74) # set analog block control
self.send_data(0x54) self.send_data(0x54)
@ -268,14 +268,14 @@ class EPD:
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):
@ -293,40 +293,40 @@ class EPD:
pixels = image_monocolor.load() pixels = image_monocolor.load()
i = 0 i = 0
# 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] == 0xC0: if (pixels[x, y] == 0xC0):
pixels[x, y] = 0x80 pixels[x, y] = 0x80
elif pixels[x, y] == 0x80: elif (pixels[x, y] == 0x80):
pixels[x, y] = 0x40 pixels[x, y] = 0x40
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):
logger.debug("Horizontal") logger.debug("Horizontal")
for x in range(imwidth): for x in range(imwidth):
for y in range(imheight): for y in range(imheight):
newx = y newx = y
newy = self.height - x - 1 newy = self.height - x - 1
if pixels[x, y] == 0xC0: if (pixels[x, y] == 0xC0):
pixels[x, y] = 0x80 pixels[x, y] = 0x80
elif pixels[x, y] == 0x80: elif (pixels[x, y] == 0x80):
pixels[x, y] = 0x40 pixels[x, y] = 0x40
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
def Clear(self): def Clear(self):
if self.width % 8 == 0: if (self.width % 8 == 0):
Width = self.width // 8 Width = self.width // 8
else: else:
Width = self.width // 8 + 1 Width = self.width // 8 + 1
@ -338,7 +338,7 @@ class EPD:
self.TurnOnDisplay() self.TurnOnDisplay()
def display(self, image): def display(self, image):
if self.width % 8 == 0: if (self.width % 8 == 0):
Width = self.width // 8 Width = self.width // 8
else: else:
Width = self.width // 8 + 1 Width = self.width // 8 + 1
@ -350,7 +350,7 @@ class EPD:
self.TurnOnDisplay() self.TurnOnDisplay()
def display_Fast(self, image): def display_Fast(self, image):
if self.width % 8 == 0: if (self.width % 8 == 0):
Width = self.width // 8 Width = self.width // 8
else: else:
Width = self.width // 8 + 1 Width = self.width // 8 + 1
@ -362,7 +362,7 @@ class EPD:
self.TurnOnDisplay_Fast() self.TurnOnDisplay_Fast()
def display_Base(self, image): def display_Base(self, image):
if self.width % 8 == 0: if (self.width % 8 == 0):
Width = self.width // 8 Width = self.width // 8
else: else:
Width = self.width // 8 + 1 Width = self.width // 8 + 1
@ -379,7 +379,7 @@ class EPD:
self.TurnOnDisplay() self.TurnOnDisplay()
def display_Base_color(self, color): def display_Base_color(self, color):
if self.width % 8 == 0: if (self.width % 8 == 0):
Width = self.width // 8 Width = self.width // 8
else: else:
Width = self.width // 8 + 1 Width = self.width // 8 + 1
@ -396,7 +396,8 @@ class EPD:
# self.TurnOnDisplay() # self.TurnOnDisplay()
def display_Partial(self, Image, Xstart, Ystart, Xend, Yend): def display_Partial(self, Image, Xstart, Ystart, Xend, Yend):
if (Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | (Xend - Xstart) % 8 == 0: if ((Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | (
Xend - Xstart) % 8 == 0):
Xstart = Xstart // 8 Xstart = Xstart // 8
Xend = Xend // 8 Xend = Xend // 8
else: else:
@ -439,23 +440,23 @@ class EPD:
self.send_command(0x24) # Write Black and White image to RAM self.send_command(0x24) # Write Black and White image to RAM
for j in range(Height): for j in range(Height):
for i in range(Width): for i in range(Width):
if (j > Ystart - 1) & (j < (Yend + 1)) & (i > Xstart - 1) & (i < (Xend + 1)): if ((j > Ystart - 1) & (j < (Yend + 1)) & (i > Xstart - 1) & (i < (Xend + 1))):
self.send_data(Image[i + j * Width]) self.send_data(Image[i + j * Width])
self.TurnOnDisplay_Partial() self.TurnOnDisplay_Partial()
def display_4Gray(self, image): def display_4Gray(self, image):
self.send_command(0x24) self.send_command(0x24)
for i in range(0, 5808): # 5808*4 46464 for i in range(0, 48000): # 5808*4 46464
temp3 = 0 temp3 = 0
for j in range(0, 2): for j in range(0, 2):
temp1 = image[i * 2 + j] temp1 = image[i * 2 + j]
for k in range(0, 2): for k in range(0, 2):
temp2 = temp1 & 0xC0 temp2 = temp1 & 0xC0
if temp2 == 0xC0: if (temp2 == 0xC0):
temp3 |= 0x00 temp3 |= 0x00
elif temp2 == 0x00: elif (temp2 == 0x00):
temp3 |= 0x01 temp3 |= 0x01
elif temp2 == 0x80: elif (temp2 == 0x80):
temp3 |= 0x01 temp3 |= 0x01
else: # 0x40 else: # 0x40
temp3 |= 0x00 temp3 |= 0x00
@ -463,31 +464,31 @@ class EPD:
temp1 <<= 2 temp1 <<= 2
temp2 = temp1 & 0xC0 temp2 = temp1 & 0xC0
if temp2 == 0xC0: if (temp2 == 0xC0):
temp3 |= 0x00 temp3 |= 0x00
elif temp2 == 0x00: elif (temp2 == 0x00):
temp3 |= 0x01 temp3 |= 0x01
elif temp2 == 0x80: elif (temp2 == 0x80):
temp3 |= 0x01 temp3 |= 0x01
else: # 0x40 else: # 0x40
temp3 |= 0x00 temp3 |= 0x00
if j != 1 or k != 1: if (j != 1 or k != 1):
temp3 <<= 1 temp3 <<= 1
temp1 <<= 2 temp1 <<= 2
self.send_data(temp3) self.send_data(temp3)
self.send_command(0x26) self.send_command(0x26)
for i in range(0, 5808): # 5808*4 46464 for i in range(0, 48000): # 5808*4 46464
temp3 = 0 temp3 = 0
for j in range(0, 2): for j in range(0, 2):
temp1 = image[i * 2 + j] temp1 = image[i * 2 + j]
for k in range(0, 2): for k in range(0, 2):
temp2 = temp1 & 0xC0 temp2 = temp1 & 0xC0
if temp2 == 0xC0: if (temp2 == 0xC0):
temp3 |= 0x00 temp3 |= 0x00
elif temp2 == 0x00: elif (temp2 == 0x00):
temp3 |= 0x01 temp3 |= 0x01
elif temp2 == 0x80: elif (temp2 == 0x80):
temp3 |= 0x00 temp3 |= 0x00
else: # 0x40 else: # 0x40
temp3 |= 0x01 temp3 |= 0x01
@ -495,15 +496,15 @@ class EPD:
temp1 <<= 2 temp1 <<= 2
temp2 = temp1 & 0xC0 temp2 = temp1 & 0xC0
if temp2 == 0xC0: if (temp2 == 0xC0):
temp3 |= 0x00 temp3 |= 0x00
elif temp2 == 0x00: elif (temp2 == 0x00):
temp3 |= 0x01 temp3 |= 0x01
elif temp2 == 0x80: elif (temp2 == 0x80):
temp3 |= 0x00 temp3 |= 0x00
else: # 0x40 else: # 0x40
temp3 |= 0x01 temp3 |= 0x01
if j != 1 or k != 1: if (j != 1 or k != 1):
temp3 <<= 1 temp3 <<= 1
temp1 <<= 2 temp1 <<= 2
self.send_data(temp3) self.send_data(temp3)
@ -516,3 +517,5 @@ class EPD:
epdconfig.delay_ms(2000) epdconfig.delay_ms(2000)
epdconfig.module_exit() epdconfig.module_exit()
### END OF FILE ###

View File

@ -28,7 +28,7 @@
# #
import logging import logging
from .. import epdconfig from . import epdconfig
# Display resolution # Display resolution
EPD_WIDTH = 128 EPD_WIDTH = 128
@ -227,7 +227,7 @@ class EPD:
self.send_data((y >> 8) & 0xFF) self.send_data((y >> 8) & 0xFF)
def init(self): def init(self):
if epdconfig.module_init() != 0: if (epdconfig.module_init() != 0):
return -1 return -1
# EPD hardware init start # EPD hardware init start
self.reset() self.reset()

View File

@ -184,7 +184,7 @@ class EPD:
self.send_command(0x01) # Driver output control self.send_command(0x01) # Driver output control
self.send_data((self.height - 1) % 256) self.send_data((self.height - 1) % 256)
self.send_data((self.height - 1) / 256) self.send_data((self.height - 1) // 256)
self.send_data(0x00) self.send_data(0x00)
self.send_command(0x11) # data entry mode self.send_command(0x11) # data entry mode

View File

@ -29,7 +29,7 @@
import logging import logging
from .. import epdconfig from . import epdconfig
# Display resolution # Display resolution
EPD_WIDTH = 800 EPD_WIDTH = 800

View File

@ -1,11 +1,11 @@
# ***************************************************************************** # *****************************************************************************
# * | File : epd7in5.py # * | File : epd4in26.py
# * | Author : Waveshare team # * | Author : Waveshare team
# * | Function : Electronic paper driver # * | Function : Electronic paper driver
# * | Info : # * | Info :
# *---------------- # *----------------
# * | This version: V4.0 # * | This version: V1.0
# * | Date : 2019-06-20 # * | Date : 2023-12-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
@ -29,11 +29,16 @@
import logging import logging
from .. import epdconfig from . import epdconfig
# Display resolution # Display resolution
EPD_WIDTH = 880 EPD_WIDTH = 800
EPD_HEIGHT = 528 EPD_HEIGHT = 480
GRAY1 = 0xff # white
GRAY2 = 0xC0
GRAY3 = 0x80 # gray
GRAY4 = 0x00 # Blackest
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -46,15 +51,39 @@ class EPD:
self.cs_pin = epdconfig.CS_PIN self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH self.width = EPD_WIDTH
self.height = EPD_HEIGHT self.height = EPD_HEIGHT
self.GRAY1 = GRAY1 # white
self.GRAY2 = GRAY2
self.GRAY3 = GRAY3 # gray
self.GRAY4 = GRAY4 # Blackest
LUT_DATA_4Gray = [ # #112bytes
0x80, 0x48, 0x4A, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x48, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x88, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xA8, 0x48, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x1E, 0x1C, 0x02, 0x00,
0x05, 0x01, 0x05, 0x01, 0x02,
0x08, 0x01, 0x01, 0x04, 0x04,
0x00, 0x02, 0x00, 0x02, 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, 0x01,
0x22, 0x22, 0x22, 0x22, 0x22,
0x17, 0x41, 0xA8, 0x32, 0x30,
0x00, 0x00]
# Hardware reset # Hardware reset
def reset(self): def reset(self):
epdconfig.digital_write(self.reset_pin, 1) epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(200) epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0) epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2) epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1) epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(200) epdconfig.delay_ms(20)
def send_command(self, command): def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0) epdconfig.digital_write(self.dc_pin, 0)
@ -71,7 +100,7 @@ class EPD:
def send_data2(self, data): def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1) epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0) epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data) epdconfig.SPI.writebytes2(data)
epdconfig.digital_write(self.cs_pin, 1) epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self): def ReadBusy(self):
@ -79,102 +108,408 @@ class EPD:
busy = epdconfig.digital_read(self.busy_pin) busy = epdconfig.digital_read(self.busy_pin)
while (busy == 1): while (busy == 1):
busy = epdconfig.digital_read(self.busy_pin) busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(200) epdconfig.delay_ms(20)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def TurnOnDisplay(self):
self.send_command(0x22) # Display Update Control
self.send_data(0xF7)
self.send_command(0x20) # Activate Display Update Sequence
self.ReadBusy()
def TurnOnDisplay_Fast(self):
self.send_command(0x22) # Display Update Control
self.send_data(0xC7)
self.send_command(0x20) # Activate Display Update Sequence
self.ReadBusy()
def TurnOnDisplay_Part(self):
self.send_command(0x22) # Display Update Control
self.send_data(0xFF)
self.send_command(0x20) # Activate Display Update Sequence
self.ReadBusy()
def TurnOnDisplay_4GRAY(self):
self.send_command(0x22) # Display Update Control
self.send_data(0xC7)
self.send_command(0x20) # Activate Display Update Sequence
self.ReadBusy()
'''
function : Setting the display window
parameter:
xstart : X-axis starting position
ystart : Y-axis starting position
xend : End position of X-axis
yend : End position of Y-axis
'''
def SetWindow(self, x_start, y_start, x_end, y_end):
self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
self.send_data(x_start & 0xFF)
self.send_data((x_start >> 8) & 0x03)
self.send_data(x_end & 0xFF)
self.send_data((x_end >> 8) & 0x03)
self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
self.send_data(y_start & 0xFF)
self.send_data((y_start >> 8) & 0xFF)
self.send_data(y_end & 0xFF)
self.send_data((y_end >> 8) & 0xFF)
'''
function : Set Cursor
parameter:
x : X-axis starting position
y : Y-axis starting position
'''
def SetCursor(self, x, y):
self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
# x point must be the multiple of 8 or the last 3 bits will be ignored
self.send_data(x & 0xFF)
self.send_data((x >> 8) & 0x03)
self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
self.send_data(y & 0xFF)
self.send_data((y >> 8) & 0xFF)
def init(self): def init(self):
if (epdconfig.module_init() != 0): if (epdconfig.module_init() != 0):
return -1 return -1
# 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(0x18) # use the internal temperature sensor
self.send_data(0xf7); self.send_data(0x80)
self.ReadBusy();
self.send_command(0x47); # Auto Write B/W RAM
self.send_data(0xf7);
self.ReadBusy();
self.send_command(0x0C); # Soft start setting self.send_command(0x0C) # set soft start
self.send_data2([0xAE, 0xC7, 0xC3, 0xC0, 0x40]) self.send_data(0xAE)
self.send_data(0xC7)
self.send_data(0xC3)
self.send_data(0xC0)
self.send_data(0x80)
self.send_command(0x01); # Set MUX as 527 self.send_command(0x01) # drive output control
self.send_data2([0xAF, 0x02, 0x01]) self.send_data((self.height - 1) % 256) # Y
self.send_data((self.height - 1) // 256) # Y
self.send_data(0x02)
self.send_command(0x11); # Data entry mode self.send_command(0x3C) # Border Border setting
self.send_data(0x01); self.send_data(0x01)
self.send_command(0x44); self.send_command(0x11) # data entry mode
self.send_data2([0x00, 0x00, 0x6F, 0x03]) # RAM x address start at 0 self.send_data(0x01) # X-mode x+ y-
self.send_command(0x45);
self.send_data2([0xAF, 0x02, 0x00, 0x00])
self.send_command(0x3C); # VBD self.SetWindow(0, self.height - 1, self.width - 1, 0)
self.send_data(0x05); # LUT1, for white
self.send_command(0x18); self.SetCursor(0, 0)
self.send_data(0X80); self.ReadBusy()
self.send_command(0x22); # EPD hardware init end
self.send_data(0XB1); # Load Temperature and waveform setting. return 0
self.send_command(0x20);
self.ReadBusy();
self.send_command(0x4E); # set RAM x address count to 0; def init_Fast(self):
self.send_data2([0x00, 0x00]) if (epdconfig.module_init() != 0):
self.send_command(0x4F); return -1
self.send_data2([0x00, 0x00]) # EPD hardware init start
self.reset()
self.ReadBusy()
self.send_command(0x12) # SWRESET
self.ReadBusy()
self.send_command(0x18) # use the internal temperature sensor
self.send_data(0x80)
self.send_command(0x0C) # set soft start
self.send_data(0xAE)
self.send_data(0xC7)
self.send_data(0xC3)
self.send_data(0xC0)
self.send_data(0x80)
self.send_command(0x01) # drive output control
self.send_data((self.height - 1) % 256) # Y
self.send_data((self.height - 1) // 256) # Y
self.send_data(0x02)
self.send_command(0x3C) # Border Border setting
self.send_data(0x01)
self.send_command(0x11) # data entry mode
self.send_data(0x01) # X-mode x+ y-
self.SetWindow(0, self.height - 1, self.width - 1, 0)
self.SetCursor(0, 0)
self.ReadBusy()
# TEMP (1.5s)
self.send_command(0x1A)
self.send_data(0x5A)
self.send_command(0x22)
self.send_data(0x91)
self.send_command(0x20)
self.ReadBusy()
# EPD hardware init end
return 0
def Lut(self):
self.send_command(0x32)
for count in range(0, 105):
self.send_data(self.LUT_DATA_4Gray[count])
self.send_command(0x03) # VGH
self.send_data(self.LUT_DATA_4Gray[105])
self.send_command(0x04) #
self.send_data(self.LUT_DATA_4Gray[106]) # VSH1
self.send_data(self.LUT_DATA_4Gray[107]) # VSH2
self.send_data(self.LUT_DATA_4Gray[108]) # VSL
self.send_command(0x2C) # VCOM Voltage
self.send_data(self.LUT_DATA_4Gray[109]) # 0x1C
def init_4GRAY(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
self.ReadBusy()
self.send_command(0x12) # SWRESET
self.ReadBusy()
self.send_command(0x18) # use the internal temperature sensor
self.send_data(0x80)
self.send_command(0x0C) # set soft start
self.send_data(0xAE)
self.send_data(0xC7)
self.send_data(0xC3)
self.send_data(0xC0)
self.send_data(0x80)
self.send_command(0x01) # drive output control
self.send_data((self.height - 1) % 256) # Y
self.send_data((self.height - 1) // 256) # Y
self.send_data(0x02)
self.send_command(0x3C) # Border Border setting
self.send_data(0x01)
self.send_command(0x11) # data entry mode
self.send_data(0x01) # X-mode x+ y-
self.SetWindow(0, self.height - 1, self.width - 1, 0)
self.SetCursor(0, 0)
self.ReadBusy()
self.Lut()
# EPD hardware init end # EPD hardware init end
return 0 return 0
def getbuffer(self, image): def getbuffer(self, image):
img = image # logger.debug("bufsiz = ",int(self.width/8) * self.height)
imwidth, imheight = img.size buf = [0xFF] * (int(self.width / 8) * self.height)
if (imwidth == self.width and imheight == self.height): image_monocolor = image.convert('1')
img = img.convert('1') imwidth, imheight = image_monocolor.size
elif (imwidth == self.height and imheight == self.width): pixels = image_monocolor.load()
img = img.rotate(90, expand=True).convert('1') # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
else: if imwidth == self.width and imheight == self.height:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height)) logger.debug("Horizontal")
# return a blank buffer for y in range(imheight):
return [0xff] * int(self.width * self.height / 8) 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
buf = bytearray(img.tobytes('raw')) 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 = self.height - x - 1
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 return buf
def display(self, image): def display(self, image):
self.send_command(0x4F);
self.send_data2([0x00, 0x00])
self.send_command(0x24);
self.send_data2(image)
self.send_command(0x22);
self.send_data(0xF7); # Load LUT from MCU(0x32)
self.send_command(0x20);
epdconfig.delay_ms(10);
self.ReadBusy();
def Clear(self):
buf = [0xff] * int(self.width * self.height / 8)
self.send_command(0x4F);
self.send_data2([0x00, 0x00])
self.send_command(0x24) self.send_command(0x24)
self.send_data2(buf) self.send_data2(image)
self.TurnOnDisplay()
def display_Base(self, image):
self.send_command(0x24)
self.send_data2(image)
self.send_command(0x26) self.send_command(0x26)
self.send_data2(buf) self.send_data2(image)
self.send_command(0x22); self.TurnOnDisplay()
self.send_data(0xF7); # Load LUT from MCU(0x32)
self.send_command(0x20); def display_Fast(self, image):
epdconfig.delay_ms(10); self.send_command(0x24)
self.ReadBusy(); self.send_data2(image)
self.TurnOnDisplay_Fast()
def display_Partial(self, Image):
# Reset
self.reset()
self.send_command(0x18) # BorderWavefrom
self.send_data(0x80)
self.send_command(0x3C) # BorderWavefrom
self.send_data(0x80)
self.send_command(0x01) # drive output control
self.send_data((self.height - 1) % 256) # Y
self.send_data((self.height - 1) // 256) # Y
self.send_command(0x11) # data entry mode
self.send_data(0x01) # X-mode x+ y-
self.SetWindow(0, self.height - 1, self.width - 1, 0)
self.SetCursor(0, 0)
self.send_command(0x24) # Write Black and White image to RAM
self.send_data2(Image)
self.TurnOnDisplay_Part()
def display_4Gray(self, image):
self.send_command(0x24)
for i in range(0, 48000): # 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 |= 0x00
elif (temp2 == 0x00):
temp3 |= 0x01
elif (temp2 == 0x80):
temp3 |= 0x01
else: # 0x40
temp3 |= 0x00
temp3 <<= 1
temp1 <<= 2
temp2 = temp1 & 0xC0
if (temp2 == 0xC0):
temp3 |= 0x00
elif (temp2 == 0x00):
temp3 |= 0x01
elif (temp2 == 0x80):
temp3 |= 0x01
else: # 0x40
temp3 |= 0x00
if (j != 1 or k != 1):
temp3 <<= 1
temp1 <<= 2
self.send_data(temp3)
self.send_command(0x26)
for i in range(0, 48000): # 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 |= 0x00
elif (temp2 == 0x00):
temp3 |= 0x01
elif (temp2 == 0x80):
temp3 |= 0x00
else: # 0x40
temp3 |= 0x01
temp3 <<= 1
temp1 <<= 2
temp2 = temp1 & 0xC0
if (temp2 == 0xC0):
temp3 |= 0x00
elif (temp2 == 0x00):
temp3 |= 0x01
elif (temp2 == 0x80):
temp3 |= 0x00
else: # 0x40
temp3 |= 0x01
if (j != 1 or k != 1):
temp3 <<= 1
temp1 <<= 2
self.send_data(temp3)
self.TurnOnDisplay_4GRAY()
def Clear(self):
self.send_command(0x24)
self.send_data2([0xFF] * (int(self.width / 8) * self.height))
self.send_command(0x26)
self.send_data2([0xFF] * (int(self.width / 8) * self.height))
self.TurnOnDisplay()
def sleep(self): def sleep(self):
self.send_command(0x10); self.send_command(0x10) # DEEP_SLEEP
self.send_data(0x01); self.send_data(0x01)
epdconfig.delay_ms(2000) epdconfig.delay_ms(2000)
epdconfig.module_exit() epdconfig.module_exit()

View File

@ -243,7 +243,7 @@ class EPD:
else: else:
Xend = Xend // 8 * 8 + 1 Xend = Xend // 8 * 8 + 1
Width = (Xend - Xstart) / 8 Width = (Xend - Xstart) // 8
Height = Yend - Ystart Height = Yend - Ystart
self.send_command(0x50) self.send_command(0x50)

View File

@ -484,7 +484,7 @@ class EPD:
else: else:
Xend = Xend // 8 * 8 + 1 Xend = Xend // 8 * 8 + 1
Width = (Xend - Xstart) / 8 Width = (Xend - Xstart) // 8
Height = Yend - Ystart Height = Yend - Ystart
self.send_command(0x50) self.send_command(0x50)

View File

@ -81,59 +81,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
@ -162,44 +162,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.delay_ms(2000) epdconfig.delay_ms(2000)
epdconfig.module_exit() epdconfig.module_exit()