+++ /dev/null
-"""
-"""
-
-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()
-
+++ /dev/null
-# /*****************************************************************************\r
-# * | File : epd12in48.py\r
-# * | Author : Waveshare electrices\r
-# * | Function : Hardware underlying interface\r
-# * | Info :\r
-# *----------------\r
-# * | This version: V1.0\r
-# * | Date : 2019-11-01\r
-# * | Info : \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-import epdconfig\r
-\r
-EPD_WIDTH = 1304\r
-EPD_HEIGHT = 984\r
-\r
-class EPD(object):\r
- def __init__(self):\r
- self.width = EPD_WIDTH\r
- self.height = EPD_HEIGHT\r
- \r
- self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN\r
- self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN\r
- self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN\r
- self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN\r
-\r
- self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN\r
- self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN\r
-\r
- self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
- self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
-\r
- self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN\r
- self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN\r
- self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN\r
- self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN\r
-\r
- def Init(self):\r
- print("EPD init...")\r
- epdconfig.module_init()\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
- self.Reset() \r
-\r
- #panel setting\r
- self.M1_SendCommand(0x00) \r
- self.M1_SendData(0x1f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
- self.S1_SendCommand(0x00) \r
- self.S1_SendData(0x1f) \r
- self.M2_SendCommand(0x00) \r
- self.M2_SendData(0x13) \r
- self.S2_SendCommand(0x00) \r
- self.S2_SendData(0x13) \r
-\r
- # booster soft start\r
- self.M1_SendCommand(0x06) \r
- self.M1_SendData(0x17) #A\r
- self.M1_SendData(0x17) #B\r
- self.M1_SendData(0x39) #C\r
- self.M1_SendData(0x17) \r
- self.M2_SendCommand(0x06) \r
- self.M2_SendData(0x17) \r
- self.M2_SendData(0x17) \r
- self.M2_SendData(0x39) \r
- self.M2_SendData(0x17) \r
-\r
- #resolution setting\r
- self.M1_SendCommand(0x61) \r
- self.M1_SendData(0x02) \r
- self.M1_SendData(0x88) #source 648\r
- self.M1_SendData(0x01) #gate 492\r
- self.M1_SendData(0xEC) \r
- self.S1_SendCommand(0x61) \r
- self.S1_SendData(0x02) \r
- self.S1_SendData(0x90) #source 656\r
- self.S1_SendData(0x01) #gate 492\r
- self.S1_SendData(0xEC) \r
- self.M2_SendCommand(0x61) \r
- self.M2_SendData(0x02) \r
- self.M2_SendData(0x90) #source 656\r
- self.M2_SendData(0x01) #gate 492\r
- self.M2_SendData(0xEC) \r
- self.S2_SendCommand(0x61) \r
- self.S2_SendData(0x02) \r
- self.S2_SendData(0x88) #source 648\r
- self.S2_SendData(0x01) #gate 492\r
- self.S2_SendData(0xEC) \r
-\r
- self.M1S1M2S2_SendCommand(0x15) #DUSPI\r
- self.M1S1M2S2_SendData(0x20) \r
-\r
- self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting\r
- self.M1S1M2S2_SendData(0x21) #Border KW\r
- self.M1S1M2S2_SendData(0x07) \r
-\r
- self.M1S1M2S2_SendCommand(0x60) #TCON\r
- self.M1S1M2S2_SendData(0x22) \r
-\r
- self.M1S1M2S2_SendCommand(0xE3) \r
- self.M1S1M2S2_SendData(0x00) \r
-\r
- #temperature\r
- temp = self.M1_ReadTemperature() \r
-\r
- self.M1S1M2S2_SendCommand(0xe0) #Cascade setting\r
- self.M1S1M2S2_SendData(0x03) \r
- self.M1S1M2S2_SendCommand(0xe5) #Force temperature\r
- self.M1S1M2S2_SendData(temp)\r
- \r
- def display(self, Image):\r
- start = time.clock()\r
- buf = [0x00] * int(self.width * self.height / 8)\r
- image_monocolor = Image.convert('1')\r
- imwidth, imheight = image_monocolor.size \r
- pixels = image_monocolor.load()\r
- temp=0;\r
- for y in range(0, imheight):\r
- for x in range(0, imwidth):\r
- # Set the bits for the column of pixels at the current position.\r
- if pixels[x, y] < 127: # black\r
- buf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
- else: # white\r
- buf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
- temp=temp+1\r
- if(temp==8):\r
- temp=0\r
-\r
- #M1 part 648*492 \r
- self.M1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(buf[y*163 + x])\r
-\r
- #S1 part 656*492\r
- self.S1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(buf[y*163 + x])\r
-\r
- #M2 part 656*492\r
- self.M2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(buf[y*163 + x])\r
-\r
- #S2 part 648*492\r
- self.S2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(buf[y*163 + x])\r
- \r
- end = time.clock()\r
- print("use time:%f"%(end - start))\r
- self.TurnOnDisplay()\r
-\r
- def clear(self):\r
- """Clear contents of image buffer"""\r
- start = time.clock()\r
- self.M1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(0xff)\r
-\r
- self.S1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(0xff)\r
- \r
- self.M2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(0xff)\r
-\r
- self.S2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(0xff)\r
- end = time.clock()\r
- print("use time:%f"%(end - start))\r
- self.TurnOnDisplay()\r
- \r
- """ M1S1M2S2 Write register address and data """\r
- def M1S1M2S2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- def M1S1M2S2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
- """ M1M2 Write register address and data """\r
- def M1M2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- \r
- def M1S1M2S2_Senddata(self, val): \r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- \r
- """ S2 Write register address and data """\r
- def S2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
-\r
- def S2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- """ M2 Write register address and data """\r
- def M2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
- def M2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
- """ S1 Write register address and data """\r
- def S1_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-\r
- def S1_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- \r
- """ M1 Write register address and data """\r
- def M1_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
- def M1_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
- def Reset(self):\r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
- time.sleep(0.2) \r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
- time.sleep(0.01) \r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
- time.sleep(0.2) \r
- \r
- def EPD_Sleep(self):\r
- self.M1S1M2S2_SendCommand(0X02) \r
- time.sleep(0.3) \r
-\r
- self.M1S1M2S2_SendCommand(0X07) \r
- self.M1S1M2S2_SendData(0xA5) \r
- time.sleep(0.3) \r
- print("module_exit")\r
- epdconfig.module_exit()\r
- \r
- \r
- def TurnOnDisplay(self):\r
- self.M1M2_SendCommand(0x04) \r
- time.sleep(0.3) \r
- self.M1S1M2S2_SendCommand(0x12) \r
- self.M1_ReadBusy()\r
- self.S1_ReadBusy()\r
- self.M2_ReadBusy()\r
- self.S2_ReadBusy()\r
- \r
- #Busy\r
- def M1_ReadBusy(self):\r
- self.M1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- print("M1_ReadBusy")\r
- while(busy):\r
- self.M1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2)\r
- \r
- def M2_ReadBusy(self):\r
- self.M2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- print("M2_ReadBusy")\r
- while(busy):\r
- self.M2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
- busy =not(busy & 0x01) \r
- time.sleep(0.2) \r
- \r
- def S1_ReadBusy(self):\r
- self.S1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- print("s1_ReadBusy")\r
- while(busy):\r
- self.S1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2) \r
- \r
- def S2_ReadBusy(self):\r
- self.S2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- print("S2_ReadBusy")\r
- while(busy):\r
- self.S2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2) \r
- \r
- def M1_ReadTemperature(self):\r
- self.M1_SendCommand(0x40) \r
- self.M1_ReadBusy() \r
- time.sleep(0.3) \r
-\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) \r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
- \r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) \r
- time.sleep(0.01) \r
- \r
- # temp = epdconfig.spi_readbyte(0x00)\r
- temp = 25\r
- print("Read Temperature Reg:%d"%temp)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
- # temp =0x29\r
- return temp \r
+++ /dev/null
-# /*****************************************************************************\r
-# * | File : epd12in48.py\r
-# * | Author : Waveshare electrices\r
-# * | Function : Hardware underlying interface\r
-# * | Info :\r
-# *----------------\r
-# * | This version: V1.0\r
-# * | Date : 2019-11-01\r
-# * | Info : \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-from . import epdconfig\r
-\r
-EPD_WIDTH = 1304\r
-EPD_HEIGHT = 984\r
-\r
-class EPD(object):\r
- def __init__(self):\r
- self.width = EPD_WIDTH\r
- self.height = EPD_HEIGHT\r
- \r
- self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN\r
- self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN\r
- self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN\r
- self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN\r
-\r
- self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN\r
- self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN\r
-\r
- self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
- self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
-\r
- self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN\r
- self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN\r
- self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN\r
- self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN\r
-\r
- def init(self):\r
- self.Init()\r
-\r
- def Init(self):\r
- print("EPD init...")\r
- epdconfig.module_init()\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
- self.Reset() \r
-\r
- #panel setting\r
- self.M1_SendCommand(0x00) \r
- self.M1_SendData(0x2f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
- self.S1_SendCommand(0x00) \r
- self.S1_SendData(0x2f) \r
- self.M2_SendCommand(0x00) \r
- self.M2_SendData(0x23) \r
- self.S2_SendCommand(0x00) \r
- self.S2_SendData(0x23) \r
-\r
- # POWER SETTING\r
- self.M1_SendCommand(0x01)\r
- self.M1_SendData(0x07)\r
- self.M1_SendData(0x17) # VGH=20V,VGL=-20V\r
- self.M1_SendData(0x3F) # VDH=15V\r
- self.M1_SendData(0x3F) # VDL=-15V\r
- self.M1_SendData(0x0d)\r
- self.M2_SendCommand(0x01)\r
- self.M2_SendData(0x07)\r
- self.M2_SendData(0x17) # VGH=20V,VGL=-20V\r
- self.M2_SendData(0x3F) # VDH=15V\r
- self.M2_SendData(0x3F) # VDL=-15V\r
- self.M2_SendData(0x0d)\r
- \r
- # booster soft start\r
- self.M1_SendCommand(0x06)\r
- self.M1_SendData(0x17) #A\r
- self.M1_SendData(0x17) #B\r
- self.M1_SendData(0x39) #C\r
- self.M1_SendData(0x17)\r
- self.M2_SendCommand(0x06)\r
- self.M2_SendData(0x17)\r
- self.M2_SendData(0x17)\r
- self.M2_SendData(0x39)\r
- self.M2_SendData(0x17)\r
-\r
- #resolution setting\r
- self.M1_SendCommand(0x61)\r
- self.M1_SendData(0x02)\r
- self.M1_SendData(0x88) #source 648\r
- self.M1_SendData(0x01) #gate 492\r
- self.M1_SendData(0xEC)\r
- self.S1_SendCommand(0x61)\r
- self.S1_SendData(0x02)\r
- self.S1_SendData(0x90) #source 656\r
- self.S1_SendData(0x01) #gate 492\r
- self.S1_SendData(0xEC)\r
- self.M2_SendCommand(0x61)\r
- self.M2_SendData(0x02)\r
- self.M2_SendData(0x90) #source 656\r
- self.M2_SendData(0x01) #gate 492\r
- self.M2_SendData(0xEC)\r
- self.S2_SendCommand(0x61)\r
- self.S2_SendData(0x02)\r
- self.S2_SendData(0x88) #source 648\r
- self.S2_SendData(0x01) #gate 492\r
- self.S2_SendData(0xEC)\r
-\r
- self.M1S1M2S2_SendCommand(0x15) #DUSPI\r
- self.M1S1M2S2_SendData(0x20)\r
-\r
- self.M1S1M2S2_SendCommand(0x30) # PLL\r
- self.M1S1M2S2_SendData(0x08)\r
-\r
- self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting\r
- self.M1S1M2S2_SendData(0x31)\r
- self.M1S1M2S2_SendData(0x07)\r
-\r
- self.M1S1M2S2_SendCommand(0x60)#TCON\r
- self.M1S1M2S2_SendData(0x22)\r
-\r
- self.M1_SendCommand(0xE0) #POWER SETTING\r
- self.M1_SendData(0x01)\r
- self.M2_SendCommand(0xE0) #POWER SETTING\r
- self.M2_SendData(0x01)\r
-\r
- self.M1S1M2S2_SendCommand(0xE3)\r
- self.M1S1M2S2_SendData(0x00)\r
-\r
- self.M1_SendCommand(0x82)\r
- self.M1_SendData(0x1c)\r
- self.M2_SendCommand(0x82)\r
- self.M2_SendData(0x1c)\r
-\r
- self.SetLut()\r
- \r
- def display(self, BlackImage, RedImage):\r
- Blackbuf = [0x00] * int(self.width * self.height / 8)\r
- blackconvert = BlackImage.convert('1') \r
- bimwidth, bimheight = blackconvert.size \r
- Blackpixles = blackconvert.load()\r
- temp=0;\r
- for y in range(0, bimheight):\r
- for x in range(0, bimwidth):\r
- if Blackpixles[x, y] < 127: # black\r
- Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
- else: # white\r
- Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
- temp=temp+1\r
- if(temp==8):\r
- temp=0\r
- \r
- Redbuf = [0x00] * int(self.width * self.height / 8)\r
- redconvert = RedImage.convert('1')\r
- rimwidth, rimheight = redconvert.size \r
- Redpixles = redconvert.load()\r
- temp=0;\r
- for y in range(0, rimheight):\r
- for x in range(0, rimwidth):\r
- if Redpixles[x, y] < 127: # black\r
- Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
- else: # white\r
- Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
- temp=temp+1\r
- if(temp==8):\r
- temp=0\r
- \r
- #S2 part 648*492\r
- self.S2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(Blackbuf[y*163 + x])\r
- self.S2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(~Redbuf[y*163 + x])\r
- \r
- #M2 part 656*492\r
- self.M2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(Blackbuf[y*163 + x])\r
- self.M2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(~Redbuf[y*163 + x])\r
-\r
- #M1 part 648*492 \r
- self.M1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(Blackbuf[y*163 + x])\r
- self.M1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(~Redbuf[y*163 + x])\r
- \r
- #S1 part 656*492\r
- self.S1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(Blackbuf[y*163 + x])\r
- self.S1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(~Redbuf[y*163 + x])\r
- \r
- self.TurnOnDisplay()\r
-\r
- def clear(self):\r
- """Clear contents of image buffer"""\r
- self.S2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(0xff) \r
- self.S2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(0x00)\r
- \r
- self.M2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(0xff)\r
- self.M2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(0x00) \r
- \r
- self.M1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(0xff)\r
- self.M1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(0x00)\r
- \r
- self.S1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(0xff)\r
- self.S1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(0x00)\r
- \r
- self.TurnOnDisplay()\r
- \r
- def Reset(self):\r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
- time.sleep(0.2) \r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
- time.sleep(0.01) \r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
- time.sleep(0.2) \r
-\r
- def sleep(self):\r
- self.EPD_Sleep()\r
- \r
- def EPD_Sleep(self):\r
- self.M1S1M2S2_SendCommand(0X02) \r
- time.sleep(0.3) \r
-\r
- self.M1S1M2S2_SendCommand(0X07) \r
- self.M1S1M2S2_SendData(0xA5) \r
- time.sleep(0.3) \r
- print("module_exit")\r
- epdconfig.module_exit()\r
-\r
- def TurnOnDisplay(self):\r
- self.M1M2_SendCommand(0x04) \r
- time.sleep(0.3) \r
- self.M1S1M2S2_SendCommand(0x12) \r
- self.M1_ReadBusy()\r
- self.S1_ReadBusy()\r
- self.M2_ReadBusy()\r
- self.S2_ReadBusy() \r
- \r
- """ M1S1M2S2 Write register address and data """\r
- def M1S1M2S2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- def M1S1M2S2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
- """ M1M2 Write register address and data """\r
- def M1M2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- \r
- def M1M2_Sendata(self, val): \r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- \r
- """ S2 Write register address and data """\r
- def S2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- def S2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- """ M2 Write register address and data """\r
- def M2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- def M2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
- """ S1 Write register address and data """\r
- def S1_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- def S1_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- \r
- """ M1 Write register address and data """\r
- def M1_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- def M1_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
- #Busy\r
- def M1_ReadBusy(self):\r
- self.M1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- while(busy):\r
- self.M1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2)\r
- def M2_ReadBusy(self):\r
- self.M2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- self.M2_SendCommand(0x71) \r
- while(busy):\r
- self.M2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
- busy =not(busy & 0x01) \r
- time.sleep(0.2)\r
- def S1_ReadBusy(self):\r
- self.S1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- while(busy):\r
- self.S1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2) \r
- def S2_ReadBusy(self):\r
- self.S2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- while(busy):\r
- self.S2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2) \r
-\r
- lut_vcom1 = [\r
- 0x00, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x00, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_ww1 = [\r
- 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_bw1 = [\r
- 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x84, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x86, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_wb1 = [\r
- 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_bb1 = [\r
- 0x92, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x01, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- \r
- def SetLut(self):\r
- self.M1S1M2S2_SendCommand(0x20) #vcom\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
-\r
- self.M1S1M2S2_SendCommand(0x21) #red not use\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_ww1[count])\r
-\r
- self.M1S1M2S2_SendCommand(0x22) #bw r\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r\r
-\r
- self.M1S1M2S2_SendCommand(0x23) #wb w\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w\r
-\r
- self.M1S1M2S2_SendCommand(0x24) #bb b\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b\r
- \r
- self.M1S1M2S2_SendCommand(0x25) #bb b\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b\r
+++ /dev/null
-# /*****************************************************************************\r
-# * | File : epd12in48b_V2.py\r
-# * | Author : Waveshare electrices\r
-# * | Function : Hardware underlying interface\r
-# * | Info :\r
-# *----------------\r
-# * | This version: V1.0\r
-# * | Date : 2022-09-14\r
-# * | Info : \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-import epdconfig\r
-\r
-EPD_WIDTH = 1304\r
-EPD_HEIGHT = 984\r
-\r
-class EPD(object):\r
- def __init__(self):\r
- self.width = EPD_WIDTH\r
- self.height = EPD_HEIGHT\r
- \r
- self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN\r
- self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN\r
- self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN\r
- self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN\r
-\r
- self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN\r
- self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN\r
-\r
- self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
- self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
-\r
- self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN\r
- self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN\r
- self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN\r
- self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN\r
-\r
- def Init(self):\r
- print("EPD init...")\r
- epdconfig.module_init()\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
- self.Reset() \r
-\r
- # panel setting for Clear\r
- # self.M1_SendCommand(0x00)\r
- # self.M1_SendData(0x07) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
- # self.S1_SendCommand(0x00)\r
- # self.S1_SendData(0x07)\r
- # self.M2_SendCommand(0x00)\r
- # self.M2_SendData(0x07)\r
- # self.S2_SendCommand(0x00)\r
- # self.S2_SendData(0x07)\r
-\r
- # panel setting for Display\r
- self.M1_SendCommand(0x00)\r
- self.M1_SendData(0x0f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
- self.S1_SendCommand(0x00)\r
- self.S1_SendData(0x0f)\r
- self.M2_SendCommand(0x00)\r
- self.M2_SendData(0x03)\r
- self.S2_SendCommand(0x00)\r
- self.S2_SendData(0x03)\r
-\r
- # booster soft start\r
- self.M1_SendCommand(0x06)\r
- self.M1_SendData(0x17) #A\r
- self.M1_SendData(0x17) #B\r
- self.M1_SendData(0x39) #C\r
- self.M1_SendData(0x17)\r
- self.M2_SendCommand(0x06)\r
- self.M2_SendData(0x17)\r
- self.M2_SendData(0x17)\r
- self.M2_SendData(0x39)\r
- self.M2_SendData(0x17)\r
-\r
- #resolution setting\r
- self.M1_SendCommand(0x61)\r
- self.M1_SendData(0x02)\r
- self.M1_SendData(0x88) #source 648\r
- self.M1_SendData(0x01) #gate 492\r
- self.M1_SendData(0xEC)\r
- self.S1_SendCommand(0x61)\r
- self.S1_SendData(0x02)\r
- self.S1_SendData(0x90) #source 656\r
- self.S1_SendData(0x01) #gate 492\r
- self.S1_SendData(0xEC)\r
- self.M2_SendCommand(0x61)\r
- self.M2_SendData(0x02)\r
- self.M2_SendData(0x90) #source 656\r
- self.M2_SendData(0x01) #gate 492\r
- self.M2_SendData(0xEC)\r
- self.S2_SendCommand(0x61)\r
- self.S2_SendData(0x02)\r
- self.S2_SendData(0x88) #source 648\r
- self.S2_SendData(0x01) #gate 492\r
- self.S2_SendData(0xEC)\r
-\r
- self.M1S1M2S2_SendCommand(0x15) #DUSPI\r
- self.M1S1M2S2_SendData(0x20)\r
-\r
- self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting\r
- self.M1S1M2S2_SendData(0x11)\r
- self.M1S1M2S2_SendData(0x07)\r
-\r
- self.M1S1M2S2_SendCommand(0x60)#TCON\r
- self.M1S1M2S2_SendData(0x22)\r
-\r
- self.M1S1M2S2_SendCommand(0xE3)\r
- self.M1S1M2S2_SendData(0x00)\r
-\r
- self.M1_ReadTemperature()\r
- \r
- def display(self, BlackImage, RedImage):\r
- start = time.perf_counter()\r
- \r
- Blackbuf = [0x00] * int(self.width * self.height / 8)\r
- blackconvert = BlackImage.convert('1') \r
- bimwidth, bimheight = blackconvert.size \r
- Blackpixles = blackconvert.load()\r
- temp=0\r
- for y in range(0, bimheight):\r
- for x in range(0, bimwidth):\r
- if Blackpixles[x, y] < 127: # black\r
- Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
- else: # white\r
- Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
- temp=temp+1\r
- if(temp==8):\r
- temp=0\r
- \r
- Redbuf = [0x00] * int(self.width * self.height / 8)\r
- redconvert = RedImage.convert('1')\r
- rimwidth, rimheight = redconvert.size \r
- Redpixles = redconvert.load()\r
- temp=0\r
- for y in range(0, rimheight):\r
- for x in range(0, rimwidth):\r
- if Redpixles[x, y] < 127: # black\r
- Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
- else: # white\r
- Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
- temp=temp+1\r
- if(temp==8):\r
- temp=0\r
- \r
- #S2 part 648*492\r
- self.S2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(Blackbuf[y*163 + x])\r
- self.S2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(~Redbuf[y*163 + x])\r
- \r
- #M2 part 656*492\r
- self.M2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(Blackbuf[y*163 + x])\r
- self.M2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(~Redbuf[y*163 + x])\r
-\r
- #M1 part 648*492 \r
- self.M1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(Blackbuf[y*163 + x])\r
- self.M1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(~Redbuf[y*163 + x])\r
- \r
- #S1 part 656*492\r
- self.S1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(Blackbuf[y*163 + x])\r
- self.S1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(~Redbuf[y*163 + x])\r
- \r
- end = time.perf_counter()\r
- print("use time: %f"%(end - start))\r
- self.TurnOnDisplay()\r
-\r
- def clear(self):\r
- """Clear contents of image buffer"""\r
- start = time.perf_counter()\r
- \r
- self.S2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(0xff) \r
- self.S2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(0, 81):\r
- self.S2_SendData(0x00)\r
- \r
- self.M2_SendCommand(0x10)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(0xff)\r
- self.M2_SendCommand(0x13)\r
- for y in range(0, 492):\r
- for x in range(81, 163):\r
- self.M2_SendData(0x00) \r
- \r
- self.M1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(0xff)\r
- self.M1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(0, 81):\r
- self.M1_SendData(0x00)\r
- \r
- self.S1_SendCommand(0x10)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(0xff)\r
- self.S1_SendCommand(0x13)\r
- for y in range(492, 984):\r
- for x in range(81, 163):\r
- self.S1_SendData(0x00)\r
- \r
- end = time.perf_counter()\r
- print (end)\r
- print (start)\r
- print("use time: %f" %(end - start))\r
- \r
- self.TurnOnDisplay()\r
- \r
- def Reset(self):\r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
- time.sleep(0.2) \r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
- time.sleep(0.01) \r
- epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
- epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
- time.sleep(0.2) \r
- \r
- def EPD_Sleep(self):\r
- self.M1S1M2S2_SendCommand(0X02) \r
- time.sleep(0.3) \r
-\r
- self.M1S1M2S2_SendCommand(0X07) \r
- self.M1S1M2S2_SendData(0xA5) \r
- time.sleep(0.3) \r
- print("module_exit")\r
- epdconfig.module_exit()\r
-\r
- def TurnOnDisplay(self):\r
- self.M1M2_SendCommand(0x04) \r
- time.sleep(0.3) \r
- self.M1S1M2S2_SendCommand(0x12) \r
- self.M1_ReadBusy()\r
- self.S1_ReadBusy()\r
- self.M2_ReadBusy()\r
- self.S2_ReadBusy() \r
- \r
- """ M1S1M2S2 Write register address and data """\r
- def M1S1M2S2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- def M1S1M2S2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
- """ M1M2 Write register address and data """\r
- def M1M2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- \r
- def M1M2_Sendata(self, val): \r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
- \r
- """ S2 Write register address and data """\r
- def S2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- def S2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- """ M2 Write register address and data """\r
- def M2_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- def M2_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val) \r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
- """ S1 Write register address and data """\r
- def S1_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- def S1_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- \r
- """ M1 Write register address and data """\r
- def M1_SendCommand(self, cmd):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(cmd)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- def M1_SendData(self, val):\r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.spi_writebyte(val)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
- #Busy\r
- def M1_ReadBusy(self):\r
- self.M1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- while(busy):\r
- self.M1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2)\r
- def M2_ReadBusy(self):\r
- self.M2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- self.M2_SendCommand(0x71) \r
- while(busy):\r
- self.M2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
- busy =not(busy & 0x01) \r
- time.sleep(0.2)\r
- def S1_ReadBusy(self):\r
- self.S1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- while(busy):\r
- self.S1_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2) \r
- def S2_ReadBusy(self):\r
- self.S2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- while(busy):\r
- self.S2_SendCommand(0x71) \r
- busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
- busy = not(busy & 0x01) \r
- time.sleep(0.2) \r
-\r
- lut_vcom1 = [\r
- 0x00, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x00, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_ww1 = [\r
- 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_bw1 = [\r
- 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x84, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x86, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_wb1 = [\r
- 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- lut_bb1 = [\r
- 0x92, 0x10, 0x10, 0x01, 0x08, 0x01,\r
- 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
- 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
- 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
- 0x01, 0x04, 0x05, 0x08, 0x08, 0x01,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- ]\r
- \r
- def SetLut(self):\r
- self.M1S1M2S2_SendCommand(0x20) #vcom\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
-\r
- self.M1S1M2S2_SendCommand(0x21) #red not use\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_ww1[count])\r
-\r
- self.M1S1M2S2_SendCommand(0x22) #bw r\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r\r
-\r
- self.M1S1M2S2_SendCommand(0x23) #wb w\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w\r
-\r
- self.M1S1M2S2_SendCommand(0x24) #bb b\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b\r
- \r
- self.M1S1M2S2_SendCommand(0x25) #bb b\r
- for count in range(0, 60):\r
- self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b\r
-\r
- def M1_ReadTemperature(self):\r
- self.M1_SendCommand(0x40)\r
- self.M1_ReadBusy()\r
- time.sleep(0.3)\r
- \r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
- epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
- epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
- \r
- epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
- time.sleep(0.05)\r
- \r
- temp = epdconfig.spi_readbyte(0x00)\r
- epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
- \r
- self.M1S1M2S2_SendCommand(0xE0)\r
- self.M1S1M2S2_SendData(0x03)\r
- self.M1S1M2S2_SendCommand(0xE5)\r
- self.M1S1M2S2_SendData(temp)\r
+++ /dev/null
-# /*****************************************************************************\r
-# * | File : epdconfig.py\r
-# * | Author : Waveshare electrices\r
-# * | Function : Hardware underlying interface\r
-# * | Info :\r
-# *----------------\r
-# * | This version: V1.0\r
-# * | Date : 2019-11-01\r
-# * | Info : \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-import os\r
-import logging\r
-import sys\r
-\r
-from ctypes import *\r
-\r
-EPD_SCK_PIN =11\r
-EPD_MOSI_PIN =10\r
-\r
-EPD_M1_CS_PIN =8\r
-EPD_S1_CS_PIN =7\r
-EPD_M2_CS_PIN =17\r
-EPD_S2_CS_PIN =18\r
-\r
-EPD_M1S1_DC_PIN =13\r
-EPD_M2S2_DC_PIN =22\r
-\r
-EPD_M1S1_RST_PIN =6\r
-EPD_M2S2_RST_PIN =23\r
-\r
-EPD_M1_BUSY_PIN =5\r
-EPD_S1_BUSY_PIN =19\r
-EPD_M2_BUSY_PIN =27\r
-EPD_S2_BUSY_PIN =24\r
-\r
-find_dirs = [\r
- os.path.dirname(os.path.realpath(__file__)),\r
- '/usr/local/lib',\r
- '/usr/lib',\r
-]\r
-spi = None\r
-for find_dir in find_dirs:\r
- val = int(os.popen('getconf LONG_BIT').read())\r
- logging.debug("System is %d bit"%val)\r
- if val == 64:\r
- so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_64bit.so')\r
- else:\r
- so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_32bit.so')\r
- if os.path.exists(so_filename):\r
- spi = CDLL(so_filename)\r
- break\r
-if spi is None:\r
- RuntimeError('Cannot find DEV_Config.so')\r
-\r
-def digital_write(pin, value):\r
- spi.DEV_Digital_Write(pin, value)\r
-\r
-def digital_read(pin):\r
- return spi.DEV_Digital_Read(pin)\r
-\r
-def spi_writebyte(value): \r
- spi.DEV_SPI_WriteByte(value)\r
- \r
-def delay_ms(delaytime):\r
- time.sleep(delaytime / 1000.0)\r
- \r
-def module_init():\r
- spi.DEV_ModuleInit()\r
-\r
-def module_exit():\r
- spi.DEV_ModuleExit()\r
-\r
-\r
-def spi_readbyte(Reg):\r
- return spi.DEV_SPI_ReadByte(Reg)\r
- \r
-def delay_ms(delaytime):\r
- time.sleep(delaytime / 1000.0)\r
-\r
- \r
--- /dev/null
+"""
+"""
+
+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()
+
--- /dev/null
+# /*****************************************************************************\r
+# * | File : epd12in48.py\r
+# * | Author : Waveshare electrices\r
+# * | Function : Hardware underlying interface\r
+# * | Info :\r
+# *----------------\r
+# * | This version: V1.0\r
+# * | Date : 2019-11-01\r
+# * | Info : \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+import epdconfig\r
+\r
+EPD_WIDTH = 1304\r
+EPD_HEIGHT = 984\r
+\r
+class EPD(object):\r
+ def __init__(self):\r
+ self.width = EPD_WIDTH\r
+ self.height = EPD_HEIGHT\r
+ \r
+ self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN\r
+ self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN\r
+ self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN\r
+ self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN\r
+\r
+ self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN\r
+ self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN\r
+\r
+ self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
+ self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
+\r
+ self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN\r
+ self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN\r
+ self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN\r
+ self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN\r
+\r
+ def Init(self):\r
+ print("EPD init...")\r
+ epdconfig.module_init()\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+ self.Reset() \r
+\r
+ #panel setting\r
+ self.M1_SendCommand(0x00) \r
+ self.M1_SendData(0x1f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
+ self.S1_SendCommand(0x00) \r
+ self.S1_SendData(0x1f) \r
+ self.M2_SendCommand(0x00) \r
+ self.M2_SendData(0x13) \r
+ self.S2_SendCommand(0x00) \r
+ self.S2_SendData(0x13) \r
+\r
+ # booster soft start\r
+ self.M1_SendCommand(0x06) \r
+ self.M1_SendData(0x17) #A\r
+ self.M1_SendData(0x17) #B\r
+ self.M1_SendData(0x39) #C\r
+ self.M1_SendData(0x17) \r
+ self.M2_SendCommand(0x06) \r
+ self.M2_SendData(0x17) \r
+ self.M2_SendData(0x17) \r
+ self.M2_SendData(0x39) \r
+ self.M2_SendData(0x17) \r
+\r
+ #resolution setting\r
+ self.M1_SendCommand(0x61) \r
+ self.M1_SendData(0x02) \r
+ self.M1_SendData(0x88) #source 648\r
+ self.M1_SendData(0x01) #gate 492\r
+ self.M1_SendData(0xEC) \r
+ self.S1_SendCommand(0x61) \r
+ self.S1_SendData(0x02) \r
+ self.S1_SendData(0x90) #source 656\r
+ self.S1_SendData(0x01) #gate 492\r
+ self.S1_SendData(0xEC) \r
+ self.M2_SendCommand(0x61) \r
+ self.M2_SendData(0x02) \r
+ self.M2_SendData(0x90) #source 656\r
+ self.M2_SendData(0x01) #gate 492\r
+ self.M2_SendData(0xEC) \r
+ self.S2_SendCommand(0x61) \r
+ self.S2_SendData(0x02) \r
+ self.S2_SendData(0x88) #source 648\r
+ self.S2_SendData(0x01) #gate 492\r
+ self.S2_SendData(0xEC) \r
+\r
+ self.M1S1M2S2_SendCommand(0x15) #DUSPI\r
+ self.M1S1M2S2_SendData(0x20) \r
+\r
+ self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting\r
+ self.M1S1M2S2_SendData(0x21) #Border KW\r
+ self.M1S1M2S2_SendData(0x07) \r
+\r
+ self.M1S1M2S2_SendCommand(0x60) #TCON\r
+ self.M1S1M2S2_SendData(0x22) \r
+\r
+ self.M1S1M2S2_SendCommand(0xE3) \r
+ self.M1S1M2S2_SendData(0x00) \r
+\r
+ #temperature\r
+ temp = self.M1_ReadTemperature() \r
+\r
+ self.M1S1M2S2_SendCommand(0xe0) #Cascade setting\r
+ self.M1S1M2S2_SendData(0x03) \r
+ self.M1S1M2S2_SendCommand(0xe5) #Force temperature\r
+ self.M1S1M2S2_SendData(temp)\r
+ \r
+ def display(self, Image):\r
+ start = time.clock()\r
+ buf = [0x00] * int(self.width * self.height / 8)\r
+ image_monocolor = Image.convert('1')\r
+ imwidth, imheight = image_monocolor.size \r
+ pixels = image_monocolor.load()\r
+ temp=0;\r
+ for y in range(0, imheight):\r
+ for x in range(0, imwidth):\r
+ # Set the bits for the column of pixels at the current position.\r
+ if pixels[x, y] < 127: # black\r
+ buf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+ else: # white\r
+ buf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+ temp=temp+1\r
+ if(temp==8):\r
+ temp=0\r
+\r
+ #M1 part 648*492 \r
+ self.M1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(buf[y*163 + x])\r
+\r
+ #S1 part 656*492\r
+ self.S1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(buf[y*163 + x])\r
+\r
+ #M2 part 656*492\r
+ self.M2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(buf[y*163 + x])\r
+\r
+ #S2 part 648*492\r
+ self.S2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(buf[y*163 + x])\r
+ \r
+ end = time.clock()\r
+ print("use time:%f"%(end - start))\r
+ self.TurnOnDisplay()\r
+\r
+ def clear(self):\r
+ """Clear contents of image buffer"""\r
+ start = time.clock()\r
+ self.M1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(0xff)\r
+\r
+ self.S1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(0xff)\r
+ \r
+ self.M2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(0xff)\r
+\r
+ self.S2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(0xff)\r
+ end = time.clock()\r
+ print("use time:%f"%(end - start))\r
+ self.TurnOnDisplay()\r
+ \r
+ """ M1S1M2S2 Write register address and data """\r
+ def M1S1M2S2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ def M1S1M2S2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+ """ M1M2 Write register address and data """\r
+ def M1M2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ \r
+ def M1S1M2S2_Senddata(self, val): \r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ \r
+ """ S2 Write register address and data """\r
+ def S2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+\r
+ def S2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ """ M2 Write register address and data """\r
+ def M2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+ def M2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+ """ S1 Write register address and data """\r
+ def S1_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+\r
+ def S1_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ \r
+ """ M1 Write register address and data """\r
+ def M1_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+ def M1_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+ def Reset(self):\r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+ time.sleep(0.2) \r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
+ time.sleep(0.01) \r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+ time.sleep(0.2) \r
+ \r
+ def EPD_Sleep(self):\r
+ self.M1S1M2S2_SendCommand(0X02) \r
+ time.sleep(0.3) \r
+\r
+ self.M1S1M2S2_SendCommand(0X07) \r
+ self.M1S1M2S2_SendData(0xA5) \r
+ time.sleep(0.3) \r
+ print("module_exit")\r
+ epdconfig.module_exit()\r
+ \r
+ \r
+ def TurnOnDisplay(self):\r
+ self.M1M2_SendCommand(0x04) \r
+ time.sleep(0.3) \r
+ self.M1S1M2S2_SendCommand(0x12) \r
+ self.M1_ReadBusy()\r
+ self.S1_ReadBusy()\r
+ self.M2_ReadBusy()\r
+ self.S2_ReadBusy()\r
+ \r
+ #Busy\r
+ def M1_ReadBusy(self):\r
+ self.M1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ print("M1_ReadBusy")\r
+ while(busy):\r
+ self.M1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2)\r
+ \r
+ def M2_ReadBusy(self):\r
+ self.M2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ print("M2_ReadBusy")\r
+ while(busy):\r
+ self.M2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+ busy =not(busy & 0x01) \r
+ time.sleep(0.2) \r
+ \r
+ def S1_ReadBusy(self):\r
+ self.S1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ print("s1_ReadBusy")\r
+ while(busy):\r
+ self.S1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2) \r
+ \r
+ def S2_ReadBusy(self):\r
+ self.S2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ print("S2_ReadBusy")\r
+ while(busy):\r
+ self.S2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2) \r
+ \r
+ def M1_ReadTemperature(self):\r
+ self.M1_SendCommand(0x40) \r
+ self.M1_ReadBusy() \r
+ time.sleep(0.3) \r
+\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) \r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+ \r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) \r
+ time.sleep(0.01) \r
+ \r
+ # temp = epdconfig.spi_readbyte(0x00)\r
+ temp = 25\r
+ print("Read Temperature Reg:%d"%temp)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+ # temp =0x29\r
+ return temp \r
--- /dev/null
+# /*****************************************************************************\r
+# * | File : epd12in48.py\r
+# * | Author : Waveshare electrices\r
+# * | Function : Hardware underlying interface\r
+# * | Info :\r
+# *----------------\r
+# * | This version: V1.0\r
+# * | Date : 2019-11-01\r
+# * | Info : \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+from . import epdconfig\r
+\r
+EPD_WIDTH = 1304\r
+EPD_HEIGHT = 984\r
+\r
+class EPD(object):\r
+ def __init__(self):\r
+ self.width = EPD_WIDTH\r
+ self.height = EPD_HEIGHT\r
+ \r
+ self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN\r
+ self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN\r
+ self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN\r
+ self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN\r
+\r
+ self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN\r
+ self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN\r
+\r
+ self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
+ self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
+\r
+ self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN\r
+ self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN\r
+ self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN\r
+ self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN\r
+\r
+ def init(self):\r
+ self.Init()\r
+\r
+ def Init(self):\r
+ print("EPD init...")\r
+ epdconfig.module_init()\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+ self.Reset() \r
+\r
+ #panel setting\r
+ self.M1_SendCommand(0x00) \r
+ self.M1_SendData(0x2f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
+ self.S1_SendCommand(0x00) \r
+ self.S1_SendData(0x2f) \r
+ self.M2_SendCommand(0x00) \r
+ self.M2_SendData(0x23) \r
+ self.S2_SendCommand(0x00) \r
+ self.S2_SendData(0x23) \r
+\r
+ # POWER SETTING\r
+ self.M1_SendCommand(0x01)\r
+ self.M1_SendData(0x07)\r
+ self.M1_SendData(0x17) # VGH=20V,VGL=-20V\r
+ self.M1_SendData(0x3F) # VDH=15V\r
+ self.M1_SendData(0x3F) # VDL=-15V\r
+ self.M1_SendData(0x0d)\r
+ self.M2_SendCommand(0x01)\r
+ self.M2_SendData(0x07)\r
+ self.M2_SendData(0x17) # VGH=20V,VGL=-20V\r
+ self.M2_SendData(0x3F) # VDH=15V\r
+ self.M2_SendData(0x3F) # VDL=-15V\r
+ self.M2_SendData(0x0d)\r
+ \r
+ # booster soft start\r
+ self.M1_SendCommand(0x06)\r
+ self.M1_SendData(0x17) #A\r
+ self.M1_SendData(0x17) #B\r
+ self.M1_SendData(0x39) #C\r
+ self.M1_SendData(0x17)\r
+ self.M2_SendCommand(0x06)\r
+ self.M2_SendData(0x17)\r
+ self.M2_SendData(0x17)\r
+ self.M2_SendData(0x39)\r
+ self.M2_SendData(0x17)\r
+\r
+ #resolution setting\r
+ self.M1_SendCommand(0x61)\r
+ self.M1_SendData(0x02)\r
+ self.M1_SendData(0x88) #source 648\r
+ self.M1_SendData(0x01) #gate 492\r
+ self.M1_SendData(0xEC)\r
+ self.S1_SendCommand(0x61)\r
+ self.S1_SendData(0x02)\r
+ self.S1_SendData(0x90) #source 656\r
+ self.S1_SendData(0x01) #gate 492\r
+ self.S1_SendData(0xEC)\r
+ self.M2_SendCommand(0x61)\r
+ self.M2_SendData(0x02)\r
+ self.M2_SendData(0x90) #source 656\r
+ self.M2_SendData(0x01) #gate 492\r
+ self.M2_SendData(0xEC)\r
+ self.S2_SendCommand(0x61)\r
+ self.S2_SendData(0x02)\r
+ self.S2_SendData(0x88) #source 648\r
+ self.S2_SendData(0x01) #gate 492\r
+ self.S2_SendData(0xEC)\r
+\r
+ self.M1S1M2S2_SendCommand(0x15) #DUSPI\r
+ self.M1S1M2S2_SendData(0x20)\r
+\r
+ self.M1S1M2S2_SendCommand(0x30) # PLL\r
+ self.M1S1M2S2_SendData(0x08)\r
+\r
+ self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting\r
+ self.M1S1M2S2_SendData(0x31)\r
+ self.M1S1M2S2_SendData(0x07)\r
+\r
+ self.M1S1M2S2_SendCommand(0x60)#TCON\r
+ self.M1S1M2S2_SendData(0x22)\r
+\r
+ self.M1_SendCommand(0xE0) #POWER SETTING\r
+ self.M1_SendData(0x01)\r
+ self.M2_SendCommand(0xE0) #POWER SETTING\r
+ self.M2_SendData(0x01)\r
+\r
+ self.M1S1M2S2_SendCommand(0xE3)\r
+ self.M1S1M2S2_SendData(0x00)\r
+\r
+ self.M1_SendCommand(0x82)\r
+ self.M1_SendData(0x1c)\r
+ self.M2_SendCommand(0x82)\r
+ self.M2_SendData(0x1c)\r
+\r
+ self.SetLut()\r
+ \r
+ def display(self, BlackImage, RedImage):\r
+ Blackbuf = [0x00] * int(self.width * self.height / 8)\r
+ blackconvert = BlackImage.convert('1') \r
+ bimwidth, bimheight = blackconvert.size \r
+ Blackpixles = blackconvert.load()\r
+ temp=0;\r
+ for y in range(0, bimheight):\r
+ for x in range(0, bimwidth):\r
+ if Blackpixles[x, y] < 127: # black\r
+ Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+ else: # white\r
+ Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+ temp=temp+1\r
+ if(temp==8):\r
+ temp=0\r
+ \r
+ Redbuf = [0x00] * int(self.width * self.height / 8)\r
+ redconvert = RedImage.convert('1')\r
+ rimwidth, rimheight = redconvert.size \r
+ Redpixles = redconvert.load()\r
+ temp=0;\r
+ for y in range(0, rimheight):\r
+ for x in range(0, rimwidth):\r
+ if Redpixles[x, y] < 127: # black\r
+ Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+ else: # white\r
+ Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+ temp=temp+1\r
+ if(temp==8):\r
+ temp=0\r
+ \r
+ #S2 part 648*492\r
+ self.S2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(Blackbuf[y*163 + x])\r
+ self.S2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(~Redbuf[y*163 + x])\r
+ \r
+ #M2 part 656*492\r
+ self.M2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(Blackbuf[y*163 + x])\r
+ self.M2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(~Redbuf[y*163 + x])\r
+\r
+ #M1 part 648*492 \r
+ self.M1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(Blackbuf[y*163 + x])\r
+ self.M1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(~Redbuf[y*163 + x])\r
+ \r
+ #S1 part 656*492\r
+ self.S1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(Blackbuf[y*163 + x])\r
+ self.S1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(~Redbuf[y*163 + x])\r
+ \r
+ self.TurnOnDisplay()\r
+\r
+ def clear(self):\r
+ """Clear contents of image buffer"""\r
+ self.S2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(0xff) \r
+ self.S2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(0x00)\r
+ \r
+ self.M2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(0xff)\r
+ self.M2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(0x00) \r
+ \r
+ self.M1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(0xff)\r
+ self.M1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(0x00)\r
+ \r
+ self.S1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(0xff)\r
+ self.S1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(0x00)\r
+ \r
+ self.TurnOnDisplay()\r
+ \r
+ def Reset(self):\r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+ time.sleep(0.2) \r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
+ time.sleep(0.01) \r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+ time.sleep(0.2) \r
+\r
+ def sleep(self):\r
+ self.EPD_Sleep()\r
+ \r
+ def EPD_Sleep(self):\r
+ self.M1S1M2S2_SendCommand(0X02) \r
+ time.sleep(0.3) \r
+\r
+ self.M1S1M2S2_SendCommand(0X07) \r
+ self.M1S1M2S2_SendData(0xA5) \r
+ time.sleep(0.3) \r
+ print("module_exit")\r
+ epdconfig.module_exit()\r
+\r
+ def TurnOnDisplay(self):\r
+ self.M1M2_SendCommand(0x04) \r
+ time.sleep(0.3) \r
+ self.M1S1M2S2_SendCommand(0x12) \r
+ self.M1_ReadBusy()\r
+ self.S1_ReadBusy()\r
+ self.M2_ReadBusy()\r
+ self.S2_ReadBusy() \r
+ \r
+ """ M1S1M2S2 Write register address and data """\r
+ def M1S1M2S2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ def M1S1M2S2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+ """ M1M2 Write register address and data """\r
+ def M1M2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ \r
+ def M1M2_Sendata(self, val): \r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ \r
+ """ S2 Write register address and data """\r
+ def S2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ def S2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ """ M2 Write register address and data """\r
+ def M2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ def M2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+ """ S1 Write register address and data """\r
+ def S1_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ def S1_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ \r
+ """ M1 Write register address and data """\r
+ def M1_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ def M1_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+ #Busy\r
+ def M1_ReadBusy(self):\r
+ self.M1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ while(busy):\r
+ self.M1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2)\r
+ def M2_ReadBusy(self):\r
+ self.M2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ self.M2_SendCommand(0x71) \r
+ while(busy):\r
+ self.M2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+ busy =not(busy & 0x01) \r
+ time.sleep(0.2)\r
+ def S1_ReadBusy(self):\r
+ self.S1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ while(busy):\r
+ self.S1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2) \r
+ def S2_ReadBusy(self):\r
+ self.S2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ while(busy):\r
+ self.S2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2) \r
+\r
+ lut_vcom1 = [\r
+ 0x00, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x00, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_ww1 = [\r
+ 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_bw1 = [\r
+ 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x84, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x86, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_wb1 = [\r
+ 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_bb1 = [\r
+ 0x92, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x01, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ \r
+ def SetLut(self):\r
+ self.M1S1M2S2_SendCommand(0x20) #vcom\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
+\r
+ self.M1S1M2S2_SendCommand(0x21) #red not use\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_ww1[count])\r
+\r
+ self.M1S1M2S2_SendCommand(0x22) #bw r\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r\r
+\r
+ self.M1S1M2S2_SendCommand(0x23) #wb w\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w\r
+\r
+ self.M1S1M2S2_SendCommand(0x24) #bb b\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b\r
+ \r
+ self.M1S1M2S2_SendCommand(0x25) #bb b\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b\r
--- /dev/null
+# /*****************************************************************************\r
+# * | File : epd12in48b_V2.py\r
+# * | Author : Waveshare electrices\r
+# * | Function : Hardware underlying interface\r
+# * | Info :\r
+# *----------------\r
+# * | This version: V1.0\r
+# * | Date : 2022-09-14\r
+# * | Info : \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+import epdconfig\r
+\r
+EPD_WIDTH = 1304\r
+EPD_HEIGHT = 984\r
+\r
+class EPD(object):\r
+ def __init__(self):\r
+ self.width = EPD_WIDTH\r
+ self.height = EPD_HEIGHT\r
+ \r
+ self.EPD_M1_CS_PIN = epdconfig.EPD_M1_CS_PIN\r
+ self.EPD_S1_CS_PIN = epdconfig.EPD_S1_CS_PIN\r
+ self.EPD_M2_CS_PIN = epdconfig.EPD_M2_CS_PIN\r
+ self.EPD_S2_CS_PIN = epdconfig.EPD_S2_CS_PIN\r
+\r
+ self.EPD_M1S1_DC_PIN = epdconfig.EPD_M1S1_DC_PIN\r
+ self.EPD_M2S2_DC_PIN = epdconfig.EPD_M2S2_DC_PIN\r
+\r
+ self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
+ self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
+\r
+ self.EPD_M1_BUSY_PIN = epdconfig.EPD_M1_BUSY_PIN\r
+ self.EPD_S1_BUSY_PIN = epdconfig.EPD_S1_BUSY_PIN\r
+ self.EPD_M2_BUSY_PIN = epdconfig.EPD_M2_BUSY_PIN\r
+ self.EPD_S2_BUSY_PIN = epdconfig.EPD_S2_BUSY_PIN\r
+\r
+ def Init(self):\r
+ print("EPD init...")\r
+ epdconfig.module_init()\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+ self.Reset() \r
+\r
+ # panel setting for Clear\r
+ # self.M1_SendCommand(0x00)\r
+ # self.M1_SendData(0x07) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
+ # self.S1_SendCommand(0x00)\r
+ # self.S1_SendData(0x07)\r
+ # self.M2_SendCommand(0x00)\r
+ # self.M2_SendData(0x07)\r
+ # self.S2_SendCommand(0x00)\r
+ # self.S2_SendData(0x07)\r
+\r
+ # panel setting for Display\r
+ self.M1_SendCommand(0x00)\r
+ self.M1_SendData(0x0f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f\r
+ self.S1_SendCommand(0x00)\r
+ self.S1_SendData(0x0f)\r
+ self.M2_SendCommand(0x00)\r
+ self.M2_SendData(0x03)\r
+ self.S2_SendCommand(0x00)\r
+ self.S2_SendData(0x03)\r
+\r
+ # booster soft start\r
+ self.M1_SendCommand(0x06)\r
+ self.M1_SendData(0x17) #A\r
+ self.M1_SendData(0x17) #B\r
+ self.M1_SendData(0x39) #C\r
+ self.M1_SendData(0x17)\r
+ self.M2_SendCommand(0x06)\r
+ self.M2_SendData(0x17)\r
+ self.M2_SendData(0x17)\r
+ self.M2_SendData(0x39)\r
+ self.M2_SendData(0x17)\r
+\r
+ #resolution setting\r
+ self.M1_SendCommand(0x61)\r
+ self.M1_SendData(0x02)\r
+ self.M1_SendData(0x88) #source 648\r
+ self.M1_SendData(0x01) #gate 492\r
+ self.M1_SendData(0xEC)\r
+ self.S1_SendCommand(0x61)\r
+ self.S1_SendData(0x02)\r
+ self.S1_SendData(0x90) #source 656\r
+ self.S1_SendData(0x01) #gate 492\r
+ self.S1_SendData(0xEC)\r
+ self.M2_SendCommand(0x61)\r
+ self.M2_SendData(0x02)\r
+ self.M2_SendData(0x90) #source 656\r
+ self.M2_SendData(0x01) #gate 492\r
+ self.M2_SendData(0xEC)\r
+ self.S2_SendCommand(0x61)\r
+ self.S2_SendData(0x02)\r
+ self.S2_SendData(0x88) #source 648\r
+ self.S2_SendData(0x01) #gate 492\r
+ self.S2_SendData(0xEC)\r
+\r
+ self.M1S1M2S2_SendCommand(0x15) #DUSPI\r
+ self.M1S1M2S2_SendData(0x20)\r
+\r
+ self.M1S1M2S2_SendCommand(0x50) #Vcom and data interval setting\r
+ self.M1S1M2S2_SendData(0x11)\r
+ self.M1S1M2S2_SendData(0x07)\r
+\r
+ self.M1S1M2S2_SendCommand(0x60)#TCON\r
+ self.M1S1M2S2_SendData(0x22)\r
+\r
+ self.M1S1M2S2_SendCommand(0xE3)\r
+ self.M1S1M2S2_SendData(0x00)\r
+\r
+ self.M1_ReadTemperature()\r
+ \r
+ def display(self, BlackImage, RedImage):\r
+ start = time.perf_counter()\r
+ \r
+ Blackbuf = [0x00] * int(self.width * self.height / 8)\r
+ blackconvert = BlackImage.convert('1') \r
+ bimwidth, bimheight = blackconvert.size \r
+ Blackpixles = blackconvert.load()\r
+ temp=0\r
+ for y in range(0, bimheight):\r
+ for x in range(0, bimwidth):\r
+ if Blackpixles[x, y] < 127: # black\r
+ Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+ else: # white\r
+ Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+ temp=temp+1\r
+ if(temp==8):\r
+ temp=0\r
+ \r
+ Redbuf = [0x00] * int(self.width * self.height / 8)\r
+ redconvert = RedImage.convert('1')\r
+ rimwidth, rimheight = redconvert.size \r
+ Redpixles = redconvert.load()\r
+ temp=0\r
+ for y in range(0, rimheight):\r
+ for x in range(0, rimwidth):\r
+ if Redpixles[x, y] < 127: # black\r
+ Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+ else: # white\r
+ Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+ temp=temp+1\r
+ if(temp==8):\r
+ temp=0\r
+ \r
+ #S2 part 648*492\r
+ self.S2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(Blackbuf[y*163 + x])\r
+ self.S2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(~Redbuf[y*163 + x])\r
+ \r
+ #M2 part 656*492\r
+ self.M2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(Blackbuf[y*163 + x])\r
+ self.M2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(~Redbuf[y*163 + x])\r
+\r
+ #M1 part 648*492 \r
+ self.M1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(Blackbuf[y*163 + x])\r
+ self.M1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(~Redbuf[y*163 + x])\r
+ \r
+ #S1 part 656*492\r
+ self.S1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(Blackbuf[y*163 + x])\r
+ self.S1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(~Redbuf[y*163 + x])\r
+ \r
+ end = time.perf_counter()\r
+ print("use time: %f"%(end - start))\r
+ self.TurnOnDisplay()\r
+\r
+ def clear(self):\r
+ """Clear contents of image buffer"""\r
+ start = time.perf_counter()\r
+ \r
+ self.S2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(0xff) \r
+ self.S2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(0, 81):\r
+ self.S2_SendData(0x00)\r
+ \r
+ self.M2_SendCommand(0x10)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(0xff)\r
+ self.M2_SendCommand(0x13)\r
+ for y in range(0, 492):\r
+ for x in range(81, 163):\r
+ self.M2_SendData(0x00) \r
+ \r
+ self.M1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(0xff)\r
+ self.M1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(0, 81):\r
+ self.M1_SendData(0x00)\r
+ \r
+ self.S1_SendCommand(0x10)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(0xff)\r
+ self.S1_SendCommand(0x13)\r
+ for y in range(492, 984):\r
+ for x in range(81, 163):\r
+ self.S1_SendData(0x00)\r
+ \r
+ end = time.perf_counter()\r
+ print (end)\r
+ print (start)\r
+ print("use time: %f" %(end - start))\r
+ \r
+ self.TurnOnDisplay()\r
+ \r
+ def Reset(self):\r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+ time.sleep(0.2) \r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
+ time.sleep(0.01) \r
+ epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+ epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+ time.sleep(0.2) \r
+ \r
+ def EPD_Sleep(self):\r
+ self.M1S1M2S2_SendCommand(0X02) \r
+ time.sleep(0.3) \r
+\r
+ self.M1S1M2S2_SendCommand(0X07) \r
+ self.M1S1M2S2_SendData(0xA5) \r
+ time.sleep(0.3) \r
+ print("module_exit")\r
+ epdconfig.module_exit()\r
+\r
+ def TurnOnDisplay(self):\r
+ self.M1M2_SendCommand(0x04) \r
+ time.sleep(0.3) \r
+ self.M1S1M2S2_SendCommand(0x12) \r
+ self.M1_ReadBusy()\r
+ self.S1_ReadBusy()\r
+ self.M2_ReadBusy()\r
+ self.S2_ReadBusy() \r
+ \r
+ """ M1S1M2S2 Write register address and data """\r
+ def M1S1M2S2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ def M1S1M2S2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+ """ M1M2 Write register address and data """\r
+ def M1M2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ \r
+ def M1M2_Sendata(self, val): \r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+ \r
+ """ S2 Write register address and data """\r
+ def S2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ def S2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ """ M2 Write register address and data """\r
+ def M2_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ def M2_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val) \r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+ """ S1 Write register address and data """\r
+ def S1_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ def S1_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ \r
+ """ M1 Write register address and data """\r
+ def M1_SendCommand(self, cmd):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(cmd)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ def M1_SendData(self, val):\r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.spi_writebyte(val)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+ #Busy\r
+ def M1_ReadBusy(self):\r
+ self.M1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ while(busy):\r
+ self.M1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2)\r
+ def M2_ReadBusy(self):\r
+ self.M2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ self.M2_SendCommand(0x71) \r
+ while(busy):\r
+ self.M2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+ busy =not(busy & 0x01) \r
+ time.sleep(0.2)\r
+ def S1_ReadBusy(self):\r
+ self.S1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ while(busy):\r
+ self.S1_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2) \r
+ def S2_ReadBusy(self):\r
+ self.S2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ while(busy):\r
+ self.S2_SendCommand(0x71) \r
+ busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+ busy = not(busy & 0x01) \r
+ time.sleep(0.2) \r
+\r
+ lut_vcom1 = [\r
+ 0x00, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x00, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x00, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_ww1 = [\r
+ 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_bw1 = [\r
+ 0xA8, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x84, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x86, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x8C, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0xF0, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_wb1 = [\r
+ 0x91, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x08, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ lut_bb1 = [\r
+ 0x92, 0x10, 0x10, 0x01, 0x08, 0x01,\r
+ 0x80, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x84, 0x08, 0x01, 0x08, 0x01, 0x06,\r
+ 0x04, 0x06, 0x01, 0x06, 0x01, 0x05,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x06,\r
+ 0x00, 0x05, 0x01, 0x1E, 0x0F, 0x01,\r
+ 0x01, 0x04, 0x05, 0x08, 0x08, 0x01,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+ ]\r
+ \r
+ def SetLut(self):\r
+ self.M1S1M2S2_SendCommand(0x20) #vcom\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
+\r
+ self.M1S1M2S2_SendCommand(0x21) #red not use\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_ww1[count])\r
+\r
+ self.M1S1M2S2_SendCommand(0x22) #bw r\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_bw1[count]) # bw=r\r
+\r
+ self.M1S1M2S2_SendCommand(0x23) #wb w\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_wb1[count]) # wb=w\r
+\r
+ self.M1S1M2S2_SendCommand(0x24) #bb b\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_bb1[count]) # bb=b\r
+ \r
+ self.M1S1M2S2_SendCommand(0x25) #bb b\r
+ for count in range(0, 60):\r
+ self.M1S1M2S2_SendData(self.lut_ww1[count]) # bb=b\r
+\r
+ def M1_ReadTemperature(self):\r
+ self.M1_SendCommand(0x40)\r
+ self.M1_ReadBusy()\r
+ time.sleep(0.3)\r
+ \r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+ epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+ epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+ \r
+ epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+ time.sleep(0.05)\r
+ \r
+ temp = epdconfig.spi_readbyte(0x00)\r
+ epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+ \r
+ self.M1S1M2S2_SendCommand(0xE0)\r
+ self.M1S1M2S2_SendData(0x03)\r
+ self.M1S1M2S2_SendCommand(0xE5)\r
+ self.M1S1M2S2_SendData(temp)\r
--- /dev/null
+# /*****************************************************************************\r
+# * | File : epdconfig.py\r
+# * | Author : Waveshare electrices\r
+# * | Function : Hardware underlying interface\r
+# * | Info :\r
+# *----------------\r
+# * | This version: V1.0\r
+# * | Date : 2019-11-01\r
+# * | Info : \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+import os\r
+import logging\r
+import sys\r
+\r
+from ctypes import *\r
+\r
+EPD_SCK_PIN =11\r
+EPD_MOSI_PIN =10\r
+\r
+EPD_M1_CS_PIN =8\r
+EPD_S1_CS_PIN =7\r
+EPD_M2_CS_PIN =17\r
+EPD_S2_CS_PIN =18\r
+\r
+EPD_M1S1_DC_PIN =13\r
+EPD_M2S2_DC_PIN =22\r
+\r
+EPD_M1S1_RST_PIN =6\r
+EPD_M2S2_RST_PIN =23\r
+\r
+EPD_M1_BUSY_PIN =5\r
+EPD_S1_BUSY_PIN =19\r
+EPD_M2_BUSY_PIN =27\r
+EPD_S2_BUSY_PIN =24\r
+\r
+find_dirs = [\r
+ os.path.dirname(os.path.realpath(__file__)),\r
+ '/usr/local/lib',\r
+ '/usr/lib',\r
+]\r
+spi = None\r
+for find_dir in find_dirs:\r
+ val = int(os.popen('getconf LONG_BIT').read())\r
+ logging.debug("System is %d bit"%val)\r
+ if val == 64:\r
+ so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_64bit.so')\r
+ else:\r
+ so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_32bit.so')\r
+ if os.path.exists(so_filename):\r
+ spi = CDLL(so_filename)\r
+ break\r
+if spi is None:\r
+ RuntimeError('Cannot find DEV_Config.so')\r
+\r
+def digital_write(pin, value):\r
+ spi.DEV_Digital_Write(pin, value)\r
+\r
+def digital_read(pin):\r
+ return spi.DEV_Digital_Read(pin)\r
+\r
+def spi_writebyte(value): \r
+ spi.DEV_SPI_WriteByte(value)\r
+ \r
+def delay_ms(delaytime):\r
+ time.sleep(delaytime / 1000.0)\r
+ \r
+def module_init():\r
+ spi.DEV_ModuleInit()\r
+\r
+def module_exit():\r
+ spi.DEV_ModuleExit()\r
+\r
+\r
+def spi_readbyte(Reg):\r
+ return spi.DEV_SPI_ReadByte(Reg)\r
+ \r
+def delay_ms(delaytime):\r
+ time.sleep(delaytime / 1000.0)\r
+\r
+ \r
--- /dev/null
+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)
+
--- /dev/null
+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
+
+++ /dev/null
-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)
-
+++ /dev/null
-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
-