Play animated GIF in CircuitPython 8.1.0 Beta 0, run on ESP32-S3, display on ST7789 SPI TFT.

In CircuitPython 8.1.0 Beta 0, animated GIF is supported with gifio.OnDiskGif.
~ ref: Release Notes for 8.1.0-beta.0

It's a exercise to play GIFs running on Espressif ESP32-S3-DevKitC-1 (flashed with CircuitPython 8.1.0-beta.0), display on 1.14" 135x240 (RGB) IPS ST7789V SPI.

To setup library and connection, refer to last post ESP32-S3/CircuitPython 8 display on ST7789 SPI TFT.


Exercise Code

cpyS3_st7789_gif.py

"""
CircuitPython exercise run on ESP32-S3,
to display GIFs on IPS with ST7789 SPI driver.
dev. board:     ESP32-S3-DevKitC-1-N8R8
CircuitPython:  Adafruit CircuitPython 8.1.0-beta.0 on 2023-03-01

Tested IPS:
- 1.14" 135x240 (RGB) IPS
- 1.54" IPS 240x240 (RGB)
- 2.0" IPS 240(RGB)x320

"""
import os, sys
import board
import busio
import terminalio
import displayio

import adafruit_st7789
import time
import gifio

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

#===init display ======================
disp_blk = board.IO4
disp_cs  = board.IO5
disp_dc  = board.IO6
disp_res = board.IO7

disp_mosi = board.IO15
disp_clk = board.IO16
disp_spi = busio.SPI(clock=disp_clk,
                     MOSI=disp_mosi)

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

#--- Setup display ---

# for 1.14" 135x240 (RGB) IPS
display = adafruit_st7789.ST7789(display_bus,
                                 width=240,
                                 height=135,
                                 rowstart=40, colstart=53,
                                 rotation=270,
                                 backlight_pin=disp_blk)

"""
# for 1.54" IPS 240x240 (RGB)
display = adafruit_st7789.ST7789(display_bus,
                                 width=240,
                                 height=240,
                                 rowstart=80,
                                 rotation=180,
                                 backlight_pin=disp_blk)
"""
"""
# for 2.0" IPS 240(RGB)x320
display = adafruit_st7789.ST7789(display_bus,
                                 width=240,
                                 height=320,
                                 backlight_pin=disp_blk)
"""
"""
# for 2.0" IPS 240(RGB)x320
# rotate 90 degree
disp_width = 240
disp_height = 320
display = adafruit_st7789.ST7789(display_bus,
                                 width=320,
                                 height=240,
                                 rotation=90,
                                 backlight_pin=disp_blk)
"""
#=======================================
info = os.uname()[4] + "\n" + \
       sys.implementation[0] + " " + os.uname()[3] + "\n" + \
       adafruit_st7789.__name__  + " " + adafruit_st7789.__version__  + "\n" + \
       str(display.width) + "x" + str(display.height)
print("=======================================")
print(info)
print("=======================================")
print("CircuitPython play GIF")
print()
time.sleep(5)

splash = displayio.Group()
display.root_group = splash

def showGIF(gif):
    odg = gifio.OnDiskGif(gif)  # Create an OnDiskGif object with the given file.

    print("------------------")
    print("GIF:", gif)
    print("W x H:", odg.width, "x", odg.height)
    print("frame_count:", odg.frame_count)

    odg.next_frame() # Load the first frame

    face = displayio.TileGrid(
        odg.bitmap,
        pixel_shader=displayio.ColorConverter(
            input_colorspace=displayio.Colorspace.RGB565_SWAPPED
        ),
        x = int((display.width-odg.width)/2),
        y = int((display.height-odg.height)/2),
    )
    splash.append(face)
    display.refresh()

    for r in range(odg.frame_count-1):
        odg.next_frame() #load next frame
        
    splash.remove(face)

gifFiles = ("/GIF/GIF_01.gif",
            "/GIF/GIF_02.gif",
            "/GIF/GIF_03.gif",
            "/GIF/GIF_04.gif",
            "/GIF/GIF_05.gif")

while True:
    for f in gifFiles:
        showGIF(f)



Exercise 2

cpyS3_st7789_gif2.py, play  animated GIFs in separated TileGrid.
"""
CircuitPython exercise run on ESP32-S3,
to display GIFs on IPS with ST7789 SPI driver, in separated TileGrid.
dev. board:     ESP32-S3-DevKitC-1-N8R8
CircuitPython:  Adafruit CircuitPython 8.1.0-beta.0 on 2023-03-01

Tested on:
- 2.0" IPS 240(RGB)x320

"""
import os, sys
import board
import busio
import terminalio
import displayio

import adafruit_st7789
import time
import gifio

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

#===init display ======================
disp_blk = board.IO4
disp_cs  = board.IO5
disp_dc  = board.IO6
disp_res = board.IO7

disp_mosi = board.IO15
disp_clk = board.IO16
disp_spi = busio.SPI(clock=disp_clk,
                     MOSI=disp_mosi)

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

#--- Setup display ---

# for 2.0" IPS 240(RGB)x320
# rotate 90 degree
disp_width = 240
disp_height = 320
display = adafruit_st7789.ST7789(display_bus,
                                 width=320,
                                 height=240,
                                 rotation=90,
                                 backlight_pin=disp_blk)

