Added support for more E-Paper displays
This commit is contained in:
		
							
								
								
									
										478
									
								
								modules/drivers/epd_4_in_2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										478
									
								
								modules/drivers/epd_4_in_2.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,478 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | 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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
from PIL import Image
 | 
			
		||||
import RPi.GPIO as GPIO
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 400
 | 
			
		||||
EPD_HEIGHT      = 300
 | 
			
		||||
 | 
			
		||||
GRAY1  = 0xff #white
 | 
			
		||||
GRAY2  = 0xC0
 | 
			
		||||
GRAY3  = 0x80 #gray
 | 
			
		||||
GRAY4  = 0x00 #Blackest
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    lut_vcom0 = [
 | 
			
		||||
    0x00, 0x17, 0x00, 0x00, 0x00, 0x02,        
 | 
			
		||||
    0x00, 0x17, 0x17, 0x00, 0x00, 0x02,        
 | 
			
		||||
    0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,        
 | 
			
		||||
    0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,        
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    ]
 | 
			
		||||
    lut_ww = [
 | 
			
		||||
    0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
 | 
			
		||||
    0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    ]
 | 
			
		||||
    lut_bw = [
 | 
			
		||||
    0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
 | 
			
		||||
    0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    ]
 | 
			
		||||
    lut_wb = [
 | 
			
		||||
    0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
 | 
			
		||||
    0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
    ]
 | 
			
		||||
    lut_bb = [
 | 
			
		||||
    0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
 | 
			
		||||
    0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
 | 
			
		||||
    0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
 | 
			
		||||
    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(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(10)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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, 44):
 | 
			
		||||
            self.send_data(self.lut_vcom0[count])
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x21)         # ww --
 | 
			
		||||
        for count in range(0, 42):
 | 
			
		||||
            self.send_data(self.lut_ww[count])
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x22)         # bw r
 | 
			
		||||
        for count in range(0, 42):
 | 
			
		||||
            self.send_data(self.lut_bw[count])
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x23)         # wb w
 | 
			
		||||
        for count in range(0, 42):
 | 
			
		||||
            self.send_data(self.lut_bb[count])
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x24)         # bb b
 | 
			
		||||
        for count in range(0, 42):
 | 
			
		||||
            self.send_data(self.lut_wb[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_data(0x0d)
 | 
			
		||||
        
 | 
			
		||||
        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(0x28)
 | 
			
		||||
 | 
			
		||||
        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_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):
 | 
			
		||||
        # logging.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()
 | 
			
		||||
        # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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):
 | 
			
		||||
            logging.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):
 | 
			
		||||
        # logging.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
 | 
			
		||||
        # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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):
 | 
			
		||||
            logging.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(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 display_4Gray(self, image):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, 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, 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.module_exit()
 | 
			
		||||
        
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										148
									
								
								modules/drivers/epd_4_in_2_colour.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								modules/drivers/epd_4_in_2_colour.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd4in2bc.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 400
 | 
			
		||||
EPD_HEIGHT      = 300
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(10)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
 | 
			
		||||
            epdconfig.delay_ms(100)
 | 
			
		||||
        logging.debug("e-Paper busy release")
 | 
			
		||||
            
 | 
			
		||||
    def init(self):
 | 
			
		||||
        if (epdconfig.module_init() != 0):
 | 
			
		||||
            return -1
 | 
			
		||||
            
 | 
			
		||||
        self.reset()
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x06) # BOOSTER_SOFT_START
 | 
			
		||||
        self.send_data (0x17)
 | 
			
		||||
        self.send_data (0x17)
 | 
			
		||||
        self.send_data (0x17) # 07 0f 17 1f 27 2F 37 2f
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x04) # POWER_ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x00) # PANEL_SETTING
 | 
			
		||||
        self.send_data(0x0F) # LUT from OTP
 | 
			
		||||
        
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        # logging.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()
 | 
			
		||||
        # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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):
 | 
			
		||||
            logging.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 display(self, imageblack, imagered):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(imageblack[i])
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x13)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(imagered[i])
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x12) 
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    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) # check code
 | 
			
		||||
        
 | 
			
		||||
        epdconfig.module_exit()
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										200
									
								
								modules/drivers/epd_5_in_83.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								modules/drivers/epd_5_in_83.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,200 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd5in83.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 600
 | 
			
		||||
