Using MatrixPortal M4 for animation
WhatHow isto MatrixPortal M4
Theuse MatrixPortal M4 isfor a development board created by Adafruit designed to control RGB LED matrices. It is equipped with an ATSAMD51 microcontroller (Cortex M4) and has built-in Wi-Fi support thanks to the ESP32 coprocessor.
HereWe arehave someanother keytutorial featuresfor ofsetting up the MatrixPortal M4:
Microcontroller: ATSAMD51, Cortex M4 processor running at 120 MHz.Coprocessor: ESP32 handles Wi-Fiboard andnetwork communication.Memory: 512KB of RAM, 8MB of QSPI flash storage.Matrix Control: Dedicated connectors for RGB LED matrices (HUB75 interface), allowing direct control without needing additional hardware.Power: Can be powered via USB-C or throughcovering thematrix’sbasics.powerThissupply.Programming: Supports programming via CircuitPython and Arduino IDE.Wi-Fi Connectivity: Useful for IoT projects that require network connectivity, such as weather stations, stock tickers, or message boards.
It’s great for building projects that involve large, colourful LED displays, such as scrolling text, interactive dashboards, or internet-connected signs. In this tutorial, wetutorial will usefocus CircuitPythonon tocreating programan a 64X32 matrix as CircuitPython libraries make it easieranimation to display images,on animations,a text,64x32 etc than Arduino IDE.
You can read more about this component here.matrix.
WiringCreating the Spitesheet
ThereA spritesheet is noa wiringsingle neededimage file that contains a collection of smaller images (called sprites) arranged in a grid or some other layout. These individual sprites can represent various frames of an animation, characters, objects, or other visual elements in a video game or graphic application.
We will need to use a bitmap spitesheet. If you just want to test the code, you can download the test.bmp
and skip this part for basicnow.
1. it'sPiskel
Piskel plugis anda play.free Pleaseonline refereditor for animated sprites & pixel art.
- Go to
thispageto see howresize
to setittheup.canvas size to 64 x 32 px - Draw whatever you want
-
Add new frame
and draw - until you finish
Using a 64X64 Matrix
Ask a Technician first!
If you are using a MatrixPortal M4 borrowed from us, please do not do this step yourself, ask a technician for help instead.
This jumper is used for use with 64x64 matrices. You can close the jumper by using your soldering iron to melt a blob of solder on the bottom solder jumper so the middle pad is 'shorted' to 8 as below.
You can read more about Address E Line Jumper here.
Install CircuitPython
CircuitPython and libraries versions
In this tutorial, we are using CircuitPython 9.0.5 (11/10/2024), and all libraries used are compatible with this version. Please double-check the latest version of CircuitPython you have installed and use updated and compatible libraries.
CircuitPython is an open-source programming language designed for microcontrollers. It's a beginner-friendly version of Python developed by Adafruit, optimized for hardware projects like controlling sensors, displays, and other electronics.
1. Download CircuitPython
Download the latest version for MatrixPortal UF2 file for your board here.
2. Put the Board into Bootloader Mode
To install CircuitPython, you need to place the board into bootloader mode.
PressGothetoresetEXPORT
button on your board twice quickly.TheSelectboard’sPNG
LED- Change
changeColumns
toa different colour (usually pulsing red or green)1 AnewDownload
USB- You
willnowappearhaveonayourverycomputerlongnamedPNGsomething like"BOOT".file
3.2. CopyPhotoshop
DragOpen the image with Photoshop- Save a copy in BMP format
- Choose
Windows
(doesn't matter what computer you use) anddrop16
theBitdownloadedUF2 fileonto the new drive. TheYouboardnowwill reboot, andhave anewready-to-godrivespitesheetnamedBMPCIRCUITPYwill appear. This drive is where you'll place your Python code and libraries.file
Libraries
DownloadImporting thelibrariesImagebundlehere, choose the version you need.CopyCreatethe libraries you need to the
a folderlibofcalledbmp
in the CIRCUITPY drive.
Commonthe librariesbitmap file you need:
- created
adafruit_matrixportalinto adafruit_debouncer.mpythe adafruit_portalbaseadafruit_esp32spineopixel.mpyadafruit_bus_deviceadafruit_requests.mpyadafruit_fakerequests.mpyadafruit_ioadafruit_bitmap_fontadafruit_display_textadafruit_lis3dh.mpyadafruit_minimqttadafruit_ticks.pyadafruit_rgb_displayadafruit_imageloadadafruit_display_shapesfolder.
Code - Scrolling Text
# SPDX-FileCopyrightText: 2020 JeffJohn EplerPark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
#import This example implements a simple two line scroller using
# Adafruit_CircuitPython_Display_Text. Each line has its own color
# and it is possible to modify the example to use other fonts and non-standard
# characters.time
import adafruit_display_text.labelos
import board
import displayio
importfrom framebufferiodigitalio import rgbmatrixDigitalInOut, Pull
from adafruit_matrixportal.matrix import terminalioMatrix
from adafruit_bitmap_fontadafruit_debouncer import bitmap_fontDebouncer
fromSPRITESHEET_FOLDER displayio= import"/bmp"
BitmapDEFAULT_FRAME_DURATION = 0.1 # If100ms
thereFRAME_DURATION_OVERRIDES was= a{
display"KIRBY.bmp": before0.05,
(protomatter, LCD, or E-paper), release it so}
# we--- canDisplay createsetup ours
displayio.release_displays()---
matrix = rgbmatrix.RGBMatrix(
Matrix(width=64, height=64, bit_depth=6,6)
rgb_pins=[
board.MTX_R1,
board.MTX_G1,
board.MTX_B1,
board.MTX_R2,
board.MTX_G2,
board.MTX_B2
],
addr_pins=[
board.MTX_ADDRA,
board.MTX_ADDRB,
board.MTX_ADDRC,
board.MTX_ADDRD
],
clock_pin=board.MTX_CLK,
latch_pin=board.MTX_LAT,
output_enable_pin=board.MTX_OE
)
display = framebufferio.FramebufferDisplay(matrix, auto_refresh=False)
keycolour = 0X7BFF4A
# Create two lines of text to scroll. Besides changing the text, you can also
# customize the color and font (using Adafruit_CircuitPython_Bitmap_Font).
# To keep this demo simple, we just used the built-in font.
# The Y coordinates of the two lines were chosen so that they looked good
# but if you change the font you might find that other values work better.
line1 = adafruit_display_text.label.Label(
terminalio.FONT,
color=keycolour, #white
text="This is Creative Technology Hub")
line1.x = display.width
line1.y = 5
line2 = adafruit_display_text.label.Label(
terminalio.FONT,
color=0x000000,
background_color=keycolour,
background_tight = True,
text="Hello Hello Hello Hello Hello Helloooooooooo")
line2.x = display.width
line2.y = 15
line3 = adafruit_display_text.label.Label(
terminalio.FONT,
color=keycolour,
text="Stop peeking come in")
line3.x = display.width
line3.y = 26
# Put each line of text into a Group, then show that group.
gsprite_group = displayio.Group()
g.append(line1)
g.append(line2)
g.append(line3)
matrix.display.root_group = gsprite_group
file_list = sorted(
[
f
for f in os.listdir(SPRITESHEET_FOLDER)
if (f.endswith(".bmp") and not f.startswith("."))
]
)
if len(file_list) == 0:
raise RuntimeError("No images found")
current_image = None
current_frame = 0
current_loop = 0
frame_count = 0
frame_duration = DEFAULT_FRAME_DURATION
direction = 1 #1 for forward, -1 for backward
def load_image():
"""
Load an image as a sprite
"""
# Thispylint: functiondisable=global-statement
willglobal scootcurrent_frame, onecurrent_loop, labelframe_count, aframe_duration
pixelwhile sprite_group:
sprite_group.pop()
filename = SPRITESHEET_FOLDER + "/" + file_list[current_image]
# # CircuitPython 7+ compatible
bitmap = displayio.OnDiskBitmap(filename)
sprite = displayio.TileGrid(
bitmap,
pixel_shader=bitmap.pixel_shader,
tile_width=bitmap.width,
tile_height=matrix.display.height,
)
sprite_group.append(sprite)
current_frame = 0
current_loop = 0
frame_count = int(bitmap.height / matrix.display.height)
frame_duration = DEFAULT_FRAME_DURATION
if file_list[current_image] in FRAME_DURATION_OVERRIDES:
frame_duration = FRAME_DURATION_OVERRIDES[file_list[current_image]]
direction = 1
def advance_image():
"""
Advance to the leftnext image in the list and send itloop back toat the end
"""
# thepylint: fardisable=global-statement
rightglobal current_image
if it'scurrent_image goneis allnot None:
current_image += 1
if current_image is None or current_image >= len(file_list):
current_image = 0
load_image()
def advance_frame():
"""
Advance to the waynext offframe screen.and Thisloop goesback inat athe functionend
"""
# becausepylint: we'lldisable=global-statement
doglobal exactlycurrent_frame, thecurrent_loop, samedirection
thingcurrent_frame with+= line1direction
andif line2current_frame below.>= defframe_count:
scroll(line):
line.xcurrent_frame = line.xframe_count - 1
line_width = line.bounding_box[2]
if line.x < -line_width:
line.x = display.width
# This function scrolls lines backwards. Try switching which function is
# called for line2 below!
def reverse_scroll(line):
line.x = line.x + 1
line_width = line.bounding_box[2]
if line.x >= display.width:
line.xdirection = -line_width1 # YouReverse candirection
addelif morecurrent_frame effects< in0:
thiscurrent_frame loop.= For0
instance,direction maybe= you want to set the1 # colorForward ofdirection
eachsprite_group[0][0] label= tocurrent_frame
a different value.advance_image()
while True:
scroll(line1)advance_frame()
#scroll(line2)
scroll(line3)
reverse_scroll(line2)
display.refresh(minimum_frames_per_second=1)time.sleep(frame_duration)