From: Dustin Walde Date: Mon, 6 Jan 2025 04:14:59 +0000 (-0800) Subject: Move src into named module X-Git-Url: https://git.walde.dev/?a=commitdiff_plain;ds=inline;p=epaper_display Move src into named module --- diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/display.py b/src/display.py deleted file mode 100644 index 1899d42..0000000 --- a/src/display.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -""" - -from logging import Logger - -import PIL -from PIL import Image - -from drivers.epd12in48b import EPD, EPD_HEIGHT, EPD_WIDTH - -logger = Logger(__name__) - - -class Display: - - def __init__(self) -> None: - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - self.epaper = EPD() - - def render(self, black: Image, red: Image): - logger.info("Init display") - self.epaper.init() - logger.info("Update display") - self.epaper.display(black, red) - logger.info("Sleep display") - self.epaper.sleep() - - def calibrate(self, iterations=1): - logger.info("Init display for calibration") - self.epaper.init() - - white = Image.new('1', (self.width, self.height), 'white') - black = Image.new('1', (self.width, self.height), 'black') - - logger.info('Calibrating e-paper display') - for i in range(iterations): - logger.info('black') - self.epaper.display(black, white) - logger.info('red') - self.epaper.display(white, black) - logger.info('white') - self.epaper.display(white, white) - logger.info(f'#{i + 1} of {iterations} complete') - - self.epaper.sleep() - diff --git a/src/drivers/__init__.py b/src/drivers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/drivers/epd12in48.py b/src/drivers/epd12in48.py deleted file mode 100644 index 16b33f5..0000000 --- a/src/drivers/epd12in48.py +++ /dev/null @@ -1,398 +0,0 @@ -# /***************************************************************************** -# * | File : epd12in48.py -# * | Author : Waveshare electrices -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2019-11-01 -# * | 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 time -import epdconfig - -EPD_WIDTH = 1304 -EPD_HEIGHT = 984 - -class EPD(object): - def __init__(self): - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN - self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN - self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN - self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN - - self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN - self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN - - self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN - self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN - - self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN - self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN - self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN - self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN - - def Init(self): - print("EPD init...") - epdconfig.module_init() - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - self.Reset() - - #panel setting - self.M1_SendCommand(0x00) - self.M1_SendData(0x1f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f - self.S1_SendCommand(0x00) - self.S1_SendData(0x1f) - self.M2_SendCommand(0x00) - self.M2_SendData(0x13) - self.S2_SendCommand(0x00) - self.S2_SendData(0x13) - - # booster soft start - self.M1_SendCommand(0x06) - self.M1_SendData(0x17) #A - self.M1_SendData(0x17) #B - self.M1_SendData(0x39) #C - self.M1_SendData(0x17) - self.M2_SendCommand(0x06) - self.M2_SendData(0x17) - self.M2_SendData(0x17) - self.M2_SendData(0x39) - self.M2_SendData(0x17) - - #resolution setting - self.M1_SendCommand(0x61) - self.M1_SendData(0x02) - self.M1_SendData(0x88) #source 648 - self.M1_SendData(0x01) #gate 492 - self.M1_SendData(0xEC) - self.S1_SendCommand(0x61) - self.S1_SendData(0x02) - self.S1_SendData(0x90) #source 656 - self.S1_SendData(0x01) #gate 492 - self.S1_SendData(0xEC) - self.M2_SendCommand(0x61) - self.M2_SendData(0x02) - self.M2_SendData(0x90) #source 656 - self.M2_SendData(0x01) #gate 492 - self.M2_SendData(0xEC) - self.S2_SendCommand(0x61) - self.S2_SendData(0x02) - self.S2_SendData(0x88) #source 648 - self.S2_SendData(0x01) #gate 492 - self.S2_SendData(0xEC) - - self.M1S1M2S2_SendCommand(0x15) #DUSPI - self.M1S1M2S2_SendData(0x20) - - self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting - self.M1S1M2S2_SendData(0x21) #Border KW - self.M1S1M2S2_SendData(0x07) - - self.M1S1M2S2_SendCommand(0x60) #TCON - self.M1S1M2S2_SendData(0x22) - - self.M1S1M2S2_SendCommand(0xE3) - self.M1S1M2S2_SendData(0x00) - - #temperature - temp = self.M1_ReadTemperature() - - self.M1S1M2S2_SendCommand(0xe0) #Cascade setting - self.M1S1M2S2_SendData(0x03) - self.M1S1M2S2_SendCommand(0xe5) #Force temperature - self.M1S1M2S2_SendData(temp) - - def display(self, Image): - start = time.clock() - buf = [0x00] * int(self.width * self.height / 8) - image_monocolor = Image.convert('1') - imwidth, imheight = image_monocolor.size - pixels = image_monocolor.load() - temp=0; - for y in range(0, imheight): - for x in range(0, imwidth): - # Set the bits for the column of pixels at the current position. - if pixels[x, y] < 127: # black - buf[int((x + y*self.width)/8)] &= ~(0x80>>temp) - else: # white - buf[int((x + y*self.width)/8)] |= (0x80>>temp) - temp=temp+1 - if(temp==8): - temp=0 - - #M1 part 648*492 - self.M1_SendCommand(0x13) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(buf[y*163 + x]) - - #S1 part 656*492 - self.S1_SendCommand(0x13) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(buf[y*163 + x]) - - #M2 part 656*492 - self.M2_SendCommand(0x13) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(buf[y*163 + x]) - - #S2 part 648*492 - self.S2_SendCommand(0x13) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(buf[y*163 + x]) - - end = time.clock() - print("use time:%f"%(end - start)) - self.TurnOnDisplay() - - def clear(self): - """Clear contents of image buffer""" - start = time.clock() - self.M1_SendCommand(0x13) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(0xff) - - self.S1_SendCommand(0x13) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(0xff) - - self.M2_SendCommand(0x13) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(0xff) - - self.S2_SendCommand(0x13) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(0xff) - end = time.clock() - print("use time:%f"%(end - start)) - self.TurnOnDisplay() - - """ M1S1M2S2 Write register address and data """ - def M1S1M2S2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - def M1S1M2S2_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - """ M1M2 Write register address and data """ - def M1M2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - def M1S1M2S2_Senddata(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - """ S2 Write register address and data """ - def S2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - - def S2_SendData(self, val): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - """ M2 Write register address and data """ - def M2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - def M2_SendData(self, val): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - """ S1 Write register address and data """ - def S1_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - - def S1_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - - """ M1 Write register address and data """ - def M1_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - - def M1_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - - def Reset(self): - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) - time.sleep(0.2) - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) - time.sleep(0.01) - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) - time.sleep(0.2) - - def EPD_Sleep(self): - self.M1S1M2S2_SendCommand(0X02) - time.sleep(0.3) - - self.M1S1M2S2_SendCommand(0X07) - self.M1S1M2S2_SendData(0xA5) - time.sleep(0.3) - print("module_exit") - epdconfig.module_exit() - - - def TurnOnDisplay(self): - self.M1M2_SendCommand(0x04) - time.sleep(0.3) - self.M1S1M2S2_SendCommand(0x12) - self.M1_ReadBusy() - self.S1_ReadBusy() - self.M2_ReadBusy() - self.S2_ReadBusy() - - #Busy - def M1_ReadBusy(self): - self.M1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) - busy = not(busy & 0x01) - print("M1_ReadBusy") - while(busy): - self.M1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - - def M2_ReadBusy(self): - self.M2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) - busy = not(busy & 0x01) - print("M2_ReadBusy") - while(busy): - self.M2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) - busy =not(busy & 0x01) - time.sleep(0.2) - - def S1_ReadBusy(self): - self.S1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) - busy = not(busy & 0x01) - print("s1_ReadBusy") - while(busy): - self.S1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - - def S2_ReadBusy(self): - self.S2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) - busy = not(busy & 0x01) - print("S2_ReadBusy") - while(busy): - self.S2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - - def M1_ReadTemperature(self): - self.M1_SendCommand(0x40) - self.M1_ReadBusy() - time.sleep(0.3) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - time.sleep(0.01) - - # temp = epdconfig.spi_readbyte(0x00) - temp = 25 - print("Read Temperature Reg:%d"%temp) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - # temp =0x29 - return temp diff --git a/src/drivers/epd12in48b.py b/src/drivers/epd12in48b.py deleted file mode 100644 index e4035a4..0000000 --- a/src/drivers/epd12in48b.py +++ /dev/null @@ -1,520 +0,0 @@ -# /***************************************************************************** -# * | File : epd12in48.py -# * | Author : Waveshare electrices -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2019-11-01 -# * | 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 time -from . import epdconfig - -EPD_WIDTH = 1304 -EPD_HEIGHT = 984 - -class EPD(object): - def __init__(self): - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN - self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN - self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN - self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN - - self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN - self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN - - self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN - self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN - - self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN - self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN - self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN - self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN - - def init(self): - self.Init() - - def Init(self): - print("EPD init...") - epdconfig.module_init() - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - self.Reset() - - #panel setting - self.M1_SendCommand(0x00) - self.M1_SendData(0x2f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f - self.S1_SendCommand(0x00) - self.S1_SendData(0x2f) - self.M2_SendCommand(0x00) - self.M2_SendData(0x23) - self.S2_SendCommand(0x00) - self.S2_SendData(0x23) - - # POWER SETTING - self.M1_SendCommand(0x01) - self.M1_SendData(0x07) - self.M1_SendData(0x17) # VGH=20V,VGL=-20V - self.M1_SendData(0x3F) # VDH=15V - self.M1_SendData(0x3F) # VDL=-15V - self.M1_SendData(0x0d) - self.M2_SendCommand(0x01) - self.M2_SendData(0x07) - self.M2_SendData(0x17) # VGH=20V,VGL=-20V - self.M2_SendData(0x3F) # VDH=15V - self.M2_SendData(0x3F) # VDL=-15V - self.M2_SendData(0x0d) - - # booster soft start - self.M1_SendCommand(0x06) - self.M1_SendData(0x17) #A - self.M1_SendData(0x17) #B - self.M1_SendData(0x39) #C - self.M1_SendData(0x17) - self.M2_SendCommand(0x06) - self.M2_SendData(0x17) - self.M2_SendData(0x17) - self.M2_SendData(0x39) - self.M2_SendData(0x17) - - #resolution setting - self.M1_SendCommand(0x61) - self.M1_SendData(0x02) - self.M1_SendData(0x88) #source 648 - self.M1_SendData(0x01) #gate 492 - self.M1_SendData(0xEC) - self.S1_SendCommand(0x61) - self.S1_SendData(0x02) - self.S1_SendData(0x90) #source 656 - self.S1_SendData(0x01) #gate 492 - self.S1_SendData(0xEC) - self.M2_SendCommand(0x61) - self.M2_SendData(0x02) - self.M2_SendData(0x90) #source 656 - self.M2_SendData(0x01) #gate 492 - self.M2_SendData(0xEC) - self.S2_SendCommand(0x61) - self.S2_SendData(0x02) - self.S2_SendData(0x88) #source 648 - self.S2_SendData(0x01) #gate 492 - self.S2_SendData(0xEC) - - self.M1S1M2S2_SendCommand(0x15) #DUSPI - self.M1S1M2S2_SendData(0x20) - - self.M1S1M2S2_SendCommand(0x30) # PLL - self.M1S1M2S2_SendData(0x08) - - self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting - self.M1S1M2S2_SendData(0x31) - self.M1S1M2S2_SendData(0x07) - - self.M1S1M2S2_SendCommand(0x60)#TCON - self.M1S1M2S2_SendData(0x22) - - self.M1_SendCommand(0xE0) #POWER SETTING - self.M1_SendData(0x01) - self.M2_SendCommand(0xE0) #POWER SETTING - self.M2_SendData(0x01) - - self.M1S1M2S2_SendCommand(0xE3) - self.M1S1M2S2_SendData(0x00) - - self.M1_SendCommand(0x82) - self.M1_SendData(0x1c) - self.M2_SendCommand(0x82) - self.M2_SendData(0x1c) - - self.SetLut() - - def display(self, BlackImage, RedImage): - Blackbuf = [0x00] * int(self.width * self.height / 8) - blackconvert = BlackImage.convert('1') - bimwidth, bimheight = blackconvert.size - Blackpixles = blackconvert.load() - temp=0; - for y in range(0, bimheight): - for x in range(0, bimwidth): - if Blackpixles[x, y] < 127: # black - Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) - else: # white - Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp) - temp=temp+1 - if(temp==8): - temp=0 - - Redbuf = [0x00] * int(self.width * self.height / 8) - redconvert = RedImage.convert('1') - rimwidth, rimheight = redconvert.size - Redpixles = redconvert.load() - temp=0; - for y in range(0, rimheight): - for x in range(0, rimwidth): - if Redpixles[x, y] < 127: # black - Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) - else: # white - Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp) - temp=temp+1 - if(temp==8): - temp=0 - - #S2 part 648*492 - self.S2_SendCommand(0x10) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(Blackbuf[y*163 + x]) - self.S2_SendCommand(0x13) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(~Redbuf[y*163 + x]) - - #M2 part 656*492 - self.M2_SendCommand(0x10) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(Blackbuf[y*163 + x]) - self.M2_SendCommand(0x13) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(~Redbuf[y*163 + x]) - - #M1 part 648*492 - self.M1_SendCommand(0x10) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(Blackbuf[y*163 + x]) - self.M1_SendCommand(0x13) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(~Redbuf[y*163 + x]) - - #S1 part 656*492 - self.S1_SendCommand(0x10) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(Blackbuf[y*163 + x]) - self.S1_SendCommand(0x13) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(~Redbuf[y*163 + x]) - - self.TurnOnDisplay() - - def clear(self): - """Clear contents of image buffer""" - self.S2_SendCommand(0x10) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(0xff) - self.S2_SendCommand(0x13) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(0x00) - - self.M2_SendCommand(0x10) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(0xff) - self.M2_SendCommand(0x13) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(0x00) - - self.M1_SendCommand(0x10) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(0xff) - self.M1_SendCommand(0x13) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(0x00) - - self.S1_SendCommand(0x10) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(0xff) - self.S1_SendCommand(0x13) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(0x00) - - self.TurnOnDisplay() - - def Reset(self): - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) - time.sleep(0.2) - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) - time.sleep(0.01) - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) - time.sleep(0.2) - - def sleep(self): - self.EPD_Sleep() - - def EPD_Sleep(self): - self.M1S1M2S2_SendCommand(0X02) - time.sleep(0.3) - - self.M1S1M2S2_SendCommand(0X07) - self.M1S1M2S2_SendData(0xA5) - time.sleep(0.3) - print("module_exit") - epdconfig.module_exit() - - def TurnOnDisplay(self): - self.M1M2_SendCommand(0x04) - time.sleep(0.3) - self.M1S1M2S2_SendCommand(0x12) - self.M1_ReadBusy() - self.S1_ReadBusy() - self.M2_ReadBusy() - self.S2_ReadBusy() - - """ M1S1M2S2 Write register address and data """ - def M1S1M2S2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - def M1S1M2S2_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - """ M1M2 Write register address and data """ - def M1M2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - def M1M2_Sendata(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - """ S2 Write register address and data """ - def S2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - def S2_SendData(self, val): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - """ M2 Write register address and data """ - def M2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - def M2_SendData(self, val): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - """ S1 Write register address and data """ - def S1_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - def S1_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - - """ M1 Write register address and data """ - def M1_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - def M1_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - - #Busy - def M1_ReadBusy(self): - self.M1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) - busy = not(busy & 0x01) - while(busy): - self.M1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - def M2_ReadBusy(self): - self.M2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) - busy = not(busy & 0x01) - self.M2_SendCommand(0x71) - while(busy): - self.M2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) - busy =not(busy & 0x01) - time.sleep(0.2) - def S1_ReadBusy(self): - self.S1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) - busy = not(busy & 0x01) - while(busy): - self.S1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - def S2_ReadBusy(self): - self.S2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) - busy = not(busy & 0x01) - while(busy): - self.S2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - - lut_vcom1 = [ - 0x00, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_ww1 = [ - 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_bw1 = [ - 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x84, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x86, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x8C, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_wb1 = [ - 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_bb1 = [ - 0x92, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - - def SetLut(self): - self.M1S1M2S2_SendCommand(0x20) #vcom - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_vcom1[count]) - - self.M1S1M2S2_SendCommand(0x21) #red not use - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_ww1[count]) - - self.M1S1M2S2_SendCommand(0x22) #bw r - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r - - self.M1S1M2S2_SendCommand(0x23) #wb w - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w - - self.M1S1M2S2_SendCommand(0x24) #bb b - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b - - self.M1S1M2S2_SendCommand(0x25) #bb b - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b diff --git a/src/drivers/epd12in48b_V2.py b/src/drivers/epd12in48b_V2.py deleted file mode 100644 index b6e90a2..0000000 --- a/src/drivers/epd12in48b_V2.py +++ /dev/null @@ -1,529 +0,0 @@ -# /***************************************************************************** -# * | File : epd12in48b_V2.py -# * | Author : Waveshare electrices -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2022-09-14 -# * | 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 time -import epdconfig - -EPD_WIDTH = 1304 -EPD_HEIGHT = 984 - -class EPD(object): - def __init__(self): - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN - self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN - self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN - self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN - - self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN - self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN - - self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN - self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN - - self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN - self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN - self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN - self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN - - def Init(self): - print("EPD init...") - epdconfig.module_init() - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - self.Reset() - - # panel setting for Clear - # self.M1_SendCommand(0x00) - # self.M1_SendData(0x07) #KW-3f KWR-2F BWROTP 0f BWOTP 1f - # self.S1_SendCommand(0x00) - # self.S1_SendData(0x07) - # self.M2_SendCommand(0x00) - # self.M2_SendData(0x07) - # self.S2_SendCommand(0x00) - # self.S2_SendData(0x07) - - # panel setting for Display - self.M1_SendCommand(0x00) - self.M1_SendData(0x0f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f - self.S1_SendCommand(0x00) - self.S1_SendData(0x0f) - self.M2_SendCommand(0x00) - self.M2_SendData(0x03) - self.S2_SendCommand(0x00) - self.S2_SendData(0x03) - - # booster soft start - self.M1_SendCommand(0x06) - self.M1_SendData(0x17) #A - self.M1_SendData(0x17) #B - self.M1_SendData(0x39) #C - self.M1_SendData(0x17) - self.M2_SendCommand(0x06) - self.M2_SendData(0x17) - self.M2_SendData(0x17) - self.M2_SendData(0x39) - self.M2_SendData(0x17) - - #resolution setting - self.M1_SendCommand(0x61) - self.M1_SendData(0x02) - self.M1_SendData(0x88) #source 648 - self.M1_SendData(0x01) #gate 492 - self.M1_SendData(0xEC) - self.S1_SendCommand(0x61) - self.S1_SendData(0x02) - self.S1_SendData(0x90) #source 656 - self.S1_SendData(0x01) #gate 492 - self.S1_SendData(0xEC) - self.M2_SendCommand(0x61) - self.M2_SendData(0x02) - self.M2_SendData(0x90) #source 656 - self.M2_SendData(0x01) #gate 492 - self.M2_SendData(0xEC) - self.S2_SendCommand(0x61) - self.S2_SendData(0x02) - self.S2_SendData(0x88) #source 648 - self.S2_SendData(0x01) #gate 492 - self.S2_SendData(0xEC) - - self.M1S1M2S2_SendCommand(0x15) #DUSPI - self.M1S1M2S2_SendData(0x20) - - self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting - self.M1S1M2S2_SendData(0x11) - self.M1S1M2S2_SendData(0x07) - - self.M1S1M2S2_SendCommand(0x60)#TCON - self.M1S1M2S2_SendData(0x22) - - self.M1S1M2S2_SendCommand(0xE3) - self.M1S1M2S2_SendData(0x00) - - self.M1_ReadTemperature() - - def display(self, BlackImage, RedImage): - start = time.perf_counter() - - Blackbuf = [0x00] * int(self.width * self.height / 8) - blackconvert = BlackImage.convert('1') - bimwidth, bimheight = blackconvert.size - Blackpixles = blackconvert.load() - temp=0 - for y in range(0, bimheight): - for x in range(0, bimwidth): - if Blackpixles[x, y] < 127: # black - Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) - else: # white - Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp) - temp=temp+1 - if(temp==8): - temp=0 - - Redbuf = [0x00] * int(self.width * self.height / 8) - redconvert = RedImage.convert('1') - rimwidth, rimheight = redconvert.size - Redpixles = redconvert.load() - temp=0 - for y in range(0, rimheight): - for x in range(0, rimwidth): - if Redpixles[x, y] < 127: # black - Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) - else: # white - Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp) - temp=temp+1 - if(temp==8): - temp=0 - - #S2 part 648*492 - self.S2_SendCommand(0x10) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(Blackbuf[y*163 + x]) - self.S2_SendCommand(0x13) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(~Redbuf[y*163 + x]) - - #M2 part 656*492 - self.M2_SendCommand(0x10) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(Blackbuf[y*163 + x]) - self.M2_SendCommand(0x13) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(~Redbuf[y*163 + x]) - - #M1 part 648*492 - self.M1_SendCommand(0x10) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(Blackbuf[y*163 + x]) - self.M1_SendCommand(0x13) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(~Redbuf[y*163 + x]) - - #S1 part 656*492 - self.S1_SendCommand(0x10) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(Blackbuf[y*163 + x]) - self.S1_SendCommand(0x13) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(~Redbuf[y*163 + x]) - - end = time.perf_counter() - print("use time: %f"%(end - start)) - self.TurnOnDisplay() - - def clear(self): - """Clear contents of image buffer""" - start = time.perf_counter() - - self.S2_SendCommand(0x10) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(0xff) - self.S2_SendCommand(0x13) - for y in range(0, 492): - for x in range(0, 81): - self.S2_SendData(0x00) - - self.M2_SendCommand(0x10) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(0xff) - self.M2_SendCommand(0x13) - for y in range(0, 492): - for x in range(81, 163): - self.M2_SendData(0x00) - - self.M1_SendCommand(0x10) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(0xff) - self.M1_SendCommand(0x13) - for y in range(492, 984): - for x in range(0, 81): - self.M1_SendData(0x00) - - self.S1_SendCommand(0x10) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(0xff) - self.S1_SendCommand(0x13) - for y in range(492, 984): - for x in range(81, 163): - self.S1_SendData(0x00) - - end = time.perf_counter() - print (end) - print (start) - print("use time: %f" %(end - start)) - - self.TurnOnDisplay() - - def Reset(self): - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) - time.sleep(0.2) - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) - time.sleep(0.01) - epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) - time.sleep(0.2) - - def EPD_Sleep(self): - self.M1S1M2S2_SendCommand(0X02) - time.sleep(0.3) - - self.M1S1M2S2_SendCommand(0X07) - self.M1S1M2S2_SendData(0xA5) - time.sleep(0.3) - print("module_exit") - epdconfig.module_exit() - - def TurnOnDisplay(self): - self.M1M2_SendCommand(0x04) - time.sleep(0.3) - self.M1S1M2S2_SendCommand(0x12) - self.M1_ReadBusy() - self.S1_ReadBusy() - self.M2_ReadBusy() - self.S2_ReadBusy() - - """ M1S1M2S2 Write register address and data """ - def M1S1M2S2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - def M1S1M2S2_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - """ M1M2 Write register address and data """ - def M1M2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - def M1M2_Sendata(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - """ S2 Write register address and data """ - def S2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - def S2_SendData(self, val): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - """ M2 Write register address and data """ - def M2_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - def M2_SendData(self, val): - epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - - """ S1 Write register address and data """ - def S1_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - def S1_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - - """ M1 Write register address and data """ - def M1_SendCommand(self, cmd): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.spi_writebyte(cmd) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - def M1_SendData(self, val): - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.spi_writebyte(val) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - - #Busy - def M1_ReadBusy(self): - self.M1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) - busy = not(busy & 0x01) - while(busy): - self.M1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - def M2_ReadBusy(self): - self.M2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) - busy = not(busy & 0x01) - self.M2_SendCommand(0x71) - while(busy): - self.M2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) - busy =not(busy & 0x01) - time.sleep(0.2) - def S1_ReadBusy(self): - self.S1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) - busy = not(busy & 0x01) - while(busy): - self.S1_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - def S2_ReadBusy(self): - self.S2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) - busy = not(busy & 0x01) - while(busy): - self.S2_SendCommand(0x71) - busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) - busy = not(busy & 0x01) - time.sleep(0.2) - - lut_vcom1 = [ - 0x00, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_ww1 = [ - 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_bw1 = [ - 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x84, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x86, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x8C, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_wb1 = [ - 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - lut_bb1 = [ - 0x92, 0x10, 0x10, 0x01, 0x08, 0x01, - 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, - 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, - 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, - ] - - def SetLut(self): - self.M1S1M2S2_SendCommand(0x20) #vcom - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_vcom1[count]) - - self.M1S1M2S2_SendCommand(0x21) #red not use - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_ww1[count]) - - self.M1S1M2S2_SendCommand(0x22) #bw r - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r - - self.M1S1M2S2_SendCommand(0x23) #wb w - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w - - self.M1S1M2S2_SendCommand(0x24) #bb b - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b - - self.M1S1M2S2_SendCommand(0x25) #bb b - for count in range(0, 60): - self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b - - def M1_ReadTemperature(self): - self.M1_SendCommand(0x40) - self.M1_ReadBusy() - time.sleep(0.3) - - epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) - epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) - epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) - epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) - - epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) - time.sleep(0.05) - - temp = epdconfig.spi_readbyte(0x00) - epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) - - self.M1S1M2S2_SendCommand(0xE0) - self.M1S1M2S2_SendData(0x03) - self.M1S1M2S2_SendCommand(0xE5) - self.M1S1M2S2_SendData(temp) diff --git a/src/drivers/epd_12_in_48_lib_32bit.so b/src/drivers/epd_12_in_48_lib_32bit.so deleted file mode 100644 index acdbb26..0000000 Binary files a/src/drivers/epd_12_in_48_lib_32bit.so and /dev/null differ diff --git a/src/drivers/epd_12_in_48_lib_64bit.so b/src/drivers/epd_12_in_48_lib_64bit.so deleted file mode 100644 index ed8ae87..0000000 Binary files a/src/drivers/epd_12_in_48_lib_64bit.so and /dev/null differ diff --git a/src/drivers/epdconfig.py b/src/drivers/epdconfig.py deleted file mode 100644 index c70a1f1..0000000 --- a/src/drivers/epdconfig.py +++ /dev/null @@ -1,99 +0,0 @@ -# /***************************************************************************** -# * | File : epdconfig.py -# * | Author : Waveshare electrices -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2019-11-01 -# * | 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 time -import os -import logging -import sys - -from ctypes import * - -EPD_SCK_PIN =11 -EPD_MOSI_PIN =10 - -EPD_M1_CS_PIN =8 -EPD_S1_CS_PIN =7 -EPD_M2_CS_PIN =17 -EPD_S2_CS_PIN =18 - -EPD_M1S1_DC_PIN =13 -EPD_M2S2_DC_PIN =22 - -EPD_M1S1_RST_PIN =6 -EPD_M2S2_RST_PIN =23 - -EPD_M1_BUSY_PIN =5 -EPD_S1_BUSY_PIN =19 -EPD_M2_BUSY_PIN =27 -EPD_S2_BUSY_PIN =24 - -find_dirs = [ - os.path.dirname(os.path.realpath(__file__)), - '/usr/local/lib', - '/usr/lib', -] -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, 'epd_12_in_48_lib_64bit.so') - else: - so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_32bit.so') - if os.path.exists(so_filename): - spi = CDLL(so_filename) - break -if spi is None: - RuntimeError('Cannot find DEV_Config.so') - -def digital_write(pin, value): - spi.DEV_Digital_Write(pin, value) - -def digital_read(pin): - return spi.DEV_Digital_Read(pin) - -def spi_writebyte(value): - spi.DEV_SPI_WriteByte(value) - -def delay_ms(delaytime): - time.sleep(delaytime / 1000.0) - -def module_init(): - spi.DEV_ModuleInit() - -def module_exit(): - spi.DEV_ModuleExit() - - -def spi_readbyte(Reg): - return spi.DEV_SPI_ReadByte(Reg) - -def delay_ms(delaytime): - time.sleep(delaytime / 1000.0) - - diff --git a/src/epaper_display/__init__.py b/src/epaper_display/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/epaper_display/display.py b/src/epaper_display/display.py new file mode 100644 index 0000000..1899d42 --- /dev/null +++ b/src/epaper_display/display.py @@ -0,0 +1,47 @@ +""" +""" + +from logging import Logger + +import PIL +from PIL import Image + +from drivers.epd12in48b import EPD, EPD_HEIGHT, EPD_WIDTH + +logger = Logger(__name__) + + +class Display: + + def __init__(self) -> None: + self.width = EPD_WIDTH + self.height = EPD_HEIGHT + self.epaper = EPD() + + def render(self, black: Image, red: Image): + logger.info("Init display") + self.epaper.init() + logger.info("Update display") + self.epaper.display(black, red) + logger.info("Sleep display") + self.epaper.sleep() + + def calibrate(self, iterations=1): + logger.info("Init display for calibration") + self.epaper.init() + + white = Image.new('1', (self.width, self.height), 'white') + black = Image.new('1', (self.width, self.height), 'black') + + logger.info('Calibrating e-paper display') + for i in range(iterations): + logger.info('black') + self.epaper.display(black, white) + logger.info('red') + self.epaper.display(white, black) + logger.info('white') + self.epaper.display(white, white) + logger.info(f'#{i + 1} of {iterations} complete') + + self.epaper.sleep() + diff --git a/src/epaper_display/drivers/__init__.py b/src/epaper_display/drivers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/epaper_display/drivers/epd12in48.py b/src/epaper_display/drivers/epd12in48.py new file mode 100644 index 0000000..16b33f5 --- /dev/null +++ b/src/epaper_display/drivers/epd12in48.py @@ -0,0 +1,398 @@ +# /***************************************************************************** +# * | File : epd12in48.py +# * | Author : Waveshare electrices +# * | Function : Hardware underlying interface +# * | Info : +# *---------------- +# * | This version: V1.0 +# * | Date : 2019-11-01 +# * | 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 time +import epdconfig + +EPD_WIDTH = 1304 +EPD_HEIGHT = 984 + +class EPD(object): + def __init__(self): + self.width = EPD_WIDTH + self.height = EPD_HEIGHT + + self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN + self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN + self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN + self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN + + self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN + self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN + + self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN + self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN + + self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN + self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN + self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN + self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN + + def Init(self): + print("EPD init...") + epdconfig.module_init() + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + self.Reset() + + #panel setting + self.M1_SendCommand(0x00) + self.M1_SendData(0x1f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f + self.S1_SendCommand(0x00) + self.S1_SendData(0x1f) + self.M2_SendCommand(0x00) + self.M2_SendData(0x13) + self.S2_SendCommand(0x00) + self.S2_SendData(0x13) + + # booster soft start + self.M1_SendCommand(0x06) + self.M1_SendData(0x17) #A + self.M1_SendData(0x17) #B + self.M1_SendData(0x39) #C + self.M1_SendData(0x17) + self.M2_SendCommand(0x06) + self.M2_SendData(0x17) + self.M2_SendData(0x17) + self.M2_SendData(0x39) + self.M2_SendData(0x17) + + #resolution setting + self.M1_SendCommand(0x61) + self.M1_SendData(0x02) + self.M1_SendData(0x88) #source 648 + self.M1_SendData(0x01) #gate 492 + self.M1_SendData(0xEC) + self.S1_SendCommand(0x61) + self.S1_SendData(0x02) + self.S1_SendData(0x90) #source 656 + self.S1_SendData(0x01) #gate 492 + self.S1_SendData(0xEC) + self.M2_SendCommand(0x61) + self.M2_SendData(0x02) + self.M2_SendData(0x90) #source 656 + self.M2_SendData(0x01) #gate 492 + self.M2_SendData(0xEC) + self.S2_SendCommand(0x61) + self.S2_SendData(0x02) + self.S2_SendData(0x88) #source 648 + self.S2_SendData(0x01) #gate 492 + self.S2_SendData(0xEC) + + self.M1S1M2S2_SendCommand(0x15) #DUSPI + self.M1S1M2S2_SendData(0x20) + + self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting + self.M1S1M2S2_SendData(0x21) #Border KW + self.M1S1M2S2_SendData(0x07) + + self.M1S1M2S2_SendCommand(0x60) #TCON + self.M1S1M2S2_SendData(0x22) + + self.M1S1M2S2_SendCommand(0xE3) + self.M1S1M2S2_SendData(0x00) + + #temperature + temp = self.M1_ReadTemperature() + + self.M1S1M2S2_SendCommand(0xe0) #Cascade setting + self.M1S1M2S2_SendData(0x03) + self.M1S1M2S2_SendCommand(0xe5) #Force temperature + self.M1S1M2S2_SendData(temp) + + def display(self, Image): + start = time.clock() + buf = [0x00] * int(self.width * self.height / 8) + image_monocolor = Image.convert('1') + imwidth, imheight = image_monocolor.size + pixels = image_monocolor.load() + temp=0; + for y in range(0, imheight): + for x in range(0, imwidth): + # Set the bits for the column of pixels at the current position. + if pixels[x, y] < 127: # black + buf[int((x + y*self.width)/8)] &= ~(0x80>>temp) + else: # white + buf[int((x + y*self.width)/8)] |= (0x80>>temp) + temp=temp+1 + if(temp==8): + temp=0 + + #M1 part 648*492 + self.M1_SendCommand(0x13) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(buf[y*163 + x]) + + #S1 part 656*492 + self.S1_SendCommand(0x13) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(buf[y*163 + x]) + + #M2 part 656*492 + self.M2_SendCommand(0x13) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(buf[y*163 + x]) + + #S2 part 648*492 + self.S2_SendCommand(0x13) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(buf[y*163 + x]) + + end = time.clock() + print("use time:%f"%(end - start)) + self.TurnOnDisplay() + + def clear(self): + """Clear contents of image buffer""" + start = time.clock() + self.M1_SendCommand(0x13) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(0xff) + + self.S1_SendCommand(0x13) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(0xff) + + self.M2_SendCommand(0x13) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(0xff) + + self.S2_SendCommand(0x13) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(0xff) + end = time.clock() + print("use time:%f"%(end - start)) + self.TurnOnDisplay() + + """ M1S1M2S2 Write register address and data """ + def M1S1M2S2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + def M1S1M2S2_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + """ M1M2 Write register address and data """ + def M1M2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + def M1S1M2S2_Senddata(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + """ S2 Write register address and data """ + def S2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + + def S2_SendData(self, val): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + """ M2 Write register address and data """ + def M2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + def M2_SendData(self, val): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + """ S1 Write register address and data """ + def S1_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + + def S1_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + + """ M1 Write register address and data """ + def M1_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + + def M1_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + + def Reset(self): + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) + time.sleep(0.2) + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) + time.sleep(0.01) + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) + time.sleep(0.2) + + def EPD_Sleep(self): + self.M1S1M2S2_SendCommand(0X02) + time.sleep(0.3) + + self.M1S1M2S2_SendCommand(0X07) + self.M1S1M2S2_SendData(0xA5) + time.sleep(0.3) + print("module_exit") + epdconfig.module_exit() + + + def TurnOnDisplay(self): + self.M1M2_SendCommand(0x04) + time.sleep(0.3) + self.M1S1M2S2_SendCommand(0x12) + self.M1_ReadBusy() + self.S1_ReadBusy() + self.M2_ReadBusy() + self.S2_ReadBusy() + + #Busy + def M1_ReadBusy(self): + self.M1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) + busy = not(busy & 0x01) + print("M1_ReadBusy") + while(busy): + self.M1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + + def M2_ReadBusy(self): + self.M2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) + busy = not(busy & 0x01) + print("M2_ReadBusy") + while(busy): + self.M2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) + busy =not(busy & 0x01) + time.sleep(0.2) + + def S1_ReadBusy(self): + self.S1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) + busy = not(busy & 0x01) + print("s1_ReadBusy") + while(busy): + self.S1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + + def S2_ReadBusy(self): + self.S2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) + busy = not(busy & 0x01) + print("S2_ReadBusy") + while(busy): + self.S2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + + def M1_ReadTemperature(self): + self.M1_SendCommand(0x40) + self.M1_ReadBusy() + time.sleep(0.3) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + time.sleep(0.01) + + # temp = epdconfig.spi_readbyte(0x00) + temp = 25 + print("Read Temperature Reg:%d"%temp) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + # temp =0x29 + return temp diff --git a/src/epaper_display/drivers/epd12in48b.py b/src/epaper_display/drivers/epd12in48b.py new file mode 100644 index 0000000..e4035a4 --- /dev/null +++ b/src/epaper_display/drivers/epd12in48b.py @@ -0,0 +1,520 @@ +# /***************************************************************************** +# * | File : epd12in48.py +# * | Author : Waveshare electrices +# * | Function : Hardware underlying interface +# * | Info : +# *---------------- +# * | This version: V1.0 +# * | Date : 2019-11-01 +# * | 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 time +from . import epdconfig + +EPD_WIDTH = 1304 +EPD_HEIGHT = 984 + +class EPD(object): + def __init__(self): + self.width = EPD_WIDTH + self.height = EPD_HEIGHT + + self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN + self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN + self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN + self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN + + self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN + self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN + + self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN + self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN + + self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN + self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN + self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN + self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN + + def init(self): + self.Init() + + def Init(self): + print("EPD init...") + epdconfig.module_init() + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + self.Reset() + + #panel setting + self.M1_SendCommand(0x00) + self.M1_SendData(0x2f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f + self.S1_SendCommand(0x00) + self.S1_SendData(0x2f) + self.M2_SendCommand(0x00) + self.M2_SendData(0x23) + self.S2_SendCommand(0x00) + self.S2_SendData(0x23) + + # POWER SETTING + self.M1_SendCommand(0x01) + self.M1_SendData(0x07) + self.M1_SendData(0x17) # VGH=20V,VGL=-20V + self.M1_SendData(0x3F) # VDH=15V + self.M1_SendData(0x3F) # VDL=-15V + self.M1_SendData(0x0d) + self.M2_SendCommand(0x01) + self.M2_SendData(0x07) + self.M2_SendData(0x17) # VGH=20V,VGL=-20V + self.M2_SendData(0x3F) # VDH=15V + self.M2_SendData(0x3F) # VDL=-15V + self.M2_SendData(0x0d) + + # booster soft start + self.M1_SendCommand(0x06) + self.M1_SendData(0x17) #A + self.M1_SendData(0x17) #B + self.M1_SendData(0x39) #C + self.M1_SendData(0x17) + self.M2_SendCommand(0x06) + self.M2_SendData(0x17) + self.M2_SendData(0x17) + self.M2_SendData(0x39) + self.M2_SendData(0x17) + + #resolution setting + self.M1_SendCommand(0x61) + self.M1_SendData(0x02) + self.M1_SendData(0x88) #source 648 + self.M1_SendData(0x01) #gate 492 + self.M1_SendData(0xEC) + self.S1_SendCommand(0x61) + self.S1_SendData(0x02) + self.S1_SendData(0x90) #source 656 + self.S1_SendData(0x01) #gate 492 + self.S1_SendData(0xEC) + self.M2_SendCommand(0x61) + self.M2_SendData(0x02) + self.M2_SendData(0x90) #source 656 + self.M2_SendData(0x01) #gate 492 + self.M2_SendData(0xEC) + self.S2_SendCommand(0x61) + self.S2_SendData(0x02) + self.S2_SendData(0x88) #source 648 + self.S2_SendData(0x01) #gate 492 + self.S2_SendData(0xEC) + + self.M1S1M2S2_SendCommand(0x15) #DUSPI + self.M1S1M2S2_SendData(0x20) + + self.M1S1M2S2_SendCommand(0x30) # PLL + self.M1S1M2S2_SendData(0x08) + + self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting + self.M1S1M2S2_SendData(0x31) + self.M1S1M2S2_SendData(0x07) + + self.M1S1M2S2_SendCommand(0x60)#TCON + self.M1S1M2S2_SendData(0x22) + + self.M1_SendCommand(0xE0) #POWER SETTING + self.M1_SendData(0x01) + self.M2_SendCommand(0xE0) #POWER SETTING + self.M2_SendData(0x01) + + self.M1S1M2S2_SendCommand(0xE3) + self.M1S1M2S2_SendData(0x00) + + self.M1_SendCommand(0x82) + self.M1_SendData(0x1c) + self.M2_SendCommand(0x82) + self.M2_SendData(0x1c) + + self.SetLut() + + def display(self, BlackImage, RedImage): + Blackbuf = [0x00] * int(self.width * self.height / 8) + blackconvert = BlackImage.convert('1') + bimwidth, bimheight = blackconvert.size + Blackpixles = blackconvert.load() + temp=0; + for y in range(0, bimheight): + for x in range(0, bimwidth): + if Blackpixles[x, y] < 127: # black + Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) + else: # white + Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp) + temp=temp+1 + if(temp==8): + temp=0 + + Redbuf = [0x00] * int(self.width * self.height / 8) + redconvert = RedImage.convert('1') + rimwidth, rimheight = redconvert.size + Redpixles = redconvert.load() + temp=0; + for y in range(0, rimheight): + for x in range(0, rimwidth): + if Redpixles[x, y] < 127: # black + Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) + else: # white + Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp) + temp=temp+1 + if(temp==8): + temp=0 + + #S2 part 648*492 + self.S2_SendCommand(0x10) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(Blackbuf[y*163 + x]) + self.S2_SendCommand(0x13) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(~Redbuf[y*163 + x]) + + #M2 part 656*492 + self.M2_SendCommand(0x10) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(Blackbuf[y*163 + x]) + self.M2_SendCommand(0x13) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(~Redbuf[y*163 + x]) + + #M1 part 648*492 + self.M1_SendCommand(0x10) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(Blackbuf[y*163 + x]) + self.M1_SendCommand(0x13) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(~Redbuf[y*163 + x]) + + #S1 part 656*492 + self.S1_SendCommand(0x10) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(Blackbuf[y*163 + x]) + self.S1_SendCommand(0x13) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(~Redbuf[y*163 + x]) + + self.TurnOnDisplay() + + def clear(self): + """Clear contents of image buffer""" + self.S2_SendCommand(0x10) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(0xff) + self.S2_SendCommand(0x13) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(0x00) + + self.M2_SendCommand(0x10) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(0xff) + self.M2_SendCommand(0x13) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(0x00) + + self.M1_SendCommand(0x10) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(0xff) + self.M1_SendCommand(0x13) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(0x00) + + self.S1_SendCommand(0x10) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(0xff) + self.S1_SendCommand(0x13) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(0x00) + + self.TurnOnDisplay() + + def Reset(self): + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) + time.sleep(0.2) + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) + time.sleep(0.01) + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) + time.sleep(0.2) + + def sleep(self): + self.EPD_Sleep() + + def EPD_Sleep(self): + self.M1S1M2S2_SendCommand(0X02) + time.sleep(0.3) + + self.M1S1M2S2_SendCommand(0X07) + self.M1S1M2S2_SendData(0xA5) + time.sleep(0.3) + print("module_exit") + epdconfig.module_exit() + + def TurnOnDisplay(self): + self.M1M2_SendCommand(0x04) + time.sleep(0.3) + self.M1S1M2S2_SendCommand(0x12) + self.M1_ReadBusy() + self.S1_ReadBusy() + self.M2_ReadBusy() + self.S2_ReadBusy() + + """ M1S1M2S2 Write register address and data """ + def M1S1M2S2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + def M1S1M2S2_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + """ M1M2 Write register address and data """ + def M1M2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + def M1M2_Sendata(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + """ S2 Write register address and data """ + def S2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + def S2_SendData(self, val): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + """ M2 Write register address and data """ + def M2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + def M2_SendData(self, val): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + """ S1 Write register address and data """ + def S1_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + def S1_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + + """ M1 Write register address and data """ + def M1_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + def M1_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + + #Busy + def M1_ReadBusy(self): + self.M1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) + busy = not(busy & 0x01) + while(busy): + self.M1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + def M2_ReadBusy(self): + self.M2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) + busy = not(busy & 0x01) + self.M2_SendCommand(0x71) + while(busy): + self.M2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) + busy =not(busy & 0x01) + time.sleep(0.2) + def S1_ReadBusy(self): + self.S1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) + busy = not(busy & 0x01) + while(busy): + self.S1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + def S2_ReadBusy(self): + self.S2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) + busy = not(busy & 0x01) + while(busy): + self.S2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + + lut_vcom1 = [ + 0x00, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_ww1 = [ + 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_bw1 = [ + 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x84, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x86, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x8C, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_wb1 = [ + 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_bb1 = [ + 0x92, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + + def SetLut(self): + self.M1S1M2S2_SendCommand(0x20) #vcom + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_vcom1[count]) + + self.M1S1M2S2_SendCommand(0x21) #red not use + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_ww1[count]) + + self.M1S1M2S2_SendCommand(0x22) #bw r + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r + + self.M1S1M2S2_SendCommand(0x23) #wb w + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w + + self.M1S1M2S2_SendCommand(0x24) #bb b + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b + + self.M1S1M2S2_SendCommand(0x25) #bb b + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b diff --git a/src/epaper_display/drivers/epd12in48b_V2.py b/src/epaper_display/drivers/epd12in48b_V2.py new file mode 100644 index 0000000..b6e90a2 --- /dev/null +++ b/src/epaper_display/drivers/epd12in48b_V2.py @@ -0,0 +1,529 @@ +# /***************************************************************************** +# * | File : epd12in48b_V2.py +# * | Author : Waveshare electrices +# * | Function : Hardware underlying interface +# * | Info : +# *---------------- +# * | This version: V1.0 +# * | Date : 2022-09-14 +# * | 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 time +import epdconfig + +EPD_WIDTH = 1304 +EPD_HEIGHT = 984 + +class EPD(object): + def __init__(self): + self.width = EPD_WIDTH + self.height = EPD_HEIGHT + + self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN + self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN + self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN + self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN + + self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN + self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN + + self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN + self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN + + self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN + self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN + self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN + self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN + + def Init(self): + print("EPD init...") + epdconfig.module_init() + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + self.Reset() + + # panel setting for Clear + # self.M1_SendCommand(0x00) + # self.M1_SendData(0x07) #KW-3f KWR-2F BWROTP 0f BWOTP 1f + # self.S1_SendCommand(0x00) + # self.S1_SendData(0x07) + # self.M2_SendCommand(0x00) + # self.M2_SendData(0x07) + # self.S2_SendCommand(0x00) + # self.S2_SendData(0x07) + + # panel setting for Display + self.M1_SendCommand(0x00) + self.M1_SendData(0x0f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f + self.S1_SendCommand(0x00) + self.S1_SendData(0x0f) + self.M2_SendCommand(0x00) + self.M2_SendData(0x03) + self.S2_SendCommand(0x00) + self.S2_SendData(0x03) + + # booster soft start + self.M1_SendCommand(0x06) + self.M1_SendData(0x17) #A + self.M1_SendData(0x17) #B + self.M1_SendData(0x39) #C + self.M1_SendData(0x17) + self.M2_SendCommand(0x06) + self.M2_SendData(0x17) + self.M2_SendData(0x17) + self.M2_SendData(0x39) + self.M2_SendData(0x17) + + #resolution setting + self.M1_SendCommand(0x61) + self.M1_SendData(0x02) + self.M1_SendData(0x88) #source 648 + self.M1_SendData(0x01) #gate 492 + self.M1_SendData(0xEC) + self.S1_SendCommand(0x61) + self.S1_SendData(0x02) + self.S1_SendData(0x90) #source 656 + self.S1_SendData(0x01) #gate 492 + self.S1_SendData(0xEC) + self.M2_SendCommand(0x61) + self.M2_SendData(0x02) + self.M2_SendData(0x90) #source 656 + self.M2_SendData(0x01) #gate 492 + self.M2_SendData(0xEC) + self.S2_SendCommand(0x61) + self.S2_SendData(0x02) + self.S2_SendData(0x88) #source 648 + self.S2_SendData(0x01) #gate 492 + self.S2_SendData(0xEC) + + self.M1S1M2S2_SendCommand(0x15) #DUSPI + self.M1S1M2S2_SendData(0x20) + + self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting + self.M1S1M2S2_SendData(0x11) + self.M1S1M2S2_SendData(0x07) + + self.M1S1M2S2_SendCommand(0x60)#TCON + self.M1S1M2S2_SendData(0x22) + + self.M1S1M2S2_SendCommand(0xE3) + self.M1S1M2S2_SendData(0x00) + + self.M1_ReadTemperature() + + def display(self, BlackImage, RedImage): + start = time.perf_counter() + + Blackbuf = [0x00] * int(self.width * self.height / 8) + blackconvert = BlackImage.convert('1') + bimwidth, bimheight = blackconvert.size + Blackpixles = blackconvert.load() + temp=0 + for y in range(0, bimheight): + for x in range(0, bimwidth): + if Blackpixles[x, y] < 127: # black + Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) + else: # white + Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp) + temp=temp+1 + if(temp==8): + temp=0 + + Redbuf = [0x00] * int(self.width * self.height / 8) + redconvert = RedImage.convert('1') + rimwidth, rimheight = redconvert.size + Redpixles = redconvert.load() + temp=0 + for y in range(0, rimheight): + for x in range(0, rimwidth): + if Redpixles[x, y] < 127: # black + Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp) + else: # white + Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp) + temp=temp+1 + if(temp==8): + temp=0 + + #S2 part 648*492 + self.S2_SendCommand(0x10) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(Blackbuf[y*163 + x]) + self.S2_SendCommand(0x13) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(~Redbuf[y*163 + x]) + + #M2 part 656*492 + self.M2_SendCommand(0x10) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(Blackbuf[y*163 + x]) + self.M2_SendCommand(0x13) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(~Redbuf[y*163 + x]) + + #M1 part 648*492 + self.M1_SendCommand(0x10) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(Blackbuf[y*163 + x]) + self.M1_SendCommand(0x13) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(~Redbuf[y*163 + x]) + + #S1 part 656*492 + self.S1_SendCommand(0x10) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(Blackbuf[y*163 + x]) + self.S1_SendCommand(0x13) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(~Redbuf[y*163 + x]) + + end = time.perf_counter() + print("use time: %f"%(end - start)) + self.TurnOnDisplay() + + def clear(self): + """Clear contents of image buffer""" + start = time.perf_counter() + + self.S2_SendCommand(0x10) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(0xff) + self.S2_SendCommand(0x13) + for y in range(0, 492): + for x in range(0, 81): + self.S2_SendData(0x00) + + self.M2_SendCommand(0x10) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(0xff) + self.M2_SendCommand(0x13) + for y in range(0, 492): + for x in range(81, 163): + self.M2_SendData(0x00) + + self.M1_SendCommand(0x10) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(0xff) + self.M1_SendCommand(0x13) + for y in range(492, 984): + for x in range(0, 81): + self.M1_SendData(0x00) + + self.S1_SendCommand(0x10) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(0xff) + self.S1_SendCommand(0x13) + for y in range(492, 984): + for x in range(81, 163): + self.S1_SendData(0x00) + + end = time.perf_counter() + print (end) + print (start) + print("use time: %f" %(end - start)) + + self.TurnOnDisplay() + + def Reset(self): + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) + time.sleep(0.2) + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) + time.sleep(0.01) + epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) + time.sleep(0.2) + + def EPD_Sleep(self): + self.M1S1M2S2_SendCommand(0X02) + time.sleep(0.3) + + self.M1S1M2S2_SendCommand(0X07) + self.M1S1M2S2_SendData(0xA5) + time.sleep(0.3) + print("module_exit") + epdconfig.module_exit() + + def TurnOnDisplay(self): + self.M1M2_SendCommand(0x04) + time.sleep(0.3) + self.M1S1M2S2_SendCommand(0x12) + self.M1_ReadBusy() + self.S1_ReadBusy() + self.M2_ReadBusy() + self.S2_ReadBusy() + + """ M1S1M2S2 Write register address and data """ + def M1S1M2S2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + def M1S1M2S2_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + """ M1M2 Write register address and data """ + def M1M2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + def M1M2_Sendata(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + """ S2 Write register address and data """ + def S2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + def S2_SendData(self, val): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + """ M2 Write register address and data """ + def M2_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + def M2_SendData(self, val): + epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + + """ S1 Write register address and data """ + def S1_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + def S1_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + + """ M1 Write register address and data """ + def M1_SendCommand(self, cmd): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.spi_writebyte(cmd) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + def M1_SendData(self, val): + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.spi_writebyte(val) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + + #Busy + def M1_ReadBusy(self): + self.M1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) + busy = not(busy & 0x01) + while(busy): + self.M1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + def M2_ReadBusy(self): + self.M2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) + busy = not(busy & 0x01) + self.M2_SendCommand(0x71) + while(busy): + self.M2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) + busy =not(busy & 0x01) + time.sleep(0.2) + def S1_ReadBusy(self): + self.S1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) + busy = not(busy & 0x01) + while(busy): + self.S1_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + def S2_ReadBusy(self): + self.S2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) + busy = not(busy & 0x01) + while(busy): + self.S2_SendCommand(0x71) + busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) + busy = not(busy & 0x01) + time.sleep(0.2) + + lut_vcom1 = [ + 0x00, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x00, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_ww1 = [ + 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_bw1 = [ + 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x84, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x86, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x8C, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_wb1 = [ + 0x91, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + lut_bb1 = [ + 0x92, 0x10, 0x10, 0x01, 0x08, 0x01, + 0x80, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x84, 0x08, 0x01, 0x08, 0x01, 0x06, + 0x04, 0x06, 0x01, 0x06, 0x01, 0x05, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06, + 0x00, 0x05, 0x01, 0x1E, 0x0F, 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, + ] + + def SetLut(self): + self.M1S1M2S2_SendCommand(0x20) #vcom + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_vcom1[count]) + + self.M1S1M2S2_SendCommand(0x21) #red not use + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_ww1[count]) + + self.M1S1M2S2_SendCommand(0x22) #bw r + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r + + self.M1S1M2S2_SendCommand(0x23) #wb w + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w + + self.M1S1M2S2_SendCommand(0x24) #bb b + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b + + self.M1S1M2S2_SendCommand(0x25) #bb b + for count in range(0, 60): + self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b + + def M1_ReadTemperature(self): + self.M1_SendCommand(0x40) + self.M1_ReadBusy() + time.sleep(0.3) + + epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) + epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) + epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) + epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) + + epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) + time.sleep(0.05) + + temp = epdconfig.spi_readbyte(0x00) + epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) + + self.M1S1M2S2_SendCommand(0xE0) + self.M1S1M2S2_SendData(0x03) + self.M1S1M2S2_SendCommand(0xE5) + self.M1S1M2S2_SendData(temp) diff --git a/src/epaper_display/drivers/epd_12_in_48_lib_32bit.so b/src/epaper_display/drivers/epd_12_in_48_lib_32bit.so new file mode 100644 index 0000000..acdbb26 Binary files /dev/null and b/src/epaper_display/drivers/epd_12_in_48_lib_32bit.so differ diff --git a/src/epaper_display/drivers/epd_12_in_48_lib_64bit.so b/src/epaper_display/drivers/epd_12_in_48_lib_64bit.so new file mode 100644 index 0000000..ed8ae87 Binary files /dev/null and b/src/epaper_display/drivers/epd_12_in_48_lib_64bit.so differ diff --git a/src/epaper_display/drivers/epdconfig.py b/src/epaper_display/drivers/epdconfig.py new file mode 100644 index 0000000..c70a1f1 --- /dev/null +++ b/src/epaper_display/drivers/epdconfig.py @@ -0,0 +1,99 @@ +# /***************************************************************************** +# * | File : epdconfig.py +# * | Author : Waveshare electrices +# * | Function : Hardware underlying interface +# * | Info : +# *---------------- +# * | This version: V1.0 +# * | Date : 2019-11-01 +# * | 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 time +import os +import logging +import sys + +from ctypes import * + +EPD_SCK_PIN =11 +EPD_MOSI_PIN =10 + +EPD_M1_CS_PIN =8 +EPD_S1_CS_PIN =7 +EPD_M2_CS_PIN =17 +EPD_S2_CS_PIN =18 + +EPD_M1S1_DC_PIN =13 +EPD_M2S2_DC_PIN =22 + +EPD_M1S1_RST_PIN =6 +EPD_M2S2_RST_PIN =23 + +EPD_M1_BUSY_PIN =5 +EPD_S1_BUSY_PIN =19 +EPD_M2_BUSY_PIN =27 +EPD_S2_BUSY_PIN =24 + +find_dirs = [ + os.path.dirname(os.path.realpath(__file__)), + '/usr/local/lib', + '/usr/lib', +] +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, 'epd_12_in_48_lib_64bit.so') + else: + so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_32bit.so') + if os.path.exists(so_filename): + spi = CDLL(so_filename) + break +if spi is None: + RuntimeError('Cannot find DEV_Config.so') + +def digital_write(pin, value): + spi.DEV_Digital_Write(pin, value) + +def digital_read(pin): + return spi.DEV_Digital_Read(pin) + +def spi_writebyte(value): + spi.DEV_SPI_WriteByte(value) + +def delay_ms(delaytime): + time.sleep(delaytime / 1000.0) + +def module_init(): + spi.DEV_ModuleInit() + +def module_exit(): + spi.DEV_ModuleExit() + + +def spi_readbyte(Reg): + return spi.DEV_SPI_ReadByte(Reg) + +def delay_ms(delaytime): + time.sleep(delaytime / 1000.0) + + diff --git a/src/epaper_display/main.py b/src/epaper_display/main.py new file mode 100644 index 0000000..ff77b38 --- /dev/null +++ b/src/epaper_display/main.py @@ -0,0 +1,18 @@ +import logging +import sys + +from PIL import Image + +import renderer + +logger = logging.getLogger() +logger.setLevel(logging.INFO) +logger = logging.getLogger(__name__) + +image = Image.open("testtree_IXCCGR.png") +logger.info("image open") + +rend = renderer.Renderer() + +rend.render(image) + diff --git a/src/epaper_display/renderer.py b/src/epaper_display/renderer.py new file mode 100644 index 0000000..b4274da --- /dev/null +++ b/src/epaper_display/renderer.py @@ -0,0 +1,51 @@ +from PIL import Image + +import display + +from typing import List, Tuple, Callable + +class Renderer: + def __init__(self) -> None: + self.width = display.EPD_HEIGHT + self.height = display.EPD_WIDTH + self.display = display.Display() + self.rules: List[Tuple[Callable[[],bool],Callable[[int,int],Image]]] = []; + self._calibrate_before_next_render = False + + def render(self): + # check for calibration first + if self._calibrate_before_next_render: + self._calibrate_before_next_render = False + self.display.calibrate() + + for rule in self.rules: + if rule[0](): + self.render_image(rule[1](self.width, self.height)) + return + + def render_image(self, image: Image): + hsv_image = image.convert("HSV") + hsv_pixels = hsv_image.load() + + black_image = image.copy() + black_pixels = black_image.load() + red_image = Image.new('L', (self.width, self.height), 'white') + red_pixels = red_image.load() + + for x in range(self.width): + for y in range(self.height): + h, s, v = hsv_pixels[x,y] + red_hue_val = max(0, 255 - h*6, (h-212)*6) + red_val = int(red_hue_val * s * v / 256 / 256) + black_val = int(255 * max(0, v - red_val) / max(1, 255 - red_val)) + if red_val > 0: + red_pixels[x, y] = 255 - red_val + black_pixels[x, y] = 3*(black_val,) + + black_image = black_image.transpose(Image.Transpose.ROTATE_270) + red_image = red_image.transpose(Image.Transpose.ROTATE_270) + self.display.render(black_image, red_image) + + def set_calibrate_next_render(self, calibrate: bool = True) -> None: + self._calibrate_before_next_render = calibrate + diff --git a/src/main.py b/src/main.py deleted file mode 100644 index ff77b38..0000000 --- a/src/main.py +++ /dev/null @@ -1,18 +0,0 @@ -import logging -import sys - -from PIL import Image - -import renderer - -logger = logging.getLogger() -logger.setLevel(logging.INFO) -logger = logging.getLogger(__name__) - -image = Image.open("testtree_IXCCGR.png") -logger.info("image open") - -rend = renderer.Renderer() - -rend.render(image) - diff --git a/src/renderer.py b/src/renderer.py deleted file mode 100644 index b4274da..0000000 --- a/src/renderer.py +++ /dev/null @@ -1,51 +0,0 @@ -from PIL import Image - -import display - -from typing import List, Tuple, Callable - -class Renderer: - def __init__(self) -> None: - self.width = display.EPD_HEIGHT - self.height = display.EPD_WIDTH - self.display = display.Display() - self.rules: List[Tuple[Callable[[],bool],Callable[[int,int],Image]]] = []; - self._calibrate_before_next_render = False - - def render(self): - # check for calibration first - if self._calibrate_before_next_render: - self._calibrate_before_next_render = False - self.display.calibrate() - - for rule in self.rules: - if rule[0](): - self.render_image(rule[1](self.width, self.height)) - return - - def render_image(self, image: Image): - hsv_image = image.convert("HSV") - hsv_pixels = hsv_image.load() - - black_image = image.copy() - black_pixels = black_image.load() - red_image = Image.new('L', (self.width, self.height), 'white') - red_pixels = red_image.load() - - for x in range(self.width): - for y in range(self.height): - h, s, v = hsv_pixels[x,y] - red_hue_val = max(0, 255 - h*6, (h-212)*6) - red_val = int(red_hue_val * s * v / 256 / 256) - black_val = int(255 * max(0, v - red_val) / max(1, 255 - red_val)) - if red_val > 0: - red_pixels[x, y] = 255 - red_val - black_pixels[x, y] = 3*(black_val,) - - black_image = black_image.transpose(Image.Transpose.ROTATE_270) - red_image = red_image.transpose(Image.Transpose.ROTATE_270) - self.display.render(black_image, red_image) - - def set_calibrate_next_render(self, calibrate: bool = True) -> None: - self._calibrate_before_next_render = calibrate -