EPD_HEIGHT      = 448
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(10)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        while(epdconfig.digital_read(self.busy_pin) == 0):      # 0: idle, 1: busy
 | 
			
		||||
            epdconfig.delay_ms(100)    
 | 
			
		||||
        logging.debug("e-Paper busy release")
 | 
			
		||||
        
 | 
			
		||||
    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(0x37)
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x00) # PANEL_SETTING
 | 
			
		||||
        self.send_data(0xCF)
 | 
			
		||||
        self.send_data(0x08)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x06) # BOOSTER_SOFT_START
 | 
			
		||||
        self.send_data(0xc7)
 | 
			
		||||
        self.send_data(0xcc)
 | 
			
		||||
        self.send_data(0x28)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x04) # POWER_ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x30) # PLL_CONTROL
 | 
			
		||||
        self.send_data(0x3c)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x41) # TEMPERATURE_CALIBRATION
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
 | 
			
		||||
        self.send_data(0x77)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x60) # TCON_SETTING
 | 
			
		||||
        self.send_data(0x22)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x61) # TCON_RESOLUTION
 | 
			
		||||
        self.send_data(0x02) # source 600
 | 
			
		||||
        self.send_data(0x58)
 | 
			
		||||
        self.send_data(0x01) # gate 448
 | 
			
		||||
        self.send_data(0xC0)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x82) # VCM_DC_SETTING
 | 
			
		||||
        self.send_data(0x1E) # decide by LUT file
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0xe5) # FLASH MODE
 | 
			
		||||
        self.send_data(0x03)
 | 
			
		||||
        
 | 
			
		||||
        # EPD hardware init end
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        buf = [0x00] * int(self.width * self.height / 4)
 | 
			
		||||
        image_monocolor = image.convert('1')
 | 
			
		||||
        imwidth, imheight = image_monocolor.size
 | 
			
		||||
        pixels = image_monocolor.load()
 | 
			
		||||
        logging.debug('imwidth = %d  imheight =  %d ',imwidth, imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            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] < 64:           # black
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2))
 | 
			
		||||
                    elif pixels[x, y] < 192:     # convert gray to red
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2))
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] |= 0x40 >> (x % 4 * 2)
 | 
			
		||||
                    else:                           # white
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] |= 0xC0 >> (x % 4 * 2)
 | 
			
		||||
        elif(imwidth == self.height and imheight == self.width):
 | 
			
		||||
            for y in range(imheight):
 | 
			
		||||
                for x in range(imwidth):
 | 
			
		||||
                    newx = y
 | 
			
		||||
                    newy = self.height - x - 1                    
 | 
			
		||||
                    if pixels[x, y] < 64:           # black
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2))
 | 
			
		||||
                    elif pixels[x, y] < 192:     # convert gray to red
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2))
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] |= 0x40 >> (y % 4 * 2)
 | 
			
		||||
                    else:                           # white
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] |= 0xC0 >> (y % 4 * 2)
 | 
			
		||||
        return buf
 | 
			
		||||
 | 
			
		||||
    def display(self, image):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 4 * self.height)):
 | 
			
		||||
            temp1 = image[i]
 | 
			
		||||
            j = 0
 | 
			
		||||
            while (j < 4):
 | 
			
		||||
                if ((temp1 & 0xC0) == 0xC0):
 | 
			
		||||
                    temp2 = 0x03
 | 
			
		||||
                elif ((temp1 & 0xC0) == 0x00):
 | 
			
		||||
                    temp2 = 0x00
 | 
			
		||||
                else:
 | 
			
		||||
                    temp2 = 0x04
 | 
			
		||||
                temp2 = (temp2 << 4) & 0xFF
 | 
			
		||||
                temp1 = (temp1 << 2) & 0xFF
 | 
			
		||||
                j += 1
 | 
			
		||||
                if((temp1 & 0xC0) == 0xC0):
 | 
			
		||||
                    temp2 |= 0x03
 | 
			
		||||
                elif ((temp1 & 0xC0) == 0x00):
 | 
			
		||||
                    temp2 |= 0x00
 | 
			
		||||
                else:
 | 
			
		||||
                    temp2 |= 0x04
 | 
			
		||||
                temp1 = (temp1 << 2) & 0xFF
 | 
			
		||||
                self.send_data(temp2)
 | 
			
		||||
                j += 1
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x12)
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    def Clear(self):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 4 * self.height)):
 | 
			
		||||
            for j in range(0, 4):
 | 
			
		||||
                self.send_data(0x33)
 | 
			
		||||
        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.module_exit()        
 | 
			
		||||
        
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										200
									
								
								modules/drivers/epd_5_in_83_colour.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								modules/drivers/epd_5_in_83_colour.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,200 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd5in83b.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 600
 | 
			
		||||
