ESP32-H2-DevKitM-1-N4/CircuitPython display on WaveShare 3.5 inch ST7796S SPI LCD

ESP32-H2-DevKitM-1-N4/CircuitPython display on WaveShare 3.5 inch ST7796S SPI LCD.



cpyH2_ST7796.py, color test and simple text.
"""
ESP32-H2-DevKitM-1-N4/CircuitPython
display on WaveShare 3.5 inch ST7796S SPI LCD

Connection:

VCC     3.3V
3V3     No Connection
GND     GND
MISO    IO3
MOSI    IO5
SCLK    IO4
SD_CS   IO2
LCD_CS  IO1
LCD_DC  IO0
LCD_RST IO10
LCD_BL  IO11
TP_SDA
TP_SCL
TP_INT
TP_RST
"""

import os, sys
import time
import board
import displayio
import busio
import fourwire
import busdisplay
from adafruit_display_text import label
import terminalio

spi_mosi = board.IO5
spi_sclk = board.IO4
sd_cs    = board.IO2
lcd_cs   = board.IO1
lcd_dc   = board.IO0
lcd_rst  = board.IO10
lcd_bl   = board.IO11

DISPLAY_width = 480
DISPLAY_height = 320

ST7796_INIT_SEQUENCE = (
    b"\x01\x80\x96"  # _SWRESET and Delay 150ms

    b"\x11\x80\x78"  # SLPOUT
    b"\x36\x01\x48"  # b"\x36\x01\x08"  # MADCTL
    b"\x3A\x01\x05"  #COLMOD
    b"\xF0\x01\xC3"  # CSCON enable command 2 part I
    b"\xF0\x01\x96"  # CSCON enable command 2 part II
    b"\xB4\x01\x01"  # DIC (Display Inversion Control) - 1 dot inversion
    b"\xB7\x01\xC6"  # EM (Entry mode Set)
    b"\xC0\x02\x80\x45"  # PWR1(Power Control 1)
    b"\xC1\x01\x13"  # PWR2(Power Control 2)
    b"\xC2\x01\xA7"  # PWR3(Power Control 3
    b"\xC5\x01\x0A"  # VCMPCTL (VCOM Control)
    b"\xE8\x08\x40\x8A\x00\x00\x29\x19\xA5\x33" # DOCA (Display Output Ctrl Adjust)
    b"\xE0\x0E\xD0\x08\x0F\x06\x06\x33\x30\x33\x47\x17\x13\x13\x2B\x31" # PGC (Positive Gamma Control)
    b"\xE1\x0E\xD0\x0A\x11\x0B\x09\x07\x2F\x33\x47\x38\x15\x16\x2C\x32" # NGC (Negative Gamma Control)
    b"\xF0\x01\x3C"     # CSCON disable command 2 part I
    b"\xF0\x81\x69\x78" # CSCON disable command 2 part II, then delay 120ms
    b"\x21\x00" # INVON (Display Inversion On)
    b"\x29\x00" # DISPON (Display On)
)

sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
                "\nrun on " + os.uname()[4] +\
                "\nusing " + busdisplay.BusDisplay.__name__
print("=========================================")
print(sys_info_text)
print("=========================================")

# === init LCD ===
# Release any resources currently in use for the displays
displayio.release_displays()

spi = busio.SPI(clock=spi_sclk, MOSI=spi_mosi)

display_bus = fourwire.FourWire(spi_bus=spi,
                                command=lcd_dc,
                                chip_select=lcd_cs,
                                reset=lcd_rst)

display = busdisplay.BusDisplay(display_bus,
                                ST7796_INIT_SEQUENCE,
                                width=DISPLAY_width,
                                height=DISPLAY_height,
                                backlight_pin=lcd_bl,
                                rotation=90)

# Make the display context
bgGroup = displayio.Group()
display.root_group = bgGroup

bg_bitmap = displayio.Bitmap(display.width, display.height, 1)  # with one color
bg_palette = displayio.Palette(1)
bg_palette[0] = 0xA0A0A0  # light-gray
bg_sprite = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
bgGroup.append(bg_sprite)

