| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 | # *****************************************************************************# * | File        :   epd4in2.py# * | Author      :   Waveshare team# * | Function    :   Electronic paper driver# * | Info        :# *----------------# * | This version:   V4.0# * | Date        :   2019-06-20# # | Info        :   python demo# -----------------------------------------------------------------------------# Permission is hereby granted, free of charge, to any person obtaining a copy# of this software and associated documnetation files (the "Software"), to deal# in the Software without restriction, including without limitation the rights# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell# copies of the Software, and to permit persons to  whom the Software is# furished to do so, subject to the following conditions:## The above copyright notice and this permission notice shall be included in# all copies or substantial portions of the Software.## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN# THE SOFTWARE.#import loggingfrom . import epdconfigfrom PIL import Imageimport RPi.GPIO as GPIO# Display resolutionEPD_WIDTH       = 400EPD_HEIGHT      = 300GRAY1  = 0xff #whiteGRAY2  = 0xC0GRAY3  = 0x80 #grayGRAY4  = 0x00 #Blackestlogger = logging.getLogger(__name__)class EPD:    def __init__(self):        self.reset_pin = epdconfig.RST_PIN        self.dc_pin = epdconfig.DC_PIN        self.busy_pin = epdconfig.BUSY_PIN        self.cs_pin = epdconfig.CS_PIN        self.width = EPD_WIDTH        self.height = EPD_HEIGHT        self.GRAY1  = GRAY1 #white        self.GRAY2  = GRAY2        self.GRAY3  = GRAY3 #gray        self.GRAY4  = GRAY4 #Blackest        self.DATA   = [0x00] * 15000    lut_vcom0 = [    0x00, 0x08, 0x08, 0x00, 0x00, 0x02,     0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01,     0x00, 0x08, 0x08, 0x00, 0x00, 0x02,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00,     ]    lut_ww = [    0x50, 0x08, 0x08, 0x00, 0x00, 0x02,     0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,     0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    ]    lut_bw = [    0x50, 0x08, 0x08, 0x00, 0x00, 0x02,     0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,     0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    ]    lut_wb = [    0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,     0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,     0x50, 0x08, 0x08, 0x00, 0x00, 0x02,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    ]    lut_bb = [    0x20, 0x08, 0x08, 0x00, 0x00, 0x02,     0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,     0x10, 0x08, 0x08, 0x00, 0x00, 0x02,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    ]    #******************************partial screen update LUT*********************************/    EPD_4IN2_Partial_lut_vcom1 =[    0x00, 0x01, 0x20, 0x01, 0x00, 0x01,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    ]    EPD_4IN2_Partial_lut_ww1 =[    0x00, 0x01, 0x20, 0x01, 0x00, 0x01,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    ]    EPD_4IN2_Partial_lut_bw1 =[    0x20, 0x01, 0x20, 0x01, 0x00, 0x01,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     ]    EPD_4IN2_Partial_lut_wb1 =[    0x10, 0x01, 0x20, 0x01, 0x00, 0x01,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     ]    EPD_4IN2_Partial_lut_bb1 =[    0x00, 0x01,0x20, 0x01, 0x00, 0x01,     0x00, 0x00,0x00, 0x00, 0x00, 0x00,     0x00, 0x00,0x00, 0x00, 0x00, 0x00,     0x00, 0x00,0x00, 0x00, 0x00, 0x00,     0x00, 0x00,0x00, 0x00, 0x00, 0x00,     0x00, 0x00,0x00, 0x00, 0x00, 0x00,    0x00, 0x00,0x00, 0x00, 0x00, 0x00,     ]    #******************************gray*********************************/    #0~3 gray    EPD_4IN2_4Gray_lut_vcom =[    0x00 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,    0x60 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,    0x00 ,0x14 ,0x00 ,0x00 ,0x00 ,0x01,    0x00 ,0x13 ,0x0A ,0x01 ,0x00 ,0x01,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00    ]    #R21    EPD_4IN2_4Gray_lut_ww =[    0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,    0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,    0x10 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,    0xA0 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    ]    #R22H r    EPD_4IN2_4Gray_lut_bw =[    0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,    0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,    0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,    0x99 ,0x0C ,0x01 ,0x03 ,0x04 ,0x01,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    ]    #R23H w    EPD_4IN2_4Gray_lut_wb =[    0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,    0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,    0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,    0x99 ,0x0B ,0x04 ,0x04 ,0x01 ,0x01,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    ]    #R24H b    EPD_4IN2_4Gray_lut_bb =[    0x80 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,    0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,    0x20 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,    0x50 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,    ]        # Hardware reset    def reset(self):        epdconfig.digital_write(self.reset_pin, 1)        epdconfig.delay_ms(10)         epdconfig.digital_write(self.reset_pin, 0)        epdconfig.delay_ms(10)        epdconfig.digital_write(self.reset_pin, 1)        epdconfig.delay_ms(10)           epdconfig.digital_write(self.reset_pin, 0)        epdconfig.delay_ms(10)        epdconfig.digital_write(self.reset_pin, 1)        epdconfig.delay_ms(10)           epdconfig.digital_write(self.reset_pin, 0)        epdconfig.delay_ms(10)        epdconfig.digital_write(self.reset_pin, 1)        epdconfig.delay_ms(10)    def send_command(self, command):        epdconfig.digital_write(self.dc_pin, 0)        epdconfig.digital_write(self.cs_pin, 0)        epdconfig.spi_writebyte([command])        epdconfig.digital_write(self.cs_pin, 1)    def send_data(self, data):        epdconfig.digital_write(self.dc_pin, 1)        epdconfig.digital_write(self.cs_pin, 0)        epdconfig.spi_writebyte([data])        epdconfig.digital_write(self.cs_pin, 1)            def ReadBusy(self):        self.send_command(0x71)        while(epdconfig.digital_read(self.busy_pin) == 0):      # 0: idle, 1: busy            self.send_command(0x71)            epdconfig.delay_ms(100)        def set_lut(self):        self.send_command(0x20)               # vcom        for count in range(0, 36):            self.send_data(self.lut_vcom0[count])                    self.send_command(0x21)         # ww --        for count in range(0, 36):            self.send_data(self.lut_ww[count])                    self.send_command(0x22)         # bw r        for count in range(0, 36):            self.send_data(self.lut_bw[count])                    self.send_command(0x23)         # wb w        for count in range(0, 36):            self.send_data(self.lut_bb[count])                    self.send_command(0x24)         # bb b        for count in range(0, 36):            self.send_data(self.lut_wb[count])    def Partial_SetLut(self):        self.send_command(0x20);        for count in range(0, 44):                  self.send_data(self.EPD_4IN2_Partial_lut_vcom1[count])        self.send_command(0x21);        for count in range(0, 42):                  self.send_data(self.EPD_4IN2_Partial_lut_ww1[count])                self.send_command(0x22);        for count in range(0, 42):                 self.send_data(self.EPD_4IN2_Partial_lut_bw1[count])        self.send_command(0x23);        for count in range(0, 42):                  self.send_data(self.EPD_4IN2_Partial_lut_wb1[count])        self.send_command(0x24);        for count in range(0, 42):                  self.send_data(self.EPD_4IN2_Partial_lut_bb1[count])           def Gray_SetLut(self):        self.send_command(0x20)      #vcom        for count in range(0, 42):            self.send_data(self.EPD_4IN2_4Gray_lut_vcom[count])         self.send_command(0x21)      #red not use        for count in range(0, 42):            self.send_data(self.EPD_4IN2_4Gray_lut_ww[count])         self.send_command(0x22)       #bw r        for count in range(0, 42):            self.send_data(self.EPD_4IN2_4Gray_lut_bw[count])         self.send_command(0x23)       #wb w        for count in range(0, 42):            self.send_data(self.EPD_4IN2_4Gray_lut_wb[count])         self.send_command(0x24)                          #bb b        for count in range(0, 42):            self.send_data(self.EPD_4IN2_4Gray_lut_bb[count])         self.send_command(0x25)      #vcom        for count in range(0, 42):            self.send_data(self.EPD_4IN2_4Gray_lut_ww[count])              def init(self):        if (epdconfig.module_init() != 0):            return -1        # EPD hardware init start        self.reset()                self.send_command(0x01) # POWER SETTING        self.send_data(0x03) # VDS_EN, VDG_EN        self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]        self.send_data(0x2b) # VDH        self.send_data(0x2b) # VDL                self.send_command(0x06) # boost soft start        self.send_data(0x17)        self.send_data(0x17)        self.send_data(0x17)                self.send_command(0x04) # POWER_ON        self.ReadBusy()                self.send_command(0x00) # panel setting        self.send_data(0xbf) # KW-BF   KWR-AF  BWROTP 0f                self.send_command(0x30) # PLL setting        self.send_data(0x3c) # 3A 100HZ   29 150Hz 39 200HZ  31 171HZ        self.send_command(0x61) # resolution setting        self.send_data(0x01)        self.send_data(0x90) # 128        self.send_data(0x01)          self.send_data(0x2c)        self.send_command(0x82) # vcom_DC setting        self.send_data(0x12)        self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING        self.send_data(0x97) # 97white border 77black border  VBDF 17|D7 VBDW 97 VBDB 57  VBDF F7 VBDW 77 VBDB 37  VBDR B7            self.set_lut()        # EPD hardware init end        return 0            def init_Partial(self):        if (epdconfig.module_init() != 0):            return -1        # EPD hardware init start        self.reset()                self.send_command(0x01) # POWER SETTING        self.send_data(0x03) # VDS_EN, VDG_EN        self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]        self.send_data(0x2b) # VDH        self.send_data(0x2b) # VDL                self.send_command(0x06) # boost soft start        self.send_data(0x17)        self.send_data(0x17)        self.send_data(0x17)                self.send_command(0x04) # POWER_ON        self.ReadBusy()                self.send_command(0x00) # panel setting        self.send_data(0xbf) # KW-BF   KWR-AF  BWROTP 0f                self.send_command(0x30) # PLL setting        self.send_data(0x3c) # 3A 100HZ   29 150Hz 39 200HZ  31 171HZ        self.send_command(0x61) # resolution setting        self.send_data(0x01)        self.send_data(0x90) # 128        self.send_data(0x01)          self.send_data(0x2c)        self.send_command(0x82) # vcom_DC setting        self.send_data(0x12)        self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING        self.send_data(0x07) # 97white border 77black border  VBDF 17|D7 VBDW 97 VBDB 57  VBDF F7 VBDW 77 VBDB 37  VBDR B7            self.Partial_SetLut();        # EPD hardware init end        return 0            def Init_4Gray(self):        if (epdconfig.module_init() != 0):            return -1        # EPD hardware init start        self.reset()                self.send_command(0x01)   #POWER SETTING        self.send_data (0x03)        self.send_data (0x00)       #VGH=20V,VGL=-20V        self.send_data (0x2b)  #VDH=15V                        self.send_data (0x2b)  #VDL=-15V        self.send_data (0x13)        self.send_command(0x06)         #booster soft start        self.send_data (0x17)  #A        self.send_data (0x17)  #B        self.send_data (0x17)  #C         self.send_command(0x04)        self.ReadBusy()        self.send_command(0x00)   #panel setting        self.send_data(0x3f)  #KW-3f   KWR-2F BWROTP 0f BWOTP 1f        self.send_command(0x30)   #PLL setting        self.send_data (0x3c)       #100hz         self.send_command(0x61)   #resolution setting        self.send_data (0x01)  #400        self.send_data (0x90)               self.send_data (0x01)  #300        self.send_data (0x2c)        self.send_command(0x82)   #vcom_DC setting        self.send_data (0x12)        self.send_command(0X50)   #VCOM AND DATA INTERVAL SETTING           self.send_data(0x97)    def getbuffer(self, image):        # logger.debug("bufsiz = ",int(self.width/8) * self.height)        buf = [0xFF] * (int(self.width/8) * self.height)        image_monocolor = image.convert('1')        imwidth, imheight = image_monocolor.size        pixels = image_monocolor.load()        # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)        if(imwidth == self.width and imheight == self.height):            logger.debug("Horizontal")            for y in range(imheight):                for x in range(imwidth):                    # Set the bits for the column of pixels at the current position.                    if pixels[x, y] == 0:                        buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))        elif(imwidth == self.height and imheight == self.width):            logger.debug("Vertical")            for y in range(imheight):                for x in range(imwidth):                    newx = y                    newy = self.height - x - 1                    if pixels[x, y] == 0:                        buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))        return buf            def getbuffer_4Gray(self, image):        # logger.debug("bufsiz = ",int(self.width/8) * self.height)        buf = [0xFF] * (int(self.width / 4) * self.height)        image_monocolor = image.convert('L')        imwidth, imheight = image_monocolor.size        pixels = image_monocolor.load()        i=0        # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)        if(imwidth == self.width and imheight == self.height):            logger.debug("Vertical")            for y in range(imheight):                for x in range(imwidth):                    # Set the bits for the column of pixels at the current position.                    if(pixels[x, y] == 0xC0):                        pixels[x, y] = 0x80                    elif (pixels[x, y] == 0x80):                        pixels[x, y] = 0x40                    i= i+1                    if(i%4 == 0):                        buf[int((x + (y * self.width))/4)] = ((pixels[x-3, y]&0xc0) | (pixels[x-2, y]&0xc0)>>2 | (pixels[x-1, y]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)                                elif(imwidth == self.height and imheight == self.width):            logger.debug("Horizontal")            for x in range(imwidth):                for y in range(imheight):                    newx = y                    newy = x                    if(pixels[x, y] == 0xC0):                        pixels[x, y] = 0x80                    elif (pixels[x, y] == 0x80):                        pixels[x, y] = 0x40                    i= i+1                    if(i%4 == 0):                        buf[int((newx + (newy * self.width))/4)] = ((pixels[x, y-3]&0xc0) | (pixels[x, y-2]&0xc0)>>2 | (pixels[x, y-1]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)                 return buf    def display(self, image):        self.send_command(0x92);         self.set_lut();        self.send_command(0x10)        for i in range(0, int(self.width * self.height / 8)):            self.send_data(0xFF)                    self.send_command(0x13)        for i in range(0, int(self.width * self.height / 8)):            self.send_data(image[i])                    self.send_command(0x12)         self.ReadBusy()    def EPD_4IN2_PartialDisplay(self, X_start, Y_start, X_end, Y_end, Image):        # EPD_WIDTH       = 400        # EPD_HEIGHT      = 300        if(EPD_WIDTH % 8 != 0):           Width = int(EPD_WIDTH / 8) + 1;        else:            Width = int(EPD_WIDTH / 8);        Height = EPD_HEIGHT;                if(X_start % 8 != 0):            X_start = int(X_start/8)*8+8        if(X_end % 8 != 0):            X_end = int(X_end/8)*8+8                        self.send_command(0x91);  #This command makes the display enter partial mode        self.send_command(0x90);  #resolution setting        self.send_data (int(X_start/256));        self.send_data (int(X_start%256));   #x-start                    self.send_data (int(X_end /256));          self.send_data (int(X_end %256)-1);  #x-end        self.send_data (int(Y_start/256));        self.send_data (int(Y_start%256));   #y-start                    self.send_data (int(Y_end/256));          self.send_data (int(Y_end%256)-1);  #y-end        self.send_data (0x28);         self.send_command(0x10);        #writes Old data to SRAM for programming        for j in range(0, int(Y_end - Y_start)):            for i in range(0, int(X_end/8) - int(X_start/8)):                self.send_data(self.DATA[(Y_start + j)*Width + int(X_start/8) + i]);                    self.send_command(0x13);     #writes New data to SRAM.        for j in range(0, int(Y_end - Y_start)):            for i in range(0, int(X_end/8) - int(X_start/8)):                self.send_data(~Image[(Y_start + j)*Width + int(X_start/8) + i]);                self.DATA[(Y_start + j)*Width + int(X_start/8) + i] = ~Image[(Y_start + j)*Width + int(X_start/8) + i]                    self.send_command(0x12);   #DISPLAY REFRESH                        epdconfig.delay_ms(200)    #The delay here is necessary, 200uS at least!!!             self.ReadBusy()    def display_4Gray(self, image):        self.send_command(0x92);         self.set_lut();        self.send_command(0x10)        for i in range(0, int(EPD_WIDTH * EPD_HEIGHT / 8)):                   # EPD_WIDTH * EPD_HEIGHT / 4            temp3=0            for j in range(0, 2):                temp1 = image[i*2+j]                for k in range(0, 2):                    temp2 = temp1&0xC0                     if(temp2 == 0xC0):                        temp3 |= 0x01#white                    elif(temp2 == 0x00):                        temp3 |= 0x00  #black                    elif(temp2 == 0x80):                         temp3 |= 0x01  #gray1                    else: #0x40                        temp3 |= 0x00 #gray2                    temp3 <<= 1                                         temp1 <<= 2                    temp2 = temp1&0xC0                     if(temp2 == 0xC0):  #white                        temp3 |= 0x01                    elif(temp2 == 0x00): #black                        temp3 |= 0x00                    elif(temp2 == 0x80):                        temp3 |= 0x01 #gray1                    else :   #0x40                            temp3 |= 0x00 #gray2                     if(j!=1 or k!=1):                            temp3 <<= 1                    temp1 <<= 2            self.send_data(temp3)                    self.send_command(0x13)                            for i in range(0, int(EPD_WIDTH * EPD_HEIGHT / 8)):                #5808*4  46464            temp3=0            for j in range(0, 2):                temp1 = image[i*2+j]                for k in range(0, 2):                    temp2 = temp1&0xC0                     if(temp2 == 0xC0):                        temp3 |= 0x01#white                    elif(temp2 == 0x00):                        temp3 |= 0x00  #black                    elif(temp2 == 0x80):                        temp3 |= 0x00  #gray1                    else: #0x40                        temp3 |= 0x01 #gray2                    temp3 <<= 1                                         temp1 <<= 2                    temp2 = temp1&0xC0                     if(temp2 == 0xC0):  #white                        temp3 |= 0x01                    elif(temp2 == 0x00): #black                        temp3 |= 0x00                    elif(temp2 == 0x80):                        temp3 |= 0x00 #gray1                    else:    #0x40                            temp3 |= 0x01 #gray2                    if(j!=1 or k!=1):                             temp3 <<= 1                    temp1 <<= 2            self.send_data(temp3)                self.Gray_SetLut()        self.send_command(0x12)        epdconfig.delay_ms(200)        self.ReadBusy()        # pass        def Clear(self):        self.send_command(0x10)        for i in range(0, int(self.width * self.height / 8)):            self.send_data(0xFF)                    self.send_command(0x13)        for i in range(0, int(self.width * self.height / 8)):            self.send_data(0xFF)                    self.send_command(0x12)         self.ReadBusy()    def sleep(self):        self.send_command(0x02) # POWER_OFF        self.ReadBusy()        self.send_command(0x07) # DEEP_SLEEP        self.send_data(0XA5)                epdconfig.delay_ms(2000)        epdconfig.module_exit()        ### END OF FILE ###
 |