EPD_HEIGHT      = 448
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(10)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        while(epdconfig.digital_read(self.busy_pin) == 0):      # 0: idle, 1: busy
 | 
			
		||||
            epdconfig.delay_ms(100)
 | 
			
		||||
        logging.debug("e-Paper busy release")
 | 
			
		||||
            
 | 
			
		||||
    def init(self):
 | 
			
		||||
        if (epdconfig.module_init() != 0):
 | 
			
		||||
            return -1
 | 
			
		||||
            
 | 
			
		||||
        self.reset()
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x01) # POWER_SETTING
 | 
			
		||||
        self.send_data(0x37)
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x00) # PANEL_SETTING
 | 
			
		||||
        self.send_data(0xCF)
 | 
			
		||||
        self.send_data(0x08)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x30) # PLL_CONTROL
 | 
			
		||||
        self.send_data(0x3A) # PLL:  0-15:0x3C, 15+:0x3A
 | 
			
		||||
        self.send_command(0X82) # VCOM VOLTAGE SETTING
 | 
			
		||||
        self.send_data(0x28) # all temperature  range
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x06) # boost
 | 
			
		||||
        self.send_data(0xc7) 	   	
 | 
			
		||||
        self.send_data(0xcc) 
 | 
			
		||||
        self.send_data(0x15) 
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
 | 
			
		||||
        self.send_data(0x77) 
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X60) # TCON SETTING
 | 
			
		||||
        self.send_data(0x22) 
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X65) # FLASH CONTROL
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x61) # tres			
 | 
			
		||||
        self.send_data(0x02) # source 600
 | 
			
		||||
        self.send_data(0x58) 
 | 
			
		||||
        self.send_data(0x01) # gate 448
 | 
			
		||||
        self.send_data(0xc0)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0xe5) # FLASH MODE		   	
 | 
			
		||||
        self.send_data(0x03) 
 | 
			
		||||
        self.send_data(0x03)
 | 
			
		||||
        
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        # logging.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()
 | 
			
		||||
        logging.debug('imwidth = %d  imheight =  %d ',imwidth, imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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):
 | 
			
		||||
            logging.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 display(self, imageblack, imagered):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 8 * self.height)):
 | 
			
		||||
            temp1 = imageblack[i]
 | 
			
		||||
            temp2 = imagered[i]
 | 
			
		||||
            j = 0
 | 
			
		||||
            while (j < 8):
 | 
			
		||||
                if ((temp2 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 = 0x04                #red
 | 
			
		||||
                elif ((temp1 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 = 0x00                #black
 | 
			
		||||
                else:
 | 
			
		||||
                    temp3 = 0x03                #white
 | 
			
		||||
					
 | 
			
		||||
                temp3 = (temp3 << 4) & 0xFF
 | 
			
		||||
                temp1 = (temp1 << 1) & 0xFF
 | 
			
		||||
                temp2 = (temp2 << 1) & 0xFF
 | 
			
		||||
                j += 1
 | 
			
		||||
                if((temp2 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 |= 0x04              #red
 | 
			
		||||
                elif ((temp1 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 |= 0x00              #black
 | 
			
		||||
                else:
 | 
			
		||||
                    temp3 |= 0x03              #white
 | 
			
		||||
                temp1 = (temp1 << 1) & 0xFF
 | 
			
		||||
                temp2 = (temp2 << 1) & 0xFF
 | 
			
		||||
                self.send_data(temp3)
 | 
			
		||||
                j += 1
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x04) # POWER ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        self.send_command(0x12) # display refresh
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    def Clear(self):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 8 * self.height)):
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x04) # POWER ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        self.send_command(0x12) # display refresh
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
 | 
			
		||||
    def sleep(self):
 | 
			
		||||
        self.send_command(0x02) # POWER_OFF
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        self.send_command(0x07) # DEEP_SLEEP
 | 
			
		||||
        self.send_data(0xA5) # check code
 | 
			
		||||
        
 | 
			
		||||
        epdconfig.module_exit()
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										202
									
								
								modules/drivers/epd_7_in_5.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								modules/drivers/epd_7_in_5.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd7in5.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 640
 | 
			
		||||
EPD_HEIGHT      = 384
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(10)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        while(epdconfig.digital_read(self.busy_pin) == 0):      # 0: idle, 1: busy
 | 
			
		||||
            epdconfig.delay_ms(100)    
 | 
			
		||||
        logging.debug("e-Paper busy release")
 | 
			
		||||
        
 | 
			
		||||
    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(0x37)
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x00) # PANEL_SETTING
 | 
			
		||||
        self.send_data(0xCF)
 | 
			
		||||
        self.send_data(0x08)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x06) # BOOSTER_SOFT_START
 | 
			
		||||
        self.send_data(0xc7)
 | 
			
		||||
        self.send_data(0xcc)
 | 
			
		||||
        self.send_data(0x28)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x04) # POWER_ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x30) # PLL_CONTROL
 | 
			
		||||
        self.send_data(0x3c)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x41) # TEMPERATURE_CALIBRATION
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
 | 
			
		||||
        self.send_data(0x77)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x60) # TCON_SETTING
 | 
			
		||||
        self.send_data(0x22)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x61) # TCON_RESOLUTION
 | 
			
		||||
        self.send_data(EPD_WIDTH >> 8)     #source 640
 | 
			
		||||
        self.send_data(EPD_WIDTH & 0xff)
 | 
			
		||||
        self.send_data(EPD_HEIGHT >> 8)     #gate 384
 | 
			
		||||
        self.send_data(EPD_HEIGHT & 0xff)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x82) # VCM_DC_SETTING
 | 
			
		||||
        self.send_data(0x1E) # decide by LUT file
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0xe5) # FLASH MODE
 | 
			
		||||
        self.send_data(0x03)
 | 
			
		||||
        
 | 
			
		||||
        # EPD hardware init end
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        logging.debug("1234")
 | 
			
		||||
        buf = [0x00] * int(self.width * self.height / 4)
 | 
			
		||||
        image_monocolor = image.convert('1')
 | 
			
		||||
        imwidth, imheight = image_monocolor.size
 | 
			
		||||
        pixels = image_monocolor.load()
 | 
			
		||||
        logging.debug('imwidth = %d  imheight =  %d ',imwidth, imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            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] < 64:           # black
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2))
 | 
			
		||||
                    elif pixels[x, y] < 192:     # convert gray to red
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2))
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] |= 0x40 >> (x % 4 * 2)
 | 
			
		||||
                    else:                           # white
 | 
			
		||||
                        buf[int((x + y * self.width) / 4)] |= 0xC0 >> (x % 4 * 2)
 | 
			
		||||
        elif(imwidth == self.height and imheight == self.width):
 | 
			
		||||
            for y in range(imheight):
 | 
			
		||||
                for x in range(imwidth):
 | 
			
		||||
                    newx = y
 | 
			
		||||
                    newy = self.height - x - 1                    
 | 
			
		||||
                    if pixels[x, y] < 64:           # black
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2))
 | 
			
		||||
                    elif pixels[x, y] < 192:     # convert gray to red
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2))
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] |= 0x40 >> (y % 4 * 2)
 | 
			
		||||
                    else:                           # white
 | 
			
		||||
                        buf[int((newx + newy*self.width) / 4)] |= 0xC0 >> (y % 4 * 2)
 | 
			
		||||
        return buf    
 | 
			
		||||
        
 | 
			
		||||
    def display(self, image):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 4 * self.height)):
 | 
			
		||||
            temp1 = image[i]
 | 
			
		||||
            j = 0
 | 
			
		||||
            while (j < 4):
 | 
			
		||||
                if ((temp1 & 0xC0) == 0xC0):
 | 
			
		||||
                    temp2 = 0x03
 | 
			
		||||
                elif ((temp1 & 0xC0) == 0x00):
 | 
			
		||||
                    temp2 = 0x00
 | 
			
		||||
                else:
 | 
			
		||||
                    temp2 = 0x04
 | 
			
		||||
                temp2 = (temp2 << 4) & 0xFF
 | 
			
		||||
                temp1 = (temp1 << 2) & 0xFF
 | 
			
		||||
                j += 1
 | 
			
		||||
                if((temp1 & 0xC0) == 0xC0):
 | 
			
		||||
                    temp2 |= 0x03
 | 
			
		||||
                elif ((temp1 & 0xC0) == 0x00):
 | 
			
		||||
                    temp2 |= 0x00
 | 
			
		||||
                else:
 | 
			
		||||
                    temp2 |= 0x04
 | 
			
		||||
                temp1 = (temp1 << 2) & 0xFF
 | 
			
		||||
                self.send_data(temp2)
 | 
			
		||||
                j += 1
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x12)
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    def Clear(self):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 4 * self.height)):
 | 
			
		||||
            for j in range(0, 4):
 | 
			
		||||
                self.send_data(0x33)
 | 
			
		||||
                
 | 
			
		||||
        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.module_exit()
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										201
									
								
								modules/drivers/epd_7_in_5_colour.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								modules/drivers/epd_7_in_5_colour.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd7in5bc.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 640
 | 
			
		||||