color_bitmap = displayio.Bitmap(display.width-10, display.height-10, 1)  # with one color
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000  # BLACK
color_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=5, y=5)
bgGroup.append(color_sprite)

color_text_group = displayio.Group(scale=3, x=20, y=120)
color_text_area = label.Label(terminalio.FONT, text="", color=0xFFFFFF)
color_text_group.append(color_text_area)
bgGroup.append(color_text_group)

colorSet = ((0xFF0000, "RED"),
            (0x00FF00, "GREEN"),
            (0x0000FF, "BLUE"),
            (0xFFFFFF, "WHITE"),
            (0x000000, "BLACK"))

# Color Test
time.sleep(0.5)
for i in colorSet:
    time.sleep(2)
    color_palette[0] = i[0]
    color_text_area.text = i[1]
    color_text_area.color = i[0] ^ 0xFFFFFF

time.sleep(0.5)
bgGroup.remove(color_text_group)

# scrolling text
# ref:
# https://learn.adafruit.com/rgb-led-matrices-matrix-panels-with-circuitpython/example-simple-two-line-text-scroller
def scroll(line):
    line.x = line.x - 1
    line_width = line.bounding_box[2]
    if line.x < -line_width:
        line.x = display.width
        
def reverse_scroll(line):
    line.x = line.x + 1
    line_width = line.bounding_box[2]
    if line.x >= display.width:
        line.x = -line_width

# Scrolling text

sys_info_group = displayio.Group(scale=2, x=0, y=20)
sys_info_area = label.Label(terminalio.FONT, text=sys_info_text, color=0xFFFFFF)
sys_info_group.append(sys_info_area)
bgGroup.append(sys_info_group)

info1_text = "coXXect.blogspot.com"
info1_scale = 3
info1_area = label.Label(terminalio.FONT, text=info1_text, color=0xFFFF00)

# Measure text width
text_width = info1_area.bounding_box[2]  # bounding_box = (x, y, width, height)

# Assume display is your display object
center_x = (display.width - text_width * info1_scale) // 2  # scale factor = 3

# Create group with centered x
info1_group = displayio.Group(scale=info1_scale, x=center_x, y=220)
info1_group.append(info1_area)
bgGroup.append(info1_group)

while True:
    scroll(sys_info_area)
    display.refresh(minimum_frames_per_second=0)


cpyH2_ST7796_stripes.py, display stripes.
"""
ESP32-H2-DevKitM-1-N4/CircuitPython
display on WaveShare 3.5 inch ST7796S SPI LCD

"""

import os, sys
import time
import board
import displayio
import busio
import fourwire
import busdisplay
from adafruit_display_text import label
import terminalio

spi_mosi = board.IO5
spi_sclk = board.IO4
sd_cs    = board.IO2
lcd_cs   = board.IO1
lcd_dc   = board.IO0
lcd_rst  = board.IO10
lcd_bl   = board.IO11

DISPLAY_width = 320
DISPLAY_height = 480
DISPLAY_ROT = 0
"""
DISPLAY_width = 480
DISPLAY_height = 320
DISPLAY_ROT = 90
"""
ST7796_INIT_SEQUENCE = (
    b"\x01\x80\x96"  # _SWRESET and Delay 150ms

    b"\x11\x80\x78"  # SLPOUT
    b"\x36\x01\x48"  # b"\x36\x01\x08"  # MADCTL
    b"\x3A\x01\x05"  #COLMOD
    b"\xF0\x01\xC3"  # CSCON enable command 2 part I
    b"\xF0\x01\x96"  # CSCON enable command 2 part II
    b"\xB4\x01\x01"  # DIC (Display Inversion Control) - 1 dot inversion
    b"\xB7\x01\xC6"  # EM (Entry mode Set)
    b"\xC0\x02\x80\x45"  # PWR1(Power Control 1)
    b"\xC1\x01\x13"  # PWR2(Power Control 2)
    b"\xC2\x01\xA7"  # PWR3(Power Control 3
    b"\xC5\x01\x0A"  # VCMPCTL (VCOM Control)
    b"\xE8\x08\x40\x8A\x00\x00\x29\x19\xA5\x33" # DOCA (Display Output Ctrl Adjust)
    b"\xE0\x0E\xD0\x08\x0F\x06\x06\x33\x30\x33\x47\x17\x13\x13\x2B\x31" # PGC (Positive Gamma Control)
    b"\xE1\x0E\xD0\x0A\x11\x0B\x09\x07\x2F\x33\x47\x38\x15\x16\x2C\x32" # NGC (Negative Gamma Control)
    b"\xF0\x01\x3C"     # CSCON disable command 2 part I
    b"\xF0\x81\x69\x78" # CSCON disable command 2 part II, then delay 120ms
    b"\x21\x00" # INVON (Display Inversion On)
    b"\x29\x00" # DISPON (Display On)
)

sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
                "\nrun on " + os.uname()[4] +\
                "\nusing " + busdisplay.BusDisplay.__name__
print("=========================================")
print(sys_info_text)
print("=========================================")

# === init LCD ===
# Release any resources currently in use for the displays
displayio.release_displays()

spi = busio.SPI(clock=spi_sclk, MOSI=spi_mosi)

display_bus = fourwire.FourWire(spi_bus=spi,
                                command=lcd_dc,
                                chip_select=lcd_cs,
                                reset=lcd_rst)

display = busdisplay.BusDisplay(display_bus,
                                ST7796_INIT_SEQUENCE,
                                width=DISPLAY_width,
                                height=DISPLAY_height,
                                backlight_pin=lcd_bl,
                                rotation=DISPLAY_ROT)

# Make the display context
bgGroup = displayio.Group()
display.root_group = bgGroup

colors = [0x000000, 0x808080]  # BLACK and WHITE

print("display.width: ", display.width)
print("display.height:", display.height)
bg_bitmap = displayio.Bitmap(display.width, display.height, 2)  # with two color
bg_palette = displayio.Palette(2)
bg_palette[0] = colors[0]
bg_palette[1] = colors[1]
bg_sprite = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
bgGroup.append(bg_sprite)

# Create label
info1_text = "@coXXect"
info1_area = label.Label(terminalio.FONT, text=info1_text, color=0xFFFFFF)

# Get text size
text_width, text_height = info1_area.bounding_box[2], info1_area.bounding_box[3]

# Set scale
scale = 3
scaled_width = text_width * scale
scaled_height = text_height * scale

# Get display size
display_width = display.width
display_height = display.height

# Calculate centered position
center_x = (display_width - scaled_width) // 2
center_y = (display_height - scaled_height) // 2

# Create group and add label
info1_group = displayio.Group(scale=scale, x=center_x, y=center_y)
info1_group.append(info1_area)
bgGroup.append(info1_group)

def fill_hori_strips(strips_wide):
    for x in range(display.width):
        color_index = (x // strips_wide) % 2  # Alternate every strips_wide pixels
        for y in range(display.height):
            bg_bitmap[x, y] = color_index
            
def fill_vert_strips(strips_wide):
    for y in range(display.height):
        color_index = (y // strips_wide) % 2  # Alternate every strips_wide pixels
        for x in range(display.width):
            bg_bitmap[x, y] = color_index

fill_vert_strips(10)
fill_vert_strips(25)
fill_vert_strips(50)
fill_hori_strips(50)
fill_hori_strips(25)
fill_hori_strips(10)
fill_hori_strips(5)

print("~ bye ~")


Related: ~ Use ST7796 SPI LCD on CircuitPython/Raspberry Pi Pico 2, by instancing BusDisplay object using custom init_sequence.

Comments

Popular posts from this blog

Drive 320x240 ILI9341 SPI TFT using ESP32-S3 (NodeMCU ESP-S3-12K-Kit) using TFT_eSPI library, in Arduino Framework.

480x320 TFT/ILI9488 SPI wih EP32C3 (arduino-esp32) using Arduino_GFX Library