101 lines
3.8 KiB
Python
101 lines
3.8 KiB
Python
"""
|
|
ST7735/FrameBuffer
|
|
|
|
MicroPython library for the ST7735(TFT-SPI)
|
|
=======================================================
|
|
@dahanzimin From the Mixly Team
|
|
"""
|
|
import time
|
|
import uframebuf
|
|
from machine import Pin
|
|
from image import Image, IMG
|
|
|
|
class ST7735(uframebuf.FrameBuffer_Uincode):
|
|
def __init__(self, spi, width, height, dc_pin=None, backlight=None, reset=None, font_address=0x700000):
|
|
self.spi = spi
|
|
self.dc = Pin(dc_pin, Pin.OUT, value=1)
|
|
self._buffer = bytearray(width * height * 2)
|
|
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
|
if reset: reset(1, 100)
|
|
self.font(font_address)
|
|
self._init()
|
|
self._oneclight = True
|
|
self._backlight = backlight
|
|
|
|
def _write(self, cmd, dat=None):
|
|
"""Write command or data"""
|
|
self.dc.off()
|
|
self.spi.write(bytearray([cmd]))
|
|
if dat is not None:
|
|
self.dc.on()
|
|
self.spi.write(dat)
|
|
|
|
def _init(self):
|
|
"""Display initialization configuration"""
|
|
for cmd, data, delay in [
|
|
(0x11, None, 120000),
|
|
(0xB1, b'\x01\x2C\x2D', 10),
|
|
(0xB2, b'\x01\x2C\x2D', 10),
|
|
(0xB3, b'\x01\x2C\x2D', 10),
|
|
(0xB4, b'\x07', 10),
|
|
(0xC0, b'\xA2\x02\x84', 10),
|
|
(0xC1, b'\xC5', 10),
|
|
(0xC2, b'\x0A\x00', 10),
|
|
(0xC3, b'\x8A\x2A', 10),
|
|
(0xC4, b'\x8A\xEE', 10),
|
|
(0xC5, b'\x0E', 10),
|
|
(0x36, b'\xC8', 10),
|
|
(0xE0, b'\x02\x1C\x07\x12\x37\x32\x29\x2D\x29\x25\x2B\x39\x00\x01\x03\x10', 10),
|
|
(0xE1, b'\x03\x1D\x07\x06\x2E\x2C\x29\x2D\x2E\x2E\x37\x3F\x00\x00\x02\x10', 10),
|
|
(0x3A, b'\x05', 10),
|
|
(0x29, None, 10),
|
|
(0x2A, b'\x00\x02\x00\x81', 10),
|
|
(0x2B, b'\x00\x03\x00\x82', 10)
|
|
]:
|
|
self._write(cmd, data)
|
|
if delay:
|
|
time.sleep_us(delay)
|
|
|
|
def display(self, data=None, x=None, y=None, scale_width=None, scale_height=None, rotation=0, sync=True):
|
|
'''data is a string, display the path image; otherwise, display the image of data'''
|
|
if type(data) is str:
|
|
data = Image.open(data, scale_width, scale_height, self.width, self.height, rotation=rotation)
|
|
if sync: self.fill(0x0, sync=False)
|
|
self.blit_rgb565(data.image, data.width, data.height, x, y)
|
|
if sync: self.show()
|
|
|
|
def screenshot(self, data=None, x=0, y=0, w=None, h=None, **kwargs):
|
|
'''data is a string, save the path image; otherwise, return the image of data'''
|
|
if (w is None and h is None):
|
|
_img = IMG(memoryview(self._buffer), self.width, self.height)
|
|
else:
|
|
_img = IMG(memoryview(self.crop_rgb565(x,y,w,h)), w, h)
|
|
if type(data) is str:
|
|
Image.save(_img, data, **kwargs)
|
|
return _img
|
|
|
|
def get_brightness(self):
|
|
return self._backlight() / 100
|
|
|
|
def set_brightness(self, brightness):
|
|
if not 0.0 <= brightness <= 1.0:
|
|
raise ValueError(
|
|
"Brightness must be a decimal number in the range: 0.0~1.0")
|
|
self._backlight(int(brightness * 100))
|
|
|
|
def color(self, red, green=None, blue=None):
|
|
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
|
if green is None or blue is None:
|
|
return red
|
|
else:
|
|
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
|
|
|
def show(self):
|
|
"""Refresh the display and show the changes."""
|
|
self._write(0x2C, self._buffer)
|
|
if self._oneclight:
|
|
self._oneclight = False
|
|
for i in range(60): #slow down display
|
|
self.set_brightness(i / 100)
|
|
time.sleep_ms(5)
|