EPD_HEIGHT      = 384
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(10)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        while(epdconfig.digital_read(self.busy_pin) == 0):      # 0: idle, 1: busy
 | 
			
		||||
            epdconfig.delay_ms(100)
 | 
			
		||||
        logging.debug("e-Paper busy release")
 | 
			
		||||
            
 | 
			
		||||
    def init(self):
 | 
			
		||||
        if (epdconfig.module_init() != 0):
 | 
			
		||||
            return -1
 | 
			
		||||
            
 | 
			
		||||
        self.reset()
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x01) # POWER_SETTING
 | 
			
		||||
        self.send_data(0x37)
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x00) # PANEL_SETTING
 | 
			
		||||
        self.send_data(0xCF)
 | 
			
		||||
        self.send_data(0x08)
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x30) # PLL_CONTROL
 | 
			
		||||
        self.send_data(0x3A) # PLL:  0-15:0x3C, 15+:0x3A
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x82) # VCM_DC_SETTING
 | 
			
		||||
        self.send_data(0x28) #all temperature  range
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x06) # BOOSTER_SOFT_START
 | 
			
		||||
        self.send_data(0xc7)
 | 
			
		||||
        self.send_data(0xcc)
 | 
			
		||||
        self.send_data(0x15)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x50) # VCOM AND DATA INTERVAL SETTING
 | 
			
		||||
        self.send_data(0x77)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x60) # TCON_SETTING
 | 
			
		||||
        self.send_data(0x22)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x65) # FLASH CONTROL
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x61) # TCON_RESOLUTION
 | 
			
		||||
        self.send_data(self.width >> 8) # source 640
 | 
			
		||||
        self.send_data(self.width & 0xff)
 | 
			
		||||
        self.send_data(self.height >> 8) # gate 384
 | 
			
		||||
        self.send_data(self.height & 0xff)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0xe5) # FLASH MODE
 | 
			
		||||
        self.send_data(0x03)
 | 
			
		||||
        
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        # logging.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()
 | 
			
		||||
        logging.debug('imwidth = %d  imheight =  %d ',imwidth, imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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):
 | 
			
		||||
            logging.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 display(self, imageblack, imagered):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 8 * self.height)):
 | 
			
		||||
            temp1 = imageblack[i]
 | 
			
		||||
            temp2 = imagered[i]
 | 
			
		||||
            j = 0
 | 
			
		||||
            while (j < 8):
 | 
			
		||||
                if ((temp2 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 = 0x04                #red
 | 
			
		||||
                elif ((temp1 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 = 0x00                #black
 | 
			
		||||
                else:
 | 
			
		||||
                    temp3 = 0x03                #white
 | 
			
		||||
					
 | 
			
		||||
                temp3 = (temp3 << 4) & 0xFF
 | 
			
		||||
                temp1 = (temp1 << 1) & 0xFF
 | 
			
		||||
                temp2 = (temp2 << 1) & 0xFF
 | 
			
		||||
                j += 1
 | 
			
		||||
                if((temp2 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 |= 0x04              #red
 | 
			
		||||
                elif ((temp1 & 0x80) == 0x00):
 | 
			
		||||
                    temp3 |= 0x00              #black
 | 
			
		||||
                else:
 | 
			
		||||
                    temp3 |= 0x03              #white
 | 
			
		||||
                temp1 = (temp1 << 1) & 0xFF
 | 
			
		||||
                temp2 = (temp2 << 1) & 0xFF
 | 
			
		||||
                self.send_data(temp3)
 | 
			
		||||
                j += 1
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x04) # POWER ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        self.send_command(0x12) # display refresh
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    def Clear(self):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width / 8 * self.height)):
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            self.send_data(0x33)
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x04) # POWER ON
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        self.send_command(0x12) # display refresh
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
 | 
			
		||||
    def sleep(self):
 | 
			
		||||
        self.send_command(0x02) # POWER_OFF
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x07) # DEEP_SLEEP
 | 
			
		||||
        self.send_data(0XA5)
 | 
			
		||||
        
 | 
			
		||||
        epdconfig.module_exit()
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										170
									
								
								modules/drivers/epd_7_in_5_v2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								modules/drivers/epd_7_in_5_v2.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd7in5.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 800
 | 
			
		||||
EPD_HEIGHT      = 480
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(2)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        self.send_command(0x71)
 | 
			
		||||
        busy = epdconfig.digital_read(self.busy_pin)
 | 
			
		||||
        while(busy == 0):
 | 
			
		||||
            self.send_command(0x71)
 | 
			
		||||
            busy = epdconfig.digital_read(self.busy_pin)
 | 
			
		||||
        epdconfig.delay_ms(200)
 | 
			
		||||
        
 | 
			
		||||
    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(0x07)
 | 
			
		||||
        self.send_data(0x07)    #VGH=20V,VGL=-20V
 | 
			
		||||
        self.send_data(0x3f)		#VDH=15V
 | 
			
		||||
        self.send_data(0x3f)		#VDL=-15V
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x04) #POWER ON
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X00)			#PANNEL SETTING
 | 
			
		||||
        self.send_data(0x1F)   #KW-3f   KWR-2F	BWROTP 0f	BWOTP 1f
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x61)        	#tres
 | 
			
		||||
        self.send_data(0x03)		#source 800
 | 
			
		||||
        self.send_data(0x20)
 | 
			
		||||
        self.send_data(0x01)		#gate 480
 | 
			
		||||
        self.send_data(0xE0)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X15)
 | 
			
		||||
        self.send_data(0x00)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X50)			#VCOM AND DATA INTERVAL SETTING
 | 
			
		||||
        self.send_data(0x10)
 | 
			
		||||
        self.send_data(0x07)
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X60)			#TCON SETTING
 | 
			
		||||
        self.send_data(0x22)
 | 
			
		||||
 | 
			
		||||
        # EPD hardware init end
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        # logging.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()
 | 
			
		||||
        # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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] == 0:
 | 
			
		||||
                        buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
 | 
			
		||||
        elif(imwidth == self.height and imheight == self.width):
 | 
			
		||||
            logging.debug("Horizontal")
 | 
			
		||||
            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 display(self, image):
 | 
			
		||||
        self.send_command(0x13)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(~image[i]);
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x12)
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    def Clear(self):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(0x00)
 | 
			
		||||
            
 | 
			
		||||
        self.send_command(0x13)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(0x00)
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x12)
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
 | 
			
		||||
    def sleep(self):
 | 
			
		||||
        self.send_command(0x02) # POWER_OFF
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x07) # DEEP_SLEEP
 | 
			
		||||
        self.send_data(0XA5)
 | 
			
		||||
        
 | 
			
		||||
        epdconfig.module_exit()
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										173
									
								
								modules/drivers/epd_7_in_5_v2_colour.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								modules/drivers/epd_7_in_5_v2_colour.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
