Use ST7796 SPI LCD on CircuitPython/Raspberry Pi Pico 2, by instancing BusDisplay object using custom init_sequence.
Currently, it's no ST7796 driver for CircuitPython. So I create ST7796 display
by instancing object of busdisplay.BusDisplay with custom
init_sequence(ST7796_INIT_SEQUENCE). Tested on
WaveShare "3.5 inch 320×480 Capacitive Touch LCD", embedded with ST7796S
driver chip and FT6336U capacitive touch control chip, with
Raspberry Pi Pico 2
running CircuitPython 9.2.4.
For the init_sequence, I reference the
MicroPython demo of Working with Raspberry Pi Pico in WaveShare wiki, with a little bit modification. Exactly ONE bit: (D6 MX/Column
Address Order) on MADCTL (36h), to flip left/right. (refer
ST7796S Datasheet)
In following exercises, various various function of the ST7796
display module was tested, include:
- Display area, color test.
(cpy_pico2_st7796_BusDisplay.py)
- Touch function of FT6336U capacitive
touch drive.(cpy_pico2_st7796_BusDisplay_FT6336.py).
- display bmp image
(from CIRCUITPY device/SD) using adafruit_imageload.
(cpy_pico2_st7796_BusDisplay_sd_imageload.py)
- and the final exercise,
cpy_pico2_st7796_BusDisplay_sd_imageload_touch.py, test all three part ST7796
LCD, FT6336U capacitive touch driver and SD Card reader
(cpy_pico2_st7796_BusDisplay_sd_imageload_touch.py)
Connection:
Connection:
Waveshare Raspberry Pi
320×480 Pico 2
ST7796 SPI
w/ FT6336U
-------------------------
VCC 3.3V
3V3 No Connection
GND GND
MISO GP0
MOSI GP3
SCLK GP2
SD_CS GP4
LCD_CS GP1
LCD_DC GP5
LCD_RST GP6
LCD_BL GP7
TP_SDA GP8
TP_SCL GP9
TP_INT GP10
TP_RST GP11
Libraries:
To install all lib using circup:
circup install adafruit_display_text adafruit_focaltouch adafruit_cursorcontrol adafruit_imageload
About circup, read "Install and using CircUp (CircuitPython library updater) to install
CircuitPython libraries".Test images:
All test images shown in the video were generated using MicroSoft "Image Creator in Bing", not real. Converted to 240x240 RGB888 bmp using py_cv_batch_resize_RGB888.py in "Resize jpg and convert to bmp in RGB888 and RGB565 mode, using Python/GIMP", save to "images" folder in MicroSD and CIRCUITPY device.
Exercises code:
cpy_pico2_st7796_BusDisplay.py
"""
Raspberry Pi Pico 2/CircuitPython 9
to display on Waveshare 3.5" 320x480 ST7796 SPI IPS
Hello World with color test.
Currently, it's no ST7796 driver for CircuitPython.
So I create ST7796 display by creating an instance of busdisplay.BusDisplay
with custom init_sequence(ST7796_INIT_SEQUENCE).
Libraries need to install:
adafruit_display_text
install with circup:
circup install adafruit_display_text
"""
import os, sys
import board
import busio
import displayio
import terminalio
from adafruit_display_text import label
import time
import busdisplay
spi_miso = board.GP0
spi_sck = board.GP2
spi_mosi = board.GP3
disp_res = board.GP6
disp_dc = board.GP5
disp_cs = board.GP1
disp_blk = board.GP7
DISPLAY_width = 320
DISPLAY_height = 480
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)
)
# Release any resources currently in use for the displays
displayio.release_displays()
disp_spi = busio.SPI(clock=spi_sck, MOSI=spi_mosi)
display_bus = displayio.FourWire(spi_bus=disp_spi,
command=disp_dc,
chip_select=disp_cs,
reset=disp_res)
"""
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=DISPLAY_width,
height=DISPLAY_height,
backlight_pin=disp_blk,
rotation=0)
"""
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=DISPLAY_height,
height=DISPLAY_width,
backlight_pin=disp_blk,
rotation=90)
sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
"\nrun on " + os.uname()[4] +\
"\nusing " + busdisplay.BusDisplay.__name__
print("=======================================")
print(sys_info_text)
print("=======================================")
print()
# 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] = 0xFFFFFF # White
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(2)
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=3, 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_group = displayio.Group(scale=2, x=0, y=220)
info1_text = "coXXect.blogspot.com"
info1_area = label.Label(terminalio.FONT, text=info1_text, color=0xFFFF00)
info1_group.append(info1_area)
bgGroup.append(info1_group)
#scroll_end = time.monotonic() + 30 # Scroll text for 15 second
#while time.monotonic() < scroll_end:
while True:
scroll(sys_info_area)
reverse_scroll(info1_area)
display.refresh(minimum_frames_per_second=0)
cpy_pico2_st7796_BusDisplay_FT6336.py
"""
Raspberry Pi Pico 2/CircuitPython 9
to display on Waveshare 3.5" 320x480 ST7796 SPI IPS
Touch test, with curcor displayed.
To set rotation, screen width/height, and touch x/y have to be adjusted accordingly.
So I implement rot_setting[] and rot_set to handle them.
To set rotation, set rot_set instead.
Libraries need to install:
adafruit_display_text
adafruit_focaltouch
adafruit_cursorcontrol
install with circup:
circup install adafruit_display_text adafruit_focaltouch adafruit_cursorcontrol
"""
import os, sys
import board
import busio
import displayio
import terminalio
from adafruit_display_text import label
import time
import busdisplay
from digitalio import DigitalInOut, Direction
import adafruit_focaltouch
import adafruit_cursorcontrol.cursorcontrol
spi_miso = board.GP0
spi_sck = board.GP2
spi_mosi = board.GP3
disp_res = board.GP6
disp_dc = board.GP5
disp_cs = board.GP1
disp_blk = board.GP7
#Connection to FT6336U
TOUCH_SDA = board.GP8
TOUCH_SCL = board.GP9
TOUCH_INT = board.GP10
TOUCH_RST = board.GP11
DISPLAY_width = 320
DISPLAY_height = 480
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)
)
# Release any resources currently in use for the displays
displayio.release_displays()
touch_irq = DigitalInOut(TOUCH_INT)
touch_irq.direction = Direction.INPUT
touch_res = DigitalInOut(TOUCH_RST)
touch_res.direction = Direction.OUTPUT
touch_res.value = True
time.sleep(0.1)
touch_res.value = False
time.sleep(0.1)
touch_res.value = True
time.sleep(0.5)
disp_spi = busio.SPI(clock=spi_sck, MOSI=spi_mosi, MISO=spi_miso)
display_bus = displayio.FourWire(spi_bus=disp_spi,
command=disp_dc,
chip_select=disp_cs,
reset=disp_res)
# rot_setting is used to better manager display width/height, touch x/y adjust
# for rotation setting.
# elements in rot_setting[] set according to rotation, set in rot_set
# rotation: pass to BusDisplay
# width : pass to
# height: pass to BusDisplay
# exchange x/y in touch
# inverse x in touch
# inverse y in touch
rot_setting = [[0, DISPLAY_width, DISPLAY_height, False, False, False],
[90, DISPLAY_height, DISPLAY_width, True, False, True],
[180, DISPLAY_width, DISPLAY_height, False, True, True],
[270, DISPLAY_height, DISPLAY_width, True, True, False]]
# rot_set set rotation
# 0 - 0
# 1 - 90
# 2 - 180
# 3 - 279
rot_set = 0
print("--- rot_setting ---")
print("rot_set\t\t", rot_set)
print("rotation:\t", rot_setting[rot_set][0])
print("width:\t\t", rot_setting[rot_set][1])
print("height:\t\t", rot_setting[rot_set][2])
print("exchange xy:\t", rot_setting[rot_set][3])
print("reverse x:\t", rot_setting[rot_set][4])
print("reverse x:\t", rot_setting[rot_set][5])
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=rot_setting[rot_set][1],
height=rot_setting[rot_set][2],
backlight_pin=disp_blk,
rotation=rot_setting[rot_set][0])
touch_i2c = busio.I2C(TOUCH_SCL, TOUCH_SDA)
ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False, irq_pin=touch_irq)
sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
"\nrun on " + os.uname()[4] +\
"\nusing " + busdisplay.BusDisplay.__name__ +\
"\n" + adafruit_focaltouch.__name__ + " " + adafruit_focaltouch.__version__ +\
"\n" + adafruit_cursorcontrol.cursorcontrol.__name__ + " " + adafruit_cursorcontrol.cursorcontrol.__version__
print("=======================================")
print(sys_info_text)
print("=======================================")
print()
# 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] = 0xFFFFFF # White
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)
# place a label on screen center
text_area = label.Label(terminalio.FONT, text="coXXect.blogspot.com", scale=2, color=0xFFFFFF)
text_area_width = text_area.bounding_box[2]*text_area.scale
text_area_height = text_area.bounding_box[3]*text_area.scale
text_area.x = int((display.width - text_area_width)/2)
text_area.y = int((display.height - text_area_height)/2)
bgGroup.append(text_area)
# Draw labels to display touch x/y
x_group = displayio.Group(scale=2, x=10, y=20)
x_text = "---"
x_area = label.Label(terminalio.FONT, text=x_text, color=0xFFFFFF)
x_group.append(x_area)
bgGroup.append(x_group)
y_group = displayio.Group(scale=2, x=10, y=40)
y_text = "---"
y_area = label.Label(terminalio.FONT, text=y_text, color=0xFFFFFF)
y_group.append(y_area)
bgGroup.append(y_group)
# initialize the mouse cursor object
# place over all others
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
display, display_group=bgGroup)
mouse_cursor.x = int(display.width/2)
mouse_cursor.y = int(display.height/2)
while True:
# if the screen is being touched print the touches
if ft.touched:
touches = ft.touches
#sometimes ft.touches is [], empty!
#so I check len to prevent IndexError: index out of range
if len(touches)>0:
if rot_setting[rot_set][3]:
x = touches[0]['y'] # exchange x/y
y = touches[0]['x']
else:
x = touches[0]['x'] # keep no exchange
y = touches[0]['y']
if rot_setting[rot_set][4]:
x = display.width - x # reverse x
if rot_setting[rot_set][5]:
y = display.height - y # reverse y
mouse_cursor.x = x
mouse_cursor.y = y
x_area.text = str(x)
y_area.text = str(y)
else:
print('no touch')
time.sleep(.3)
cpy_pico2_st7796_BusDisplay_sd_imageload.py
"""
Raspberry Pi Pico 2/CircuitPython 9
to display on Waveshare 3.5" 320x480 ST7796 SPI IPS
Display bmp images (from sd/device 'images' folder) using adafruit_imageload.
Auto switch images.
Libraries need to install:
adafruit_imageload
install with circup:
circup install adafruit_imageload
"""
import os, sys
import board
import busio
import displayio
import terminalio
import time
import busdisplay
import sdcardio
import storage
import adafruit_imageload
import gc
spi_miso = board.GP0
spi_sck = board.GP2
spi_mosi = board.GP3
disp_res = board.GP6
disp_dc = board.GP5
disp_cs = board.GP1
disp_blk = board.GP7
sd_cs = board.GP4
DISPLAY_width = 320
DISPLAY_height = 480
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)
)
# Release any resources currently in use for the displays
displayio.release_displays()
share_spi = busio.SPI(clock=spi_sck, MOSI=spi_mosi, MISO=spi_miso)
"""
Try to increase the speed of spi
Found that it limit to: share_spi.frequency: 37500000
and no significant improvement overall.
"""
share_spi.try_lock()
share_spi.configure(baudrate=40000000)
share_spi.unlock()
print("share_spi.frequency:", share_spi.frequency)
rot_setting = [[0, DISPLAY_width, DISPLAY_height, False, False, False],
[90, DISPLAY_height, DISPLAY_width, True, False, True],
[180, DISPLAY_width, DISPLAY_height, False, True, True],
[270, DISPLAY_height, DISPLAY_width, True, True, False]]
rot_set = 1
display_bus = displayio.FourWire(spi_bus=share_spi,
command=disp_dc,
chip_select=disp_cs,
reset=disp_res)
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=rot_setting[rot_set][1],
height=rot_setting[rot_set][2],
backlight_pin=disp_blk,
rotation=rot_setting[rot_set][0])
# init SD Card
sd = sdcardio.SDCard(spi=share_spi,
cs=sd_cs)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
#images_folder = '/sd/images/' # load images from sd card, 'images' folder
images_folder = '/images/' # load images from CircuitPython device, 'images' folder
files = os.listdir(images_folder)
bmp_files = [file for file in files if file.endswith('.bmp')]
bmp_file_list = sorted(bmp_files)
for f in bmp_file_list:
print(images_folder + f)
sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
"\nrun on " + os.uname()[4] +\
"\nusing " + busdisplay.BusDisplay.__name__
print("=======================================")
print(sys_info_text)
print("=======================================")
print()
# Create a dummy bitmap
dummy_bitmap = displayio.Bitmap(240, 240, 1)
dummy_palette = displayio.Palette(1)
dummy_palette[0] = 0x000000
bmpTileGrid = displayio.TileGrid(dummy_bitmap, pixel_shader=dummy_palette)
bmpTileGrid.x = (display.width-240)//2
bmpTileGrid.y = (display.height-240)//2
group = displayio.Group()
group.append(bmpTileGrid)
display.root_group = group
# remark: my Python code converting RGB565
# not work for adafruit_imageload.
def update_images(path_to_bmp):
gc.collect()
# using adafruit_imageload
image, palette = adafruit_imageload.load(
path_to_bmp, bitmap=displayio.Bitmap, palette=displayio.Palette)
bmpTileGrid.bitmap = image
bmpTileGrid.pixel_shader = palette
#display.refresh() # for display.auto_refresh = False
counter = 1
while True:
print("======== Loop Start " + str(counter) + " ========")
tick_ms_start = time.monotonic()
for f in bmp_file_list:
update_images(images_folder+f)
tick_ms_end = time.monotonic()
print("--- Loop End ---")
print("Time for one loop:",
tick_ms_end-tick_ms_start,
"s")
counter = counter+1
while True:
pass
cpy_pico2_st7796_BusDisplay_sd_imageload_touch.py
"""
Raspberry Pi Pico 2/CircuitPython 9
to display on Waveshare 3.5" 320x480 ST7796 SPI IPS
Display bmp images (from sd/device 'images' folder) using adafruit_imageload.
Touch to switch images.
- Touch on left 1/3 to switch to previous image.
- Touch on right 1/3 to switch to next image.
This exercise test all three parts of Waveshare 3.5" 320x480 ST7796 SPI IPS:
screen, touch and sd card reader.
Libraries need to install:
adafruit_display_text
adafruit_imageload
adafruit_focaltouch
install with circup:
circup install adafruit_display_text adafruit_imageload adafruit_focaltouch
"""
import os, sys
import board
import busio
import displayio
import terminalio
from adafruit_display_text import label
import time
import busdisplay
import sdcardio
import storage
import adafruit_imageload
from digitalio import DigitalInOut, Direction
import adafruit_focaltouch
import gc
spi_miso = board.GP0
spi_sck = board.GP2
spi_mosi = board.GP3
disp_res = board.GP6
disp_dc = board.GP5
disp_cs = board.GP1
disp_blk = board.GP7
sd_cs = board.GP4
#Connection to FT6336U
TOUCH_SDA = board.GP8
TOUCH_SCL = board.GP9
TOUCH_INT = board.GP10
TOUCH_RST = board.GP11
DISPLAY_width = 320
DISPLAY_height = 480
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)
)
# Release any resources currently in use for the displays
displayio.release_displays()
touch_irq = DigitalInOut(TOUCH_INT)
touch_irq.direction = Direction.INPUT
touch_res = DigitalInOut(TOUCH_RST)
touch_res.direction = Direction.OUTPUT
touch_res.value = True
time.sleep(0.1)
touch_res.value = False
time.sleep(0.1)
touch_res.value = True
time.sleep(0.5)
share_spi = busio.SPI(clock=spi_sck, MOSI=spi_mosi, MISO=spi_miso)
rot_setting = [[0, DISPLAY_width, DISPLAY_height, False, False, False],
[90, DISPLAY_height, DISPLAY_width, True, False, True],
[180, DISPLAY_width, DISPLAY_height, False, True, True],
[270, DISPLAY_height, DISPLAY_width, True, True, False]]
rot_set = 1
display_bus = displayio.FourWire(spi_bus=share_spi,
command=disp_dc,
chip_select=disp_cs,
reset=disp_res)
display = busdisplay.BusDisplay(display_bus,
ST7796_INIT_SEQUENCE,
width=rot_setting[rot_set][1],
height=rot_setting[rot_set][2],
backlight_pin=disp_blk,
rotation=rot_setting[rot_set][0])
touch_i2c = busio.I2C(TOUCH_SCL, TOUCH_SDA)
ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False, irq_pin=touch_irq)
# init SD Card
sd = sdcardio.SDCard(spi=share_spi,
cs=sd_cs)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
#images_folder = '/sd/images/' # load images from sd card, 'images' folder
images_folder = '/images/' # load images from CircuitPython device, 'images' folder
files = os.listdir(images_folder)
bmp_files = [file for file in files if file.endswith('.bmp')]
bmp_file_list = sorted(bmp_files)
for f in bmp_file_list:
print(images_folder + f)
sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
"\nrun on " + os.uname()[4] +\
"\nusing " + busdisplay.BusDisplay.__name__
print("=======================================")
print(sys_info_text)
print("=======================================")
print()
group = displayio.Group()
# Create a dummy bitmap
dummy_bitmap = displayio.Bitmap(240, 240, 1)
dummy_palette = displayio.Palette(1)
dummy_palette[0] = 0x000000
bmpTileGrid = displayio.TileGrid(dummy_bitmap, pixel_shader=dummy_palette)
bmpTileGrid.x = (display.width-240)//2
bmpTileGrid.y = (display.height-240)//2
group.append(bmpTileGrid)
# place a label on screen center
text_area = label.Label(terminalio.FONT, text="", color=0xFFFFFF)
text_area.x = 10
text_area.y = 10
group.append(text_area)
display.root_group = group
# remark: my Python code converting RGB565
# not work for adafruit_imageload.
def update_images(path_to_bmp):
gc.collect()
# using adafruit_imageload
image, palette = adafruit_imageload.load(
path_to_bmp, bitmap=displayio.Bitmap, palette=displayio.Palette)
bmpTileGrid.bitmap = image
bmpTileGrid.pixel_shader = palette
#display.refresh() # for display.auto_refresh = False
image_index = 0
def wait_touch():
left_max = display.width//3
right_min = (display.width*2)//3
while True:
# if the screen is being touched print the touches
if ft.touched:
touches = ft.touches
#sometimes ft.touches is [], empty!
#so I check len to prevent IndexError: index out of range
if len(touches)>0:
if rot_setting[rot_set][3]:
x = touches[0]['y']
y = touches[0]['x']
else:
x = touches[0]['x']
y = touches[0]['y']
if rot_setting[rot_set][4]:
x = display.width - x
if rot_setting[rot_set][5]:
y = display.height - y
if x < left_max:
return -1
elif x > right_min:
return 1
else:
print('no touch')
time.sleep(.3)
while True:
image_full_path = images_folder+bmp_file_list[image_index]
text_area.text = image_full_path
text_area.scale=1
update_images(image_full_path)
text_area.scale=2
image_index = image_index+wait_touch()
if image_index==len(bmp_file_list):
image_index=0
if image_index==-1:
image_index=len(bmp_file_list)-1
Comments
Post a Comment