RP2040/CircuitPython 8.1.0-beta.1 - Play animated GIF stored in SD Card

Previous post my exercise of playing animated GIF (stored in CircuitPython device) on 8 bit parallel bus ILI9341. This exercise load the animated GIFs from SD Card.

updated@2023-04-15:
Exercise code for Wio Terminal added, scroll down to find it.


Prepare SD Card

A 4G SD Card is formatted as FAT to store GIFs.


Connection

It's a SD Card on my 2.8 inch 320x240 ili9341 TFT with 8/16BIT parallel interface. To interface, extra pins for SD Card are needed.

    Connection between RP2040 and
    2.8" 320x240 ili9341 TFT in 8-bit parallel interface:

	RP2040 GPIO
        |                      |
        V	               V
		+------------+
	2	| CLK	T_CS |	
		| F_CS	PEN  |
	3	| MOSI	MISO | 4
		| NC	GND  | GND
        GND	| GND	VDD  | 3V3
        3V3	| VDD	BL   | 3V3
	5	| SDCS	DB15 | 17
        16	| DB14	DB13 | 15
        14	| DB12	DB11 | 13
        12      | DB10	DB9  | 11
        10	| DB8	DB7  |
		| DB6	DB5  |
		| DB4	DB3  |
		| DB2	DB1  |
		| DB0	RST  | 20
        8       | RD	WR   | 19
        9 	| RS	CS   | 18
		+------------+
	        ILI9341 TFT (parallel i/f)

        GPIO in BLUE - for TFT
        GPIO in RED  - for SD Card
	

Code

cpyPico_SD_SetupAndMount.py
A simple example to setup and mount SD Card, also list contents in SD.
"""
Run on WeAct RP2040 (16MB)/CircuitPyth 8.1.0-beta.1
To setup and mount SD Card
ref:
https://docs.circuitpython.org/en/latest/shared-bindings/sdcardio/index.html#module-sdcardio
"""
import os
import board, busio
import sdcardio
import storage

SPI_CLK = board.GP2
SPI_MOSI= board.GP3
SPI_MISO= board.GP4
SDCS    = board.GP5

SD_spi = busio.SPI(clock=SPI_CLK, MOSI=SPI_MOSI, MISO=SPI_MISO)
sd = sdcardio.SDCard(SD_spi, SDCS)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
for f in os.listdir('/sd'):
    print(f)





cpyPico_ParallelBus_ili9341_aniGIF_SD.py
Play animated GIF stored in SD Card
"""
Run on WeAct RP2040 (16MB Flash)/CircuitPython 8.1.0-beta.1
display on 8 bit ILI9341,
play animated GIFs using gifio.OnDiskGif()
"""
import os, sys
import time
import board
import displayio
import adafruit_ili9341
import gifio
import sdcardio
import storage
import busio

displayio.release_displays()
# pins for SD Card
SPI_CLK = board.GP2
SPI_MOSI= board.GP3
SPI_MISO= board.GP4
SDCS    = board.GP5

"""
For Raspberry Pi Pico/RP2040,
supports data0= only, not data_pins=, because it requires contiguous pins.
"""
TFT_DATA0 = board.GP10  #The first data pin. The rest are implied
                        #D0~D7 = GP10~17
TFT_RS = board.GP9    #command
TFT_CS = board.GP18   #chip Select
TFT_WR = board.GP19   #write
TFT_RD = board.GP8    #read
TFT_RST = board.GP20  #reset

TFT_WIDTH = 320
TFT_HEIGHT = 240

display_bus = displayio.ParallelBus(data0=TFT_DATA0,
                                    command=TFT_RS,
                                    chip_select=TFT_CS,
                                    write=TFT_WR,
                                    read=TFT_RD,
                                    reset=TFT_RST,
                                    frequency=60000000)

display = adafruit_ili9341.ILI9341(display_bus,
                                   width=TFT_WIDTH,
                                   height=TFT_HEIGHT)
display.rotation=0

print("========================================")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("========================================")
print(adafruit_ili9341.__name__, adafruit_ili9341.__version__)
print(display_bus)
print()
print("display.rotation:", display.rotation)
print("display.width:   ", display.width)
print("display.height:  ", display.height)
print()


# setup and mount SD Card
SD_spi = busio.SPI(clock=SPI_CLK, MOSI=SPI_MOSI, MISO=SPI_MISO)
sd = sdcardio.SDCard(SD_spi, SDCS)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
for f in os.listdir('/sd'):
    print(f)
print()
time.sleep(5)

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

def showGIF(gif):
    print("------------------")
    print("GIF:", gif)
    
    odg = gifio.OnDiskGif(gif)  # Create an OnDiskGif object with the given file.

    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)
"""
#320x180
gifFiles = ("/sd/SD_GIF2_1_320.gif",
            "/sd/SD_GIF2_2_320.gif",
            "/sd/SD_GIF2_3_320.gif",
            "/sd/SD_GIF2_4_320.gif")
"""
#200x113
gifFiles = ("/sd/SD_GIF2_1_200.gif",
            "/sd/SD_GIF2_2_200.gif",
            "/sd/SD_GIF2_3_200.gif",
            "/sd/SD_GIF2_4_200.gif")

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





Play animated GIF on Wio Terminal/CircuitPython 8.1.0 beta 1




cpyWio_aniGIF_SD.py
"""
Run on Wio Terminal/CircuitPython 8.1.0-beta.1
play animated GIFs using gifio.OnDiskGif()
"""
import os, sys
import time
import board
import displayio
import gifio
import sdcardio
import storage
import busio

# pins for SD Card
SPI_CLK = board.SD_SCK
SPI_MOSI= board.SD_MOSI
SPI_MISO= board.SD_MISO
SDCS    = board.SD_CS

display = board.DISPLAY

print("========================================")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("========================================")
print()
#print("display.width:   ", board.DISPLAY.width)
#print("display.height:  ", board.DISPLAY.height)
print()


# setup and mount SD Card
SD_spi = busio.SPI(clock=SPI_CLK, MOSI=SPI_MOSI, MISO=SPI_MISO)
sd = sdcardio.SDCard(SD_spi, SDCS)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
for f in os.listdir('/sd'):
    print(f)
print()
time.sleep(5)

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

def showGIF(gif):
    print("------------------")
    print("GIF:", gif)
    
    odg = gifio.OnDiskGif(gif)  # Create an OnDiskGif object with the given file.

    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)

#320x180
gifFiles = ("/sd/SD_GIF2_1_320.gif",
            "/sd/SD_GIF2_2_320.gif",
            "/sd/SD_GIF2_3_320.gif",
            "/sd/SD_GIF2_4_320.gif")
"""
#200x113
gifFiles = ("/sd/SD_GIF2_1_200.gif",
            "/sd/SD_GIF2_2_200.gif",
            "/sd/SD_GIF2_3_200.gif",
            "/sd/SD_GIF2_4_200.gif")
"""
while True:
    for f in gifFiles:
        showGIF(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