# *****************************************************************************
 | 
			
		||||
# * | File        :	  epd7in5bc.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 logging
 | 
			
		||||
from . import epdconfig
 | 
			
		||||
 | 
			
		||||
# Display resolution
 | 
			
		||||
EPD_WIDTH       = 800
 | 
			
		||||
EPD_HEIGHT      = 480
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    # Hardware reset
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200) 
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 0)
 | 
			
		||||
        epdconfig.delay_ms(4)
 | 
			
		||||
        epdconfig.digital_write(self.reset_pin, 1)
 | 
			
		||||
        epdconfig.delay_ms(200)   
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        logging.debug("e-Paper busy")
 | 
			
		||||
        self.send_command(0x71)
 | 
			
		||||
        busy = epdconfig.digital_read(self.busy_pin)
 | 
			
		||||
        while(busy == 0):
 | 
			
		||||
            self.send_command(0x71)
 | 
			
		||||
            busy = epdconfig.digital_read(self.busy_pin)
 | 
			
		||||
        epdconfig.delay_ms(200)
 | 
			
		||||
            
 | 
			
		||||
    def init(self):
 | 
			
		||||
        if (epdconfig.module_init() != 0):
 | 
			
		||||
            return -1
 | 
			
		||||
            
 | 
			
		||||
        self.reset()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x01);			#POWER SETTING
 | 
			
		||||
        self.send_data(0x07);
 | 
			
		||||
        self.send_data(0x07);    #VGH=20V,VGL=-20V
 | 
			
		||||
        self.send_data(0x3f);		#VDH=15V
 | 
			
		||||
        self.send_data(0x3f);		#VDL=-15V
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x04); #POWER ON
 | 
			
		||||
        epdconfig.delay_ms(100);
 | 
			
		||||
        self.ReadBusy();
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X00);			#PANNEL SETTING
 | 
			
		||||
        self.send_data(0x0F);   #KW-3f   KWR-2F	BWROTP 0f	BWOTP 1f
 | 
			
		||||
 | 
			
		||||
        self.send_command(0x61);        	#tres
 | 
			
		||||
        self.send_data(0x03);		#source 800
 | 
			
		||||
        self.send_data(0x20);
 | 
			
		||||
        self.send_data(0x01);		#gate 480
 | 
			
		||||
        self.send_data(0xE0);
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X15);
 | 
			
		||||
        self.send_data(0x00);
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X50);			#VCOM AND DATA INTERVAL SETTING
 | 
			
		||||
        self.send_data(0x11);
 | 
			
		||||
        self.send_data(0x07);
 | 
			
		||||
 | 
			
		||||
        self.send_command(0X60);			#TCON SETTING
 | 
			
		||||
        self.send_data(0x22);
 | 
			
		||||
        
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def getbuffer(self, image):
 | 
			
		||||
        # logging.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()
 | 
			
		||||
        logging.debug('imwidth = %d  imheight =  %d ',imwidth, imheight)
 | 
			
		||||
        if(imwidth == self.width and imheight == self.height):
 | 
			
		||||
            logging.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):
 | 
			
		||||
            logging.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 display(self, imageblack, imagered):
 | 
			
		||||
        self.send_command(0x10)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(imageblack[i]);
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x13)
 | 
			
		||||
        for i in range(0, int(self.width * self.height / 8)):
 | 
			
		||||
            self.send_data(~imagered[i]);
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x12)
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
    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(0x00)
 | 
			
		||||
                
 | 
			
		||||
        self.send_command(0x12)
 | 
			
		||||
        epdconfig.delay_ms(100)
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
 | 
			
		||||
    def sleep(self):
 | 
			
		||||
        self.send_command(0x02) # POWER_OFF
 | 
			
		||||
        self.ReadBusy()
 | 
			
		||||
        
 | 
			
		||||
        self.send_command(0x07) # DEEP_SLEEP
 | 
			
		||||
        self.send_data(0XA5)
 | 
			
		||||
        
 | 
			
		||||
        epdconfig.module_exit()
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										154
									
								
								modules/drivers/epdconfig.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								modules/drivers/epdconfig.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
