diff --git a/lib/LCD_2inch.py b/lib/LCD_2inch.py new file mode 100644 index 0000000..72aa1bb --- /dev/null +++ b/lib/LCD_2inch.py @@ -0,0 +1,179 @@ + +import time +from . import lcdconfig + +class LCD_2inch(lcdconfig.RaspberryPi): + + width = 240 + height = 320 + def command(self, cmd): + self.digital_write(self.DC_PIN, False) + self.spi_writebyte([cmd]) + + def data(self, val): + self.digital_write(self.DC_PIN, True) + self.spi_writebyte([val]) + def reset(self): + """Reset the display""" + self.digital_write(self.RST_PIN,True) + time.sleep(0.01) + self.digital_write(self.RST_PIN,False) + time.sleep(0.01) + self.digital_write(self.RST_PIN,True) + time.sleep(0.01) + + def Init(self): + """Initialize dispaly""" + self.module_init() + self.reset() + + self.command(0x36) + self.data(0x00) + + self.command(0x3A) + self.data(0x05) + + self.command(0x21) + + self.command(0x2A) + self.data(0x00) + self.data(0x00) + self.data(0x01) + self.data(0x3F) + + self.command(0x2B) + self.data(0x00) + self.data(0x00) + self.data(0x00) + self.data(0xEF) + + self.command(0xB2) + self.data(0x0C) + self.data(0x0C) + self.data(0x00) + self.data(0x33) + self.data(0x33) + + self.command(0xB7) + self.data(0x35) + + self.command(0xBB) + self.data(0x1F) + + self.command(0xC0) + self.data(0x2C) + + self.command(0xC2) + self.data(0x01) + + self.command(0xC3) + self.data(0x12) + + self.command(0xC4) + self.data(0x20) + + self.command(0xC6) + self.data(0x0F) + + self.command(0xD0) + self.data(0xA4) + self.data(0xA1) + + self.command(0xE0) + self.data(0xD0) + self.data(0x08) + self.data(0x11) + self.data(0x08) + self.data(0x0C) + self.data(0x15) + self.data(0x39) + self.data(0x33) + self.data(0x50) + self.data(0x36) + self.data(0x13) + self.data(0x14) + self.data(0x29) + self.data(0x2D) + + self.command(0xE1) + self.data(0xD0) + self.data(0x08) + self.data(0x10) + self.data(0x08) + self.data(0x06) + self.data(0x06) + self.data(0x39) + self.data(0x44) + self.data(0x51) + self.data(0x0B) + self.data(0x16) + self.data(0x14) + self.data(0x2F) + self.data(0x31) + self.command(0x21) + + self.command(0x11) + + self.command(0x29) + + + def SetWindows(self, Xstart, Ystart, Xend, Yend): + #set the X coordinates + self.command(0x2A) + self.data(Xstart>>8) #Set the horizontal starting point to the high octet + self.data(Xstart & 0xff) #Set the horizontal starting point to the low octet + self.data(Xend>>8) #Set the horizontal end to the high octet + self.data((Xend - 1) & 0xff)#Set the horizontal end to the low octet + + #set the Y coordinates + self.command(0x2B) + self.data(Ystart>>8) + self.data((Ystart & 0xff)) + self.data(Yend>>8) + self.data((Yend - 1) & 0xff ) + + self.command(0x2C) + + def ShowImage(self,Image,Xstart=0,Ystart=0): + """Set buffer to value of Python Imaging Library image.""" + """Write display buffer to physical display""" + imwidth, imheight = Image.size + if imwidth == self.height and imheight == self.width: + img = self.np.asarray(Image) + pix = self.np.zeros((self.width, self.height,2), dtype = self.np.uint8) + #RGB888 >> RGB565 + pix[...,[0]] = self.np.add(self.np.bitwise_and(img[...,[0]],0xF8),self.np.right_shift(img[...,[1]],5)) + pix[...,[1]] = self.np.add(self.np.bitwise_and(self.np.left_shift(img[...,[1]],3),0xE0), self.np.right_shift(img[...,[2]],3)) + pix = pix.flatten().tolist() + + self.command(0x36) + self.data(0x70) + self.SetWindows ( 0, 0, self.height,self.width) + self.digital_write(self.DC_PIN,True) + for i in range(0,len(pix),4096): + self.spi_writebyte(pix[i:i+4096]) + + else : + img = self.np.asarray(Image) + pix = self.np.zeros((imheight,imwidth , 2), dtype = self.np.uint8) + + pix[...,[0]] = self.np.add(self.np.bitwise_and(img[...,[0]],0xF8),self.np.right_shift(img[...,[1]],5)) + pix[...,[1]] = self.np.add(self.np.bitwise_and(self.np.left_shift(img[...,[1]],3),0xE0), self.np.right_shift(img[...,[2]],3)) + + pix = pix.flatten().tolist() + + self.command(0x36) + self.data(0x00) + self.SetWindows ( 0, 0, self.width, self.height) + self.digital_write(self.DC_PIN,True) + for i in range(0,len(pix),4096): + self.spi_writebyte(pix[i:i+4096]) + + def clear(self): + """Clear contents of image buffer""" + _buffer = [0xff]*(self.width * self.height * 2) + self.SetWindows ( 0, 0, self.height, self.width) + self.digital_write(self.DC_PIN,True) + for i in range(0,len(_buffer),4096): + self.spi_writebyte(_buffer[i:i+4096]) + diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/lcdconfig.py b/lib/lcdconfig.py new file mode 100644 index 0000000..b6bc218 --- /dev/null +++ b/lib/lcdconfig.py @@ -0,0 +1,116 @@ +# /***************************************************************************** +# * | 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 sys +import time +import spidev +import logging +import numpy as np +from gpiozero import * + +class RaspberryPi: + def __init__(self,spi=spidev.SpiDev(0,0),spi_freq=40000000,rst = 27,dc = 25,bl = 18,bl_freq=1000,i2c=None,i2c_freq=100000): + self.np=np + self.INPUT = False + self.OUTPUT = True + + self.SPEED =spi_freq + self.BL_freq=bl_freq + + self.RST_PIN= self.gpio_mode(rst,self.OUTPUT) + self.DC_PIN = self.gpio_mode(dc,self.OUTPUT) + self.BL_PIN = self.gpio_pwm(bl) + self.bl_DutyCycle(0) + + #Initialize SPI + self.SPI = spi + if self.SPI!=None : + self.SPI.max_speed_hz = spi_freq + self.SPI.mode = 0b00 + + def gpio_mode(self,Pin,Mode,pull_up = None,active_state = True): + if Mode: + return DigitalOutputDevice(Pin,active_high = True,initial_value =False) + else: + return DigitalInputDevice(Pin,pull_up=pull_up,active_state=active_state) + + def digital_write(self, Pin, value): + if value: + Pin.on() + else: + Pin.off() + + def digital_read(self, Pin): + return Pin.value + + def delay_ms(self, delaytime): + time.sleep(delaytime / 1000.0) + + def gpio_pwm(self,Pin): + return PWMOutputDevice(Pin,frequency = self.BL_freq) + + def spi_writebyte(self, data): + if self.SPI!=None : + self.SPI.writebytes(data) + + def bl_DutyCycle(self, duty): + self.BL_PIN.value = duty / 100 + + def bl_Frequency(self,freq):# Hz + self.BL_PIN.frequency = freq + + def module_init(self): + if self.SPI!=None : + self.SPI.max_speed_hz = self.SPEED + self.SPI.mode = 0b00 + return 0 + + def module_exit(self): + logging.debug("spi end") + if self.SPI!=None : + self.SPI.close() + + logging.debug("gpio cleanup...") + self.digital_write(self.RST_PIN, 1) + self.digital_write(self.DC_PIN, 0) + self.BL_PIN.close() + time.sleep(0.001) + + + +''' +if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'): + implementation = RaspberryPi() + +for func in [x for x in dir(implementation) if not x.startswith('_')]: + setattr(sys.modules[__name__], func, getattr(implementation, func)) +''' + +### END OF FILE ###