Display bmp with XIAO ESP32S3 Sense/CircuitPython on GC9A01 Round LCD using OnDiskBitmap, adafruit_imageload and adafruit_slideshow

Previous exercise on "Seeed Studio XIAO ESP32S3 Sense/CircuitPython display on 1.28" 240x240 GC9A01 Round IPS LCD", it's another exercise to display bmp using OnDiskBitmap, adafruit_imageload and adafruit_slideshow.

Actually, it's ported from my previous exercises on Raspberry Pi Pico with 1.54" 240x240 ST7789 SPI IPS:
Raspberry Pi Pico 2/CircuitPython 9 display bmp on ST7789 LCD using adafruit_imageload/adafruit_slideshow
displayio.OnDiskBitmap on Pico 2 W/CircuitPython 9

Connection, same as in previous exercise.

All testing images were generated using "Image Creator in Bing", not real. Converted to 240x240 RGB888/RGB565 using Python.

The exercises need libraries gc9a01, adafruit_imageload and adafruit_slideshow. To install the libraries using circup:
circup install gc9a01, adafruit_imageload, adafruit_slideshow
To know how to install and use circup, read: https://coxxect.blogspot.com/2024/12/install-and-using-circup-circuitpython.html

Exercise Code:

cpy_XS3_gc9a01_sd_mount.py
"""
Color test on
Seeed Studio XIAO ESP32S3 Sense/CircuitPython 9.2.1
with 1.28" 240x240 Round GC9A01 SPI IPS LCD + MicroSD
(Share SPI between Display and SD)

Just mount sd, such that you can check MicroSD in Thonny 
"""
import board
import busio

import sdcardio
import storage
import displayio

# Release any resources currently in use for the displays, in case for displayio used before restart
displayio.release_displays()

# SPI shared by Display and SD
share_spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# === SD card be initialized before display
sd = sdcardio.SDCard(spi=share_spi,
                     cs=board.SDCS)

vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')


cpy_XS3_gc9a01_sd_OnDiskBitmap_imageload.py
"""
Color test on
Seeed Studio XIAO ESP32S3 Sense/CircuitPython 9.2.1
with 1.28" 240x240 Round GC9A01 SPI IPS LCD + MicroSD
(Share SPI between Display and SD)

Display bmp (stored in MicroSD) using OnDiskBitmap/adafruit_imageload

CircuitPython Libraries Bundle for Version 9.x needed:
(https://circuitpython.org/libraries)
- gc9a01.mpy
- adafruit_imageload folder

Notice that gc9a01.mpy is in Community Bundle (circuitpython-community-bundle-...),
not Adafruit Circuit Bundle (adafruit-circuitpython-bundle-...).

Share SPI between display and sd card, using sdcardio:

sdcardio – Interface to an SD card via the SPI bus
https://docs.circuitpython.org/en/latest/shared-bindings/sdcardio/index.html

sdcardio.SDCard - SD Card Block Interface
https://docs.circuitpython.org/en/latest/shared-bindings/sdcardio/index.html#sdcardio.SDCard
!Important
If the same SPI bus is shared with other peripherals,
it is important that the SD card be initialized before accessing any other peripheral on the bus.
Failure to do so can prevent the SD card from being recognized until it is powered off or re-inserted.
"""
import os, sys
import board
import time
import displayio
import busio
import terminalio
import adafruit_imageload

import sdcardio
import storage
import gc9a01
import gc

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

# SPI shared by Display and SD
share_spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)

disp_res  = board.D0
disp_dc   = board.D1
disp_cs   = board.D2
disp_blk  = board.D3

# === SD card be initialized before display
sd = sdcardio.SDCard(spi=share_spi,
                     cs=board.SDCS)

#images_folder = '/sd/images_bmp/'   # load bmp images from SD
images_folder = '/images/'          # load bmp images from local filesystem

vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')

for i in os.listdir(images_folder):
    print(i)
# ===========

display_bus = displayio.FourWire(spi_bus=share_spi,
                                 command=disp_dc,
                                 chip_select=disp_cs,
                                 reset=disp_res)

display = gc9a01.GC9A01(display_bus, width=240, height=240, backlight_pin=disp_blk)

#=======================================
info = os.uname()[4] + "\n" + \
       sys.implementation[0] + " " + os.uname()[3] + "\n" + \
       gc9a01.__name__ + " " + gc9a01.__version__