# /*****************************************************************************
 | 
			
		||||
# * | File        :	  epdconfig.py
 | 
			
		||||
# * | Author      :   Waveshare team
 | 
			
		||||
# * | Function    :   Hardware underlying interface
 | 
			
		||||
# * | Info        :
 | 
			
		||||
# *----------------
 | 
			
		||||
# * | This version:   V1.0
 | 
			
		||||
# * | Date        :   2019-06-21
 | 
			
		||||
# * | Info        :   
 | 
			
		||||
# ******************************************************************************
 | 
			
		||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
# of this software and associated documnetation files (the "Software"), to deal
 | 
			
		||||
# in the Software without restriction, including without limitation the rights
 | 
			
		||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
# copies of the Software, and to permit persons to  whom the Software is
 | 
			
		||||
# furished to do so, subject to the following conditions:
 | 
			
		||||
#
 | 
			
		||||
# The above copyright notice and this permission notice shall be included in
 | 
			
		||||
# all copies or substantial portions of the Software.
 | 
			
		||||
#
 | 
			
		||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
# THE SOFTWARE.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import logging
 | 
			
		||||
import sys
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RaspberryPi:
 | 
			
		||||
    # Pin definition
 | 
			
		||||
    RST_PIN         = 17
 | 
			
		||||
    DC_PIN          = 25
 | 
			
		||||
    CS_PIN          = 8
 | 
			
		||||
    BUSY_PIN        = 24
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        import spidev
 | 
			
		||||
        import RPi.GPIO
 | 
			
		||||
 | 
			
		||||
        self.GPIO = RPi.GPIO
 | 
			
		||||
 | 
			
		||||
        # SPI device, bus = 0, device = 0
 | 
			
		||||
        self.SPI = spidev.SpiDev(0, 0)
 | 
			
		||||
 | 
			
		||||
    def digital_write(self, pin, value):
 | 
			
		||||
        self.GPIO.output(pin, value)
 | 
			
		||||
 | 
			
		||||
    def digital_read(self, pin):
 | 
			
		||||
        return self.GPIO.input(pin)
 | 
			
		||||
 | 
			
		||||
    def delay_ms(self, delaytime):
 | 
			
		||||
        time.sleep(delaytime / 1000.0)
 | 
			
		||||
 | 
			
		||||
    def spi_writebyte(self, data):
 | 
			
		||||
        self.SPI.writebytes(data)
 | 
			
		||||
 | 
			
		||||
    def module_init(self):
 | 
			
		||||
        self.GPIO.setmode(self.GPIO.BCM)
 | 
			
		||||
        self.GPIO.setwarnings(False)
 | 
			
		||||
        self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
 | 
			
		||||
        self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
 | 
			
		||||
        self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
 | 
			
		||||
        self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
 | 
			
		||||
        self.SPI.max_speed_hz = 4000000
 | 
			
		||||
        self.SPI.mode = 0b00
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def module_exit(self):
 | 
			
		||||
        logging.debug("spi end")
 | 
			
		||||
        #self.SPI.close() #removed as it causes some problems
 | 
			
		||||
 | 
			
		||||
        logging.debug("close 5V, Module enters 0 power consumption ...")
 | 
			
		||||
        self.GPIO.output(self.RST_PIN, 0)
 | 
			
		||||
        self.GPIO.output(self.DC_PIN, 0)
 | 
			
		||||
 | 
			
		||||
        self.GPIO.cleanup()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JetsonNano:
 | 
			
		||||
    # Pin definition
 | 
			
		||||
    RST_PIN         = 17
 | 
			
		||||
    DC_PIN          = 25
 | 
			
		||||
    CS_PIN          = 8
 | 
			
		||||
    BUSY_PIN        = 24
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        import ctypes
 | 
			
		||||
        find_dirs = [
 | 
			
		||||
            os.path.dirname(os.path.realpath(__file__)),
 | 
			
		||||
            '/usr/local/lib',
 | 
			
		||||
            '/usr/lib',
 | 
			
		||||
        ]
 | 
			
		||||
        self.SPI = None
 | 
			
		||||
        for find_dir in find_dirs:
 | 
			
		||||
            so_filename = os.path.join(find_dir, 'sysfs_software_spi.so')
 | 
			
		||||
            if os.path.exists(so_filename):
 | 
			
		||||
                self.SPI = ctypes.cdll.LoadLibrary(so_filename)
 | 
			
		||||
                break
 | 
			
		||||
        if self.SPI is None:
 | 
			
		||||
            raise RuntimeError('Cannot find sysfs_software_spi.so')
 | 
			
		||||
 | 
			
		||||
        import Jetson.GPIO
 | 
			
		||||
        self.GPIO = Jetson.GPIO
 | 
			
		||||
 | 
			
		||||
    def digital_write(self, pin, value):
 | 
			
		||||
        self.GPIO.output(pin, value)
 | 
			
		||||
 | 
			
		||||
    def digital_read(self, pin):
 | 
			
		||||
        return self.GPIO.input(self.BUSY_PIN)
 | 
			
		||||
 | 
			
		||||
    def delay_ms(self, delaytime):
 | 
			
		||||
        time.sleep(delaytime / 1000.0)
 | 
			
		||||
 | 
			
		||||
    def spi_writebyte(self, data):
 | 
			
		||||
        self.SPI.SYSFS_software_spi_transfer(data[0])
 | 
			
		||||
 | 
			
		||||
    def module_init(self):
 | 
			
		||||
        self.GPIO.setmode(self.GPIO.BCM)
 | 
			
		||||
        self.GPIO.setwarnings(False)
 | 
			
		||||
        self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
 | 
			
		||||
        self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
 | 
			
		||||
        self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
 | 
			
		||||
        self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
 | 
			
		||||
        self.SPI.SYSFS_software_spi_begin()
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def module_exit(self):
 | 
			
		||||
        logging.debug("spi end")
 | 
			
		||||
        self.SPI.SYSFS_software_spi_end()
 | 
			
		||||
 | 
			
		||||
        logging.debug("close 5V, Module enters 0 power consumption ...")
 | 
			
		||||
        self.GPIO.output(self.RST_PIN, 0)
 | 
			
		||||
        self.GPIO.output(self.DC_PIN, 0)
 | 
			
		||||
 | 
			
		||||
        self.GPIO.cleanup()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'):
 | 
			
		||||
    implementation = RaspberryPi()
 | 
			
		||||
else:
 | 
			
		||||
    implementation = JetsonNano()
 | 
			
		||||
 | 
			
		||||
for func in [x for x in dir(implementation) if not x.startswith('_')]:
 | 
			
		||||
    setattr(sys.modules[__name__], func, getattr(implementation, func))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### END OF FILE ###
 | 
			
		||||
							
								
								
									
										1
									
								
								modules/drivers/init.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								modules/drivers/init.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#nothing in here. What did you expect?
 | 
			
		||||
		Reference in New Issue
	
	Block a user