#=======================================
info = os.uname()[4] + "\n" + \
       sys.implementation[0] + " " + os.uname()[3] + "\n" + \
       adafruit_st7789.__name__  + " " + adafruit_st7789.__version__  + "\n" + \
       str(display.width) + "x" + str(display.height)
print("=======================================")
print(info)
print("=======================================")
print("CircuitPython play GIF")
print()
time.sleep(2)

splash = displayio.Group()
display.root_group = splash

def showGIF(gif, off_x, off_y):
    odg = gifio.OnDiskGif(gif)
    #print("W x H:", odg.width, "x", odg.height)
    
    odg.next_frame() # Load the first frame

    face = displayio.TileGrid(
        odg.bitmap,
        pixel_shader=displayio.ColorConverter(
            input_colorspace=displayio.Colorspace.RGB565_SWAPPED
        ),
        x = off_x,
        y = off_y,
    )

    splash.append(face)
    display.refresh()

    for r in range(odg.frame_count-1):
        odg.next_frame()

gifFiles = ("/GIF/GIF_01.gif",
            "/GIF/GIF_02.gif",
            "/GIF/GIF_03.gif",
            "/GIF/GIF_04.gif",
            "/GIF/GIF_05.gif")

offset_x = 0
offset_y = 0
div_x = 30
div_y = 30

for f in gifFiles:
    showGIF(f, offset_x, offset_y)
    offset_x = offset_x + div_x
    offset_y = offset_y + div_y
    
while True:
    pass



Exercise 3

cpyS3_st7789_gif3.py, play animated GIFs repeatly in a moving TileGrid.
"""
CircuitPython exercise run on ESP32-S3,
to display GIFs on IPS with ST7789 SPI driver, in a moving TileGrid.
dev. board:     ESP32-S3-DevKitC-1-N8R8
CircuitPython:  Adafruit CircuitPython 8.1.0-beta.0 on 2023-03-01

Tested on:
- 2.0" IPS 240(RGB)x320

"""
import os, sys
import board
import busio
import terminalio
import displayio

import adafruit_st7789
import time
import gifio

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

#===init display ======================
disp_blk = board.IO4
disp_cs  = board.IO5
disp_dc  = board.IO6
disp_res = board.IO7

disp_mosi = board.IO15
disp_clk = board.IO16
disp_spi = busio.SPI(clock=disp_clk,
                     MOSI=disp_mosi)

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

#--- Setup display ---

# for 2.0" IPS 240(RGB)x320
# rotate 90 degree
disp_width = 240
disp_height = 320
display = adafruit_st7789.ST7789(display_bus,
                                 width=320,
                                 height=240,
                                 rotation=90,
                                 backlight_pin=disp_blk)

#=======================================
info = os.uname()[4] + "\n" + \
       sys.implementation[0] + " " + os.uname()[3] + "\n" + \
       adafruit_st7789.__name__  + " " + adafruit_st7789.__version__  + "\n" + \
       str(display.width) + "x" + str(display.height)
print("=======================================")
print(info)
print("=======================================")
print("CircuitPython play GIF")
print()
time.sleep(2)

splash = displayio.Group()
display.root_group = splash

# Moving animation base on GIFs are in 200x113
gif_w = 200
gif_h = 113
lim_x = display.width-gif_w
lim_y = display.height-gif_h
dir_x = 1
dir_y = 1


def updateGIF(myface, gif):
    global dir_x, dir_y
    odg = gifio.OnDiskGif(gif)
    #print("W x H:", odg.width, "x", odg.height)
    
    odg.next_frame() # Load the first frame
    myface.bitmap = odg.bitmap

    #print("frame.count:", odg.frame_count)
    for r in range(odg.frame_count-1):
        odg.next_frame()
        x = myface.x+dir_x
        y = myface.y+dir_y

        if dir_x==1:
            if x>=lim_x:
                dir_x=-1
        else:
            if x<=0:
                dir_x=1
                
        if dir_y==1:
            if y>=lim_y:
                dir_y=-1
        else:
            if y<=0:
                dir_y=1
                
        myface.x = x
        myface.y = y
        

gifFiles = ("/GIF/GIF_01.gif",
            "/GIF/GIF_02.gif",
            "/GIF/GIF_03.gif",
            "/GIF/GIF_04.gif",
            "/GIF/GIF_05.gif")

# create a dummy odg to fill in TileGrid
# It will be replace by GIFs later
dummy_odg = gifio.OnDiskGif(gifFiles[0])
dummy_odg.next_frame() # Load the first frame

face = displayio.TileGrid(
    dummy_odg.bitmap,
    pixel_shader=displayio.ColorConverter(
        input_colorspace=displayio.Colorspace.RGB565_SWAPPED
        ),
    x = 0,
    y = 0,
)
splash.append(face)
display.refresh()

while True:
    for f in gifFiles:
        updateGIF(face, f)





Comments

Popular posts from this blog

MicroPython/ESP32-C3 + 1.8" 128x160 TFT ST7735 SPI, using boochow/MicroPython-ST7735 library.

CameraWebServe: ESP32-S3 (arduino-esp32) + OV5640 camera module