print("=======================================")
print(info)
print("=======================================")
print()

#images bmp stored in MicroSD
images_file = ["img_001_pythonConverted_240x240_rgb888.bmp",
               "img_002_pythonConverted_240x240_rgb565.bmp",
               "img_003_pythonConverted_240x240_rgb888.bmp",
               "img_004_pythonConverted_240x240_rgb565.bmp",
               "img_005_pythonConverted_240x240_rgb888.bmp",
               "img_006_pythonConverted_240x240_rgb565.bmp",
               "img_007_pythonConverted_240x240_rgb888.bmp",
               "img_008_pythonConverted_240x240_rgb565.bmp",
               "img_009_pythonConverted_240x240_rgb888.bmp",
               "img_010_pythonConverted_240x240_rgb565.bmp"
               ]

# 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)

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):
    """
    # using displayio.OnDiskBitmap()
    image = displayio.OnDiskBitmap(path_to_bmp)
    palette = image.pixel_shader
    """
    # 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()

counter = 1
while True:
    print("======== Loop Start " + str(counter) + " ========")
    print(gc.mem_free())
    gc.collect()
    print(gc.mem_free())
    
    tick_ms_start = time.monotonic()
    for f in images_file:
        update_images(images_folder+f)
    tick_ms_end = time.monotonic()
    
    print("--- Loop End ---")
    print(gc.mem_free())
    gc.collect()
    print(gc.mem_free())
    
    print("Time for one loop:",
          tick_ms_end-tick_ms_start,
          "s")
    
    counter = counter+1
    
while True:
    pass


cpy_XS3_gc9a01_sd_slideshow.py
"""
Color test on
Seeed Studio XIAO ESP32S3 Sense/CircuitPython 9.2.1
with 1.28" 240x240 Round GC9A01 SPI IPS LCD + MicroSD
(Share SPI between Display and SD)

Display bmp (stored in MicroSD) in SlideShow using adafruit_slideshow

Library needed:
- gc9a01.mpy
- adafruit_slideshow.mpy

Notice that gc9a01.mpy is in Community Bundle (circuitpython-community-bundle-...),
not Adafruit Circuit Bundle (adafruit-circuitpython-bundle-...).

Share SPI between display and sd card, using sdcardio:

sdcardio – Interface to an SD card via the SPI bus
https://docs.circuitpython.org/en/latest/shared-bindings/sdcardio/index.html

sdcardio.SDCard - SD Card Block Interface
https://docs.circuitpython.org/en/latest/shared-bindings/sdcardio/index.html#sdcardio.SDCard
!Important
If the same SPI bus is shared with other peripherals,
it is important that the SD card be initialized before accessing any other peripheral on the bus.
Failure to do so can prevent the SD card from being recognized until it is powered off or re-inserted.
"""
import os, sys
import board
import time
import displayio
import busio
import terminalio

import sdcardio
import storage
import gc9a01
import adafruit_slideshow

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

# SPI shared by Display and SD
share_spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)

disp_res  = board.D0
disp_dc   = board.D1
disp_cs   = board.D2
disp_blk  = board.D3

# === SD card be initialized before display
sd = sdcardio.SDCard(spi=share_spi,
                     cs=board.SDCS)

images_path = '/sd/images_slideshow'

vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
for i in os.listdir(images_path):
    print(i)
# ===========

display_bus = displayio.FourWire(spi_bus=share_spi,
                                 command=disp_dc,
                                 chip_select=disp_cs,
                                 reset=disp_res)

display = gc9a01.GC9A01(display_bus, width=240, height=240, backlight_pin=disp_blk)

#=======================================
info = os.uname()[4] + "\n" + \
       sys.implementation[0] + " " + os.uname()[3] + "\n" + \
       gc9a01.__name__ + " " + gc9a01.__version__
print("=======================================")
print(info)
print("=======================================")
print()

# Create the slideshow object that plays through once alphabetically.
slideshow = adafruit_slideshow.SlideShow(display,
                                         folder=images_path,
                                         loop=True,
                                         order=adafruit_slideshow.PlayBackOrder.ALPHABETICAL,
                                         dwell=5)

while slideshow.update():
    pass



Comments

Popular posts from this blog

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

my dev.tools - FNIRSI 2C23T 3-in-1 Dual Channel Oscilloscope/Multimeter/Signal Generator