Last active
July 17, 2025 12:32
-
-
Save georgelviv/ce324a3385e3fc211bceaf51b53bfa34 to your computer and use it in GitHub Desktop.
Python lib for ST7735 display 128x160 driven by SPI for RPI5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Based on https://github.com/pimoroni/st7735-python/blob/main/st7735/__init__.py | |
| import numbers | |
| import time | |
| from gpiozero import OutputDevice | |
| import numpy as np | |
| import spidev | |
| ST7735_NOP = 0x00 | |
| ST7735_SWRESET = 0x01 | |
| ST7735_RDDID = 0x04 | |
| ST7735_RDDST = 0x09 | |
| ST7735_SLPIN = 0x10 | |
| ST7735_SLPOUT = 0x11 | |
| ST7735_PTLON = 0x12 | |
| ST7735_NORON = 0x13 | |
| ST7735_INVOFF = 0x20 | |
| ST7735_INVON = 0x21 | |
| ST7735_DISPOFF = 0x28 | |
| ST7735_DISPON = 0x29 | |
| ST7735_CASET = 0x2A | |
| ST7735_RASET = 0x2B | |
| ST7735_RAMWR = 0x2C | |
| ST7735_RAMRD = 0x2E | |
| ST7735_PTLAR = 0x30 | |
| ST7735_MADCTL = 0x36 | |
| ST7735_COLMOD = 0x3A | |
| ST7735_FRMCTR1 = 0xB1 | |
| ST7735_FRMCTR2 = 0xB2 | |
| ST7735_FRMCTR3 = 0xB3 | |
| ST7735_INVCTR = 0xB4 | |
| ST7735_DISSET5 = 0xB6 | |
| ST7735_PWCTR1 = 0xC0 | |
| ST7735_PWCTR2 = 0xC1 | |
| ST7735_PWCTR3 = 0xC2 | |
| ST7735_PWCTR4 = 0xC3 | |
| ST7735_PWCTR5 = 0xC4 | |
| ST7735_VMCTR1 = 0xC5 | |
| ST7735_RDID1 = 0xDA | |
| ST7735_RDID2 = 0xDB | |
| ST7735_RDID3 = 0xDC | |
| ST7735_RDID4 = 0xDD | |
| ST7735_GMCTRP1 = 0xE0 | |
| ST7735_GMCTRN1 = 0xE1 | |
| ST7735_PWCTR6 = 0xFC | |
| # Colours for convenience | |
| ST7735_BLACK = 0x0000 # 0b 00000 000000 00000 | |
| ST7735_BLUE = 0x001F # 0b 00000 000000 11111 | |
| ST7735_GREEN = 0x07E0 # 0b 00000 111111 00000 | |
| ST7735_RED = 0xF800 # 0b 11111 000000 00000 | |
| ST7735_CYAN = 0x07FF # 0b 00000 111111 11111 | |
| ST7735_MAGENTA = 0xF81F # 0b 11111 000000 11111 | |
| ST7735_YELLOW = 0xFFE0 # 0b 11111 111111 00000 | |
| ST7735_WHITE = 0xFFFF # 0b 11111 111111 11111 | |
| class ST7735(object): | |
| CS = 0 | |
| PORT = 0 | |
| DC_PIN = 23 | |
| RST_PIN = 24 | |
| WIDTH = 128 | |
| HEIGHT = 160 | |
| def __init__(self, rotation=0, spi_speed_hz=4000000): | |
| self._spi = spidev.SpiDev(self.PORT, self.CS) | |
| self._spi.mode = 0 | |
| self._spi.lsbfirst = False | |
| self._spi.max_speed_hz = spi_speed_hz | |
| self._rotation = rotation | |
| self._bl = None | |
| self._rst = None | |
| # Set DC as output. | |
| self._dc = OutputDevice(self.DC_PIN) | |
| self._rst = OutputDevice(self.RST_PIN) | |
| self.reset() | |
| self._init() | |
| def send(self, data, is_data=True): | |
| if is_data: | |
| self._dc.on() | |
| else: | |
| self._dc.off() | |
| if isinstance(data, numbers.Number): | |
| data = [data & 0xFF] | |
| self._spi.xfer3(data) | |
| def display_off(self): | |
| self.command(ST7735_DISPOFF) | |
| def display_on(self): | |
| self.command(ST7735_DISPON) | |
| def sleep(self): | |
| self.command(ST7735_SLPIN) | |
| def wake(self): | |
| self.command(ST7735_SLPOUT) | |
| def command(self, data): | |
| """Write a byte or array of bytes to the display as command data.""" | |
| self.send(data, False) | |
| def data(self, data): | |
| """Write a byte or array of bytes to the display as display data.""" | |
| self.send(data, True) | |
| def reset(self): | |
| """Reset the display, if reset pin is connected.""" | |
| self._rst.on() | |
| time.sleep(0.500) | |
| self._rst.off() | |
| time.sleep(0.500) | |
| self._rst.on() | |
| time.sleep(0.500) | |
| def _init(self): | |
| # Initialize the display. | |
| self.command(ST7735_SWRESET) # Software reset | |
| time.sleep(0.150) # delay 150 ms | |
| self.command(ST7735_SLPOUT) # Out of sleep mode | |
| time.sleep(0.500) # delay 500 ms | |
| self.command(ST7735_FRMCTR1) # Frame rate ctrl - normal mode | |
| self.data(0x01) # Rate = fosc/(1x2+40) * (LINE+2C+2D) | |
| self.data(0x2C) | |
| self.data(0x2D) | |
| self.command(ST7735_FRMCTR2) # Frame rate ctrl - idle mode | |
| self.data(0x01) # Rate = fosc/(1x2+40) * (LINE+2C+2D) | |
| self.data(0x2C) | |
| self.data(0x2D) | |
| self.command(ST7735_FRMCTR3) # Frame rate ctrl - partial mode | |
| self.data(0x01) # Dot inversion mode | |
| self.data(0x2C) | |
| self.data(0x2D) | |
| self.data(0x01) # Line inversion mode | |
| self.data(0x2C) | |
| self.data(0x2D) | |
| self.command(ST7735_INVCTR) # Display inversion ctrl | |
| self.data(0x07) # No inversion | |
| self.command(ST7735_PWCTR1) # Power control | |
| self.data(0xA2) | |
| self.data(0x02) # -4.6V | |
| self.data(0x84) # auto mode | |
| self.command(ST7735_PWCTR2) # Power control | |
| self.data(0x0A) # Opamp current small | |
| self.data(0x00) # Boost frequency | |
| self.command(ST7735_PWCTR4) # Power control | |
| # BCLK/2, Opamp current small & Medium low | |
| self.data(0x8A) | |
| self.data(0x2A) | |
| self.command(ST7735_PWCTR5) # Power control | |
| self.data(0x8A) | |
| self.data(0xEE) | |
| self.command(ST7735_VMCTR1) # Power control | |
| self.data(0x0E) | |
| self.command(ST7735_INVOFF) # Don't invert display | |
| self.command(ST7735_MADCTL) # Memory access control (directions) | |
| self.data(0xC0) | |
| self.command(ST7735_COLMOD) # set color mode | |
| self.data(0x05) # 16-bit color | |
| self.command(ST7735_CASET) # Column addr set | |
| self.data(0x00) # XSTART = 0 | |
| self.data(0x00) | |
| self.data(0x00) # XEND = ROWS - height | |
| self.data(self.WIDTH - 1) | |
| self.command(ST7735_RASET) # Row addr set | |
| self.data(0x00) # XSTART = 0 | |
| self.data(0x00) | |
| self.data(0x00) # XEND = COLS - width | |
| self.data(self.HEIGHT - 1) | |
| self.command(ST7735_GMCTRP1) # Set Gamma | |
| self.data(0x02) | |
| self.data(0x1c) | |
| self.data(0x07) | |
| self.data(0x12) | |
| self.data(0x37) | |
| self.data(0x32) | |
| self.data(0x29) | |
| self.data(0x2d) | |
| self.data(0x29) | |
| self.data(0x25) | |
| self.data(0x2B) | |
| self.data(0x39) | |
| self.data(0x00) | |
| self.data(0x01) | |
| self.data(0x03) | |
| self.data(0x10) | |
| self.command(ST7735_GMCTRN1) # Set Gamma | |
| self.data(0x03) | |
| self.data(0x1d) | |
| self.data(0x07) | |
| self.data(0x06) | |
| self.data(0x2E) | |
| self.data(0x2C) | |
| self.data(0x29) | |
| self.data(0x2D) | |
| self.data(0x2E) | |
| self.data(0x2E) | |
| self.data(0x37) | |
| self.data(0x3F) | |
| self.data(0x00) | |
| self.data(0x00) | |
| self.data(0x02) | |
| self.data(0x10) | |
| self.command(ST7735_NORON) # Normal display on | |
| time.sleep(0.10) # 10 ms | |
| self.display_on() | |
| time.sleep(0.100) # 100 ms | |
| def set_window(self): | |
| y0 = 0 | |
| x0 = 0 | |
| x1 = self.WIDTH - 1 | |
| y1 = self.HEIGHT - 1 | |
| self.command(ST7735_CASET) # Column addr set | |
| self.data(x0 >> 8) | |
| self.data(x0) # XSTART | |
| self.data(x1 >> 8) | |
| self.data(x1) # XEND | |
| self.command(ST7735_RASET) # Row addr set | |
| self.data(y0 >> 8) | |
| self.data(y0) # YSTART | |
| self.data(y1 >> 8) | |
| self.data(y1) # YEND | |
| self.command(ST7735_RAMWR) # write to RAM | |
| def display(self, image): | |
| self.set_window() | |
| pixelbytes = list(self.image_to_data(image, self._rotation)) | |
| self.data(pixelbytes) | |
| def image_to_data(self, image, rotation=0): | |
| pb = np.rot90(np.array(image.convert('RGB')), | |
| rotation // 90).astype('uint16') | |
| color = ((pb[:, :, 0] & 0xF8) << 8) | ( | |
| (pb[:, :, 1] & 0xFC) << 3) | (pb[:, :, 2] >> 3) | |
| return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment