1.54" 320x320 ST7796 SPI IPS on Waveshare ESP32-H2-Zero/CircuitPython 10.0.3
1.54" 320x320 ST7796 SPI IPS
on
Waveshare ESP32-H2-Zero/CircuitPython 10.0.3
Currently, no official ST7796 library for CircuitPython, so we have to implement my custom ST7796_INIT_SEQUENCE and busdisplay.BusDisplay().
cpy_H2Zero_st7796_320x320.py, simple color test.
"""
Waveshare ESP32-H2-Zero/CircuitPython
display on 1.54 inch 320x320 ST7796 SPI IPS
320x320 ST7796 LCD ESP32-H2-Zero
-
BL -----+ +-----=======-----+
3V3 ---+ | |5V GPIO24|
GND ---|-|-------------|GND GPIO23|
+-|-------------|3V3 GPIO25|
+-------------|GPIO0 GPIO22|
CS -------------------|GPIO1 GPIO14|
SCK -------------------|GPIO2 GPIO13|
DC -------------------|GPIO3 GPIO12|
MOSI -------------------|GPIO4 GPIO11|
|GPIO5 GPIO10|
+-----------------+
CircuitPython Libraries Bundle for Version 10.x needed:
(https://circuitpython.org/libraries)
- adafruit_display_text folder
"""
import os, sys, board, time
import busdisplay
import displayio
import busio
import fourwire
from adafruit_display_text import label
import terminalio
TFT_MOSI = board.IO4
TFT_DC = board.IO3
TFT_SCK = board.IO2
TFT_CS = board.IO1
TFT_BL = board.IO0
DISPLAY_width = 320
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=TFT_SCK, MOSI=TFT_MOSI)
display_bus = fourwire.FourWire(spi_bus=spi,
command=TFT_DC,
chip_select=TFT_CS)
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=DISPLAY_width,
height=DISPLAY_height,
backlight_pin=TFT_BL)
# 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-2, display.height-2, 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=1, y=1)
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 = 2
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)
cpy_H2Zero_st7796_OnDiskBitmap.py, display .bmp in CircuitPython devices /images folder, using OnDiskBitmap.
"""
Waveshare ESP32-H2-Zero/CircuitPython
display on 1.54 inch 320x320 ST7796 SPI IPS
Display images in /images folder using displayio.OnDiskBitmap, in SlideShow form.
"""
import os, sys, board, time
import busdisplay
import displayio
import busio
import fourwire
import terminalio
TFT_MOSI = board.IO4
TFT_DC = board.IO3
TFT_SCK = board.IO2
TFT_CS = board.IO1
TFT_BL = board.IO0
DISPLAY_width = 320
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=TFT_SCK, MOSI=TFT_MOSI)
display_bus = fourwire.FourWire(spi_bus=spi,
command=TFT_DC,
chip_select=TFT_CS)
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=DISPLAY_width,
height=DISPLAY_height,
backlight_pin=TFT_BL)
# Make the display context
#images bmp stored in CIRCUITPY's /images/ folder
images_folder = "/images/"
images_file = ["image_001_320x320_rgb888.bmp",
"image_002_320x320_rgb888.bmp"]
# Create a dummy bitmap
dummy_bitmap = displayio.Bitmap(320, 320, 1)
dummy_palette = displayio.Palette(1)
dummy_palette[0] = 0x000000
bmpTileGrid = displayio.TileGrid(dummy_bitmap, pixel_shader=dummy_palette)
group = displayio.Group()
group.append(bmpTileGrid)
display.root_group = group
def fade_in():
for i in range(101):
display.brightness = 0.01 * i
time.sleep(0.01)
def fade_out():
for i in range(100, -1, -1):
display.brightness = 0.01 * i
time.sleep(0.01)
#fade_out()
def update_bmpTileGrid(path_to_bmp):
odb = displayio.OnDiskBitmap(path_to_bmp)
bmpTileGrid.bitmap = odb
bmpTileGrid.pixel_shader = odb.pixel_shader
display.refresh()
#fade_in()
#time.sleep(3)
#fade_out()
while True:
for f in images_file:
update_bmpTileGrid(images_folder+f)
while True:
pass
cpy_H2Zero_st7796_SD_OnDiskBitmap.py, display .bmp in /sd/images_bmp folder, using OnDiskBitmap.
"""
Waveshare ESP32-H2-Zero/CircuitPython
display on 1.54 inch 320x320 ST7796 SPI IPS
Display bmp in /sd/images_bmp folder using displayio.OnDiskBitmap.
LCD and SD Card module share the same spi.
320x320 ST7796 LCD ESP32-H2-Zero
-
BL ---------+ +-----=======-----+
3V3 -------+ | |5V GPIO24|
GND -------|-|---------|GND GPIO23|
+-|---------|3V3 GPIO25|
+---------|GPIO0 GPIO22|
CS -------------------|GPIO1 GPIO14|
SCK ----------+--------|GPIO2 GPIO13|
DC ----------|--------|GPIO3 GPIO12|
MOSI --------+-|--------|GPIO4 GPIO11|
| | +----|GPIO5 GPIO10| ----+
| | | +-----------------+ |
MicroSD | | | |
GND --- GND | | | |
VCC --- 5V | | | |
MISO --------|-|---+ |
MOSI --------+ | |
SCK ----------+ |
CS -------------------------------------------+
Notice: For my MicroSD Card module,
VCC: 4.5~5.5V
Data: 3V3/5V
"""
import os, sys, board, time
import busdisplay
import displayio
import busio
import fourwire
import terminalio
import sdcardio
import storage
SPI_MISO = board.IO5
SPI_MOSI = board.IO4
TFT_DC = board.IO3
SPI_SCK = board.IO2
TFT_CS = board.IO1
TFT_BL = board.IO0
SD_CS = board.IO10
DISPLAY_width = 320
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("=========================================")
# Release any resources currently in use for the displays
displayio.release_displays()
spi = busio.SPI(clock=SPI_SCK, MOSI=SPI_MOSI, MISO=SPI_MISO) # spi shared by LCD and SD Card module
# === SD card be initialized before display
sd = sdcardio.SDCard(spi=spi, cs=SD_CS)
# Test .bmp stored in "images_bmp" folder in MicroSD card.
storage.mount(storage.VfsFat(sd), '/sd')
images_folder = "/sd/images_bmp/"
# Collect all .bmp files into a list
images_file = sorted(
[f for f in os.listdir(images_folder) if f.lower().endswith(".bmp")]
)
# Print the list
for b in images_file:
print(b)
# === init LCD ===
display_bus = fourwire.FourWire(spi_bus=spi,
command=TFT_DC,
chip_select=TFT_CS)
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=DISPLAY_width,
height=DISPLAY_height,
backlight_pin=TFT_BL)
# Create a dummy bitmap
dummy_bitmap = displayio.Bitmap(320, 320, 1)
dummy_palette = displayio.Palette(1)
dummy_palette[0] = 0x000000
bmpTileGrid = displayio.TileGrid(dummy_bitmap, pixel_shader=dummy_palette)
group = displayio.Group()
group.append(bmpTileGrid)
display.root_group = group
#fade_out()
def update_bmpTileGrid(path_to_bmp):
print("display:", path_to_bmp)
odb = displayio.OnDiskBitmap(path_to_bmp)
bmpTileGrid.bitmap = odb
bmpTileGrid.pixel_shader = odb.pixel_shader
display.refresh()
while True:
for f in images_file:
update_bmpTileGrid(images_folder+f)
Comments
Post a Comment