# LED Matrix Display for Bitmap Pixel Art and Animation

## Overview

https://youtu.be/VZcNJuJpLjc

![](https://cdn-learn.adafruit.com/assets/assets/000/095/394/medium800thumb/led_matrices_pixel_art.jpg?1602012399)

Build your own pixel art display in order to view some of your favorite retro, low-rez artwork! We'll use **.bmp** format raster graphics files formatted for the 64x32 pixel RGB LED matrix display.

You can create your own pixel art, or scour the web for some favorites.

This project uses the Matrix Portal to show the pixel art on the display. It runs CircuitPython and uses the Slideshow library to make it easy!

You can play the slideshow and let it loop, or press the Matrix Portal's UP and DOWN buttons to pause/resume the loop and pick a particular image you're dying to see!

## Parts
### Adafruit Matrix Portal - CircuitPython Powered Internet Display

[Adafruit Matrix Portal - CircuitPython Powered Internet Display](https://www.adafruit.com/product/4745)
Folks love our [wide selection of RGB matrices](https://www.adafruit.com/category/327) and accessories, for making custom colorful LED displays... and our RGB Matrix Shields and FeatherWings can be quickly soldered together to make the wiring much easier. But what if we made it...

In Stock
[Buy Now](https://www.adafruit.com/product/4745)
[Related Guides to the Product](https://learn.adafruit.com/products/4745/guides)
![Video of a person rotating an LED matrix panel with animation resembling falling colored sand.](https://cdn-shop.adafruit.com/product-videos/640x480/4745-05.jpg)

### Black LED Diffusion Acrylic Panel 12" x 12" - 0.1" / 2.6mm thick

[Black LED Diffusion Acrylic Panel 12" x 12" - 0.1" / 2.6mm thick](https://www.adafruit.com/product/4594)
A nice whoppin' slab of some lovely black acrylic to add some extra diffusion to your LED Matrix project. This material is 2.6mm (0.1") thick and is made of special cast acrylic that makes it perfect for glowy projects, especially matricies or NeoPixels.

Unlike smoke or...

In Stock
[Buy Now](https://www.adafruit.com/product/4594)
[Related Guides to the Product](https://learn.adafruit.com/products/4594/guides)
![LED RGB matrix 12" x 12" with "Adafruit Industries LED Matrix" text showing, and LED acrylic slowly covering to make it nicely diffused](https://cdn-shop.adafruit.com/product-videos/640x480/4594-04.jpg)

### 5V 2.5A Switching Power Supply with 20AWG MicroUSB Cable

[5V 2.5A Switching Power Supply with 20AWG MicroUSB Cable](https://www.adafruit.com/product/1995)
Our all-in-one 5V 2.5 Amp + MicroUSB cable power adapter is the perfect choice for powering single-board computers like Raspberry Pi, BeagleBone, or anything else that's power-hungry!

This adapter was specifically designed to provide 5.25V, not 5V, but we still call it a 5V USB...

In Stock
[Buy Now](https://www.adafruit.com/product/1995)
[Related Guides to the Product](https://learn.adafruit.com/products/1995/guides)
![MicroUSB power supply with bundled cable and U.S. plugs.](https://cdn-shop.adafruit.com/640x480/1995-02.jpg)

### Micro B USB to USB C Adapter

[Micro B USB to USB C Adapter](https://www.adafruit.com/product/4299)
As technology changes and adapts, so does Adafruit, and speaking of&nbsp;_adapting_, this&nbsp;_ **adapter** _&nbsp;has a Micro B USB jack&nbsp;and a USB C plug.

USB C is the latest industry-standard connector for transmitting data&nbsp;_and_&nbsp;power....

In Stock
[Buy Now](https://www.adafruit.com/product/4299)
[Related Guides to the Product](https://learn.adafruit.com/products/4299/guides)
![Angled shot of Micro B USB to USB C Adapter.](https://cdn-shop.adafruit.com/640x480/4299-02.jpg)

### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

Out of Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
![USB cable - USB A to Micro-B - 3 foot long](https://cdn-shop.adafruit.com/640x480/592-01.jpg)

# LED Matrix Display for Bitmap Pixel Art and Animation

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## Set up CircuitPython Quick Start!

Follow this quick step-by-step for super-fast Python power :)

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/matrixportal_m4/)
## Further Information

For more detailed info on installing CircuitPython, check out [Installing CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython).

 **Click the link above and download the latest UF2 file.**

Download and save it to your desktop (or wherever is handy).

![led_matrices_Save_to_Desktop.png](https://cdn-learn.adafruit.com/assets/assets/000/095/075/medium640/led_matrices_Save_to_Desktop.png?1601050695)

Plug your MatrixPortal M4 into your computer using a known-good USB cable.

**A lot of people end up using charge-only USB cables and it is very frustrating! So make sure you have a USB cable you know is good for data sync.**

Double-click the **Reset** button (indicated by the green arrow) on your board, and you will see the NeoPixel RGB LED (indicated by the magenta arrow) turn green. If it turns red, check the USB cable, try another USB port, etc.

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

![led_matrices_matrixportal_install_cp.jpg](https://cdn-learn.adafruit.com/assets/assets/000/125/447/medium640/led_matrices_matrixportal_install_cp.jpg?1697644568)

You will see a new disk drive appear called **MATRIXBOOT**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **MATRIXBOOT****.**

![led_matrices_MATRIXBOOT.png](https://cdn-learn.adafruit.com/assets/assets/000/125/448/medium640/led_matrices_MATRIXBOOT.png?1697644692)

![led_matrices_Drag_to_Drive.png](https://cdn-learn.adafruit.com/assets/assets/000/125/449/medium640/led_matrices_Drag_to_Drive.png?1697644703)

The LED will flash. Then, the **MATRIXBOOT** &nbsp;drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![led_matrices_circuitpy.png](https://cdn-learn.adafruit.com/assets/assets/000/125/450/medium640/led_matrices_circuitpy.png?1697645066)

# LED Matrix Display for Bitmap Pixel Art and Animation

## Code the Pixel Art Display

https://youtu.be/lKxBRi1dw4c

## Text Editor

Adafruit recommends using the Mu editor for editing your CircuitPython code. You can get more info in [this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves simple text files.

## Code

To use with CircuitPython, you need to first install a few libraries, into the lib folder on your **CIRCUITPY** drive. Then you need to update **code.py** with the example script.

Thankfully, we can do this in one go. In the example below, click the **Download Project Bundle** button below to download the necessary libraries and the **code.py** file in a zip file. Extract the contents of the zip file, open the directory **Pixel\_Art\_Slideshow/** and then click on the directory that matches the version of CircuitPython you're using and&nbsp;copy the contents of that directory to your **CIRCUITPY** drive.

Your **CIRCUITPY** drive should now look similar to the following image:

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/Pixel_Art_Slideshow.png )

Primary: 

![](https://cdn-learn.adafruit.com/assets/assets/000/095/433/medium800/led_matrices_pixart.jpg?1602086009)

## Pixel Art Specs

If you want to create your own artwork for display, these are the specifications to follow:

- Images should be a maximum of 32 pixels high
- Images can be up to 64 pixels wide
- Colors are 16-bit or 24-bit RGB
- Save files as .bmp format

We've found that crisp images (not too much anti-aliasing) work best.

We have a whole page on [Pixel Art Fundamentals](https://learn.adafruit.com/makecode-arcade-pixel-art-sprites/pixel-art-fundamentals) here!

![led_matrices_gaming_snesMario.png](https://cdn-learn.adafruit.com/assets/assets/000/095/429/medium640/led_matrices_gaming_snesMario.png?1602084445)

You can use nearly any paint program, but dedicated pixel art programs work best, such as [Aseprite](https://www.aseprite.org/) or the free pixel art app [Piskel](https://www.piskelapp.com/).

![led_matrices_aseprite_ruby.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/427/medium640/led_matrices_aseprite_ruby.jpg?1602084107)

![led_matrices_piskel.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/428/medium640/led_matrices_piskel.jpg?1602084226)

## Art Collecting

If you want to search for ready-made art to display, here are some tips.

### Game Frame Art

The excellent [Game Frame](https://ledseq.com/) product by Jeremy Williams pioneered the pixel art frame. You can check the [LedSeq Game Frame forums](https://ledseq.com/forums/forum/game-frame/) for art gallery submissions. Although these tend to be 16x16 pixel images, you can scale them up (don't interpolate!) for use on the Matrix Portal.

Jeremy has also graciously made the code and art for Game Frame available for [free download here](https://ledseq.com/product/game-frame-sd-files/).

![led_matrices_sdCollage.png](https://cdn-learn.adafruit.com/assets/assets/000/095/431/medium640/led_matrices_sdCollage.png?1602085779)

### Search

Another great tip from LedSeq is to use a Google image search to return results of "pixel art" or "video game" at a specific resolution, either 64x32 or 32x32:

`https://www.google.com/search?q=pixel+art&tbm=isch&tbs=isz:ex,iszw:32,iszh:32`

### Itch.io Assets

Many talented artist post their pixel art [game assets to Itch.io](https://itch.io/game-assets/tag-pixel-art) where you can name your price in many case for amazing artwork!

Shown here are the excellent [PIPOYA FREE RPG Character Sprites](https://pipoya.itch.io/pipoya-free-rpg-character-sprites-32x32).

![led_matrices_04SPhB.png](https://cdn-learn.adafruit.com/assets/assets/000/095/430/medium640/led_matrices_04SPhB.png?1602085566)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Pixel_Art_Slideshow/code.py

## How it Works

### Libraries

Here's how the code works. First we import the `time`, `board`, `digitalio`, `adafruit_matrixportal`, `adafruit_slideshow`, and `adafruit_debouncer` libraries.

### Variables

Then, we'll set the variables for the `IMAGE_DURATION` in seconds (you can adjust this as you like), as well as the path to the image folder.

```python
import time
import board
from digitalio import DigitalInOut, Pull
from adafruit_matrixportal.matrix import Matrix
from adafruit_slideshow import SlideShow, PlayBackDirection, HorizontalAlignment
from adafruit_debouncer import Debouncer

IMAGE_DURATION = 3
IMAGE_FOLDER = "/bmps"
```

### Display/Pin Setup

Next, we set up the display and the pins used for the buttons.

```python
matrix = Matrix(bit_depth=6)
display = matrix.display

pin_down = DigitalInOut(board.BUTTON_DOWN)
pin_down.switch_to_input(pull=Pull.UP)
button_down = Debouncer(pin_down)
pin_up = DigitalInOut(board.BUTTON_UP)
pin_up.switch_to_input(pull=Pull.UP)
button_up = Debouncer(pin_up)
```

## Slideshow Setup

The alignment of images narrower than 64 pixels wide will alternate, initially with right-side alignment. The `auto_advance` state is set to true initially, but can be changed by pressing the UP button later.

The slideshow is set up next using the settings shown here.

```python
align_right = True
auto_advance = True

slideshow = SlideShow(
    display,
    None,
    folder=IMAGE_FOLDER,
    order=0,
    auto_advance=False,
    fade_effect=False,
    dwell=IMAGE_DURATION,
    h_align=HorizontalAlignment.RIGHT,
)
last_advance = time.monotonic()
```

## Advance!

The `advance()` function will be used to drive the `slideshow.advance()` command using the alternating right/left alignment and auto-advance features.

```python
def advance():
    # pylint: disable=global-statement
    global align_right, last_advance
    align_right = not align_right
    if align_right:
        slideshow.h_align = HorizontalAlignment.RIGHT
    else:
        slideshow.h_align = HorizontalAlignment.LEFT
    last_advance = time.monotonic()
    slideshow.advance()
```

## Main Loop

Here's what happens during the main loop of the program:

- Check if `auto_advance` is on, and if the `time.monotonic()` value is bigger than the `last_advance` time plus the `IMAGE_DURATION` time. If so, `advance()` to the next image!
- Check for button presses:
  - If the **UP** button is pressed, toggle the auto\_advance state
  - If the **DOWN** button is pressed, manually advance to the next image

```python
while True:
    if auto_advance and time.monotonic() &gt; last_advance + IMAGE_DURATION:
        advance()
    button_down.update()
    button_up.update()
    if button_up.fell:
        auto_advance = not auto_advance
    if button_down.fell:
        slideshow.direction = PlayBackDirection.FORWARD
        advance()
```

# LED Matrix Display for Bitmap Pixel Art and Animation

## Prep the MatrixPortal

## Power Prep

The MatrixPortal supplies power to the matrix display panel via two standoffs. These come with protective tape applied (part of our manufacturing process) which MUST BE REMOVED!

Use some tweezers or a fingernail to remove the two amber circles.

![adafruit_io_mxprtl-3866.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/902/medium640/adafruit_io_mxprtl-3866.jpg?1600706317)

![adafruit_io_mxprtl-3867.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/903/medium640/adafruit_io_mxprtl-3867.jpg?1600706324)

## Power Terminals

Next, screw in the spade connectors to the corresponding standoff.

- **red** wire goes to **+5V** &nbsp;
- **black** wire goes to **GND**

![adafruit_io_mxprtl-3869.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/907/medium640/adafruit_io_mxprtl-3869.jpg?1600706432)

![adafruit_io_mxprtl-3871.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/908/medium640/adafruit_io_mxprtl-3871.jpg?1600706551)

## Panel Power

Plug either one of the four-conductor power plugs into the power connector pins on the panel. The plug can only go in one way, and that way is marked on the board's silkscreen.

![adafruit_io_mxprtl-3872.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/910/medium640/adafruit_io_mxprtl-3872.jpg?1600706597)

![adafruit_io_mxprtl-3873.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/911/medium640/adafruit_io_mxprtl-3873.jpg?1600706672)

## Dual Matrix Setup

If you're planning to use a 64x64 matrix, [follow these instructions on soldering the Address E Line jumper](https://learn.adafruit.com/adafruit-matrixportal-m4/pinouts#address-e-line-jumper-3072815).

## Board Connection

Now, plug the board into the left side shrouded 8x2 connector as shown. The orientation matters, so take a moment to confirm that the **white indicator arrow on the matrix panel is oriented pointing up and right** as seen here and the MatrixPortal overhangs the edge of the panel when connected. This allows you to use the edge buttons from the front side.

&nbsp;

Check nothing is impeding the board from plugging in firmly. If there's a plastic nub on the matrix that's keeping the Portal from sitting flat, cut it off with diagonal cutters

![adafruit_io_mxprtl-3874.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/912/medium640/adafruit_io_mxprtl-3874.jpg?1600706721)

![adafruit_io_mxprtl-3875.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/913/medium640/adafruit_io_mxprtl-3875.jpg?1600706732)

![](https://cdn-learn.adafruit.com/assets/assets/000/094/914/medium800/adafruit_io_mxprtl-3876.jpg?1600706891)

![](https://cdn-learn.adafruit.com/assets/assets/000/094/915/medium800/adafruit_io_mxprtl-3877.jpg?1600706894)

Info: 

# LED Matrix Display for Bitmap Pixel Art and Animation

## LED Matrix Diffuser

## LED Diffusion Acrylic

You can add an [LED diffusion acrylic faceplate](https://www.adafruit.com/product/4594) to the your LED matrix display. (Pictured here with the [ON AIR project](https://learn.adafruit.com/rgb-matrix-automatic-youtube-on-air-sign))

This can help protect the LEDs as well as enhance the look of the sign both indoors and out by reducing glare and specular highlights of the plastic matrix grid.

![led_matrices_onairbuild-3367.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/987/medium640/led_matrices_onairbuild-3367.jpg?1597088161)

## Measure and Cut the Plastic

You can use the sign to measure and mark cut lines on the paper backing of the acrylic sheet.

Then, use a tablesaw or bandsaw with a fine toothed blade and a guide or sled to make the cuts.

Note: it is possible to score and snap acrylic, but it can be very tricky to get an even snap without proper clamping.

![led_matrices_onairbuild-3343.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/988/medium640/led_matrices_onairbuild-3343.jpg?1597088278)

![led_matrices_onairbuild-3346.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/989/medium640/led_matrices_onairbuild-3346.jpg?1597088290)

![led_matrices_onairbuild-3347.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/991/medium640/led_matrices_onairbuild-3347.jpg?1597089259)

![led_matrices_onairbuild-3349.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/992/medium640/led_matrices_onairbuild-3349.jpg?1597089270)

![](https://cdn-learn.adafruit.com/assets/assets/000/093/998/medium800/led_matrices_onairbuild-3352.jpg?1597089308)

Peel away the paper backing from both sides and set the acrylic onto your matrix display with the matte finished side facing out.

![led_matrices_onairbuild-3355.jpg](https://cdn-learn.adafruit.com/assets/assets/000/093/999/medium640/led_matrices_onairbuild-3355.jpg?1597089331)

## Uglu Dashes

The best method we've found for adhering acrylic to the matrix display is to use [Uglu Dashes clear adhesive rectangles from Pro Tapes](https://www.protapes.com/products/uglu-600-dashes-sheets). They are incredibly strong (although can be removed if necessary), easy to apply, and are invisible once attached.

Use one at each corner and one each at the halfway point of the long edges, then press the acrylic and matrix panel together for about 20 seconds.

![adafruit_io_weathermx-2-3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/842/medium640/adafruit_io_weathermx-2-3.jpg?1600463849)

![adafruit_io_weathermx-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/843/medium640/adafruit_io_weathermx-2.jpg?1600463856)

![adafruit_io_weathermx-2-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/844/medium640/adafruit_io_weathermx-2-2.jpg?1600463866)

Here you can see the impact of using the diffusion acrylic. (Pictured here with the ON AIR sign project)

![](https://cdn-learn.adafruit.com/assets/assets/000/094/006/medium800thumb/led_matrices_diffusionOnAir.jpg?1597089757)

## Stand

A very simple and attractive way to display your matrix is with the adjustable [bent-wire stand](https://www.adafruit.com/product/1679).

![led_matrices_onairbuild-3418.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/032/medium640/led_matrices_onairbuild-3418.jpg?1597094067)

![led_matrices_onairbuild-3419.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/033/medium640/led_matrices_onairbuild-3419.jpg?1597094085)

![led_matrices_onairbuild-3421.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/034/medium640/led_matrices_onairbuild-3421.jpg?1597094097)

![led_matrices_onairbuild-3422.jpg](https://cdn-learn.adafruit.com/assets/assets/000/094/035/medium640/led_matrices_onairbuild-3422.jpg?1597094107)

![](https://cdn-learn.adafruit.com/assets/assets/000/095/378/medium800/adafruit_io_led_matrices_onairbuild-3383.jpg?1602006263)

Alternately, you can use a frame, [3D printed brackets](https://learn.adafruit.com/led-protest-sign/build-the-sign#step-3065326), tape, glue, or even large binder clips to secure the acrylic to the sign and then mount it on on a wall, shelf, or display cabinet.

[These mini-magnet feet](https://www.adafruit.com/product/4631) can be used to stick the sign to a ferrous surface.

# LED Matrix Display for Bitmap Pixel Art and Animation

## Sprite Sheet Animation

Thinking about game sprites naturally leads us to think about sprite animation. Let's add that now! Traditional 2D animation in games is usually implemented with something called a **sprite sheet** , so we'll do the same here!

Before we get started with sprite animation, it's important to have a solid foundation in static pixel art creation. If needed, check out this page on [Pixel Art Fundamentals](https://learn.adafruit.com/makecode-arcade-pixel-art-sprites/pixel-art-fundamentals) first.

![](https://cdn-learn.adafruit.com/assets/assets/000/075/120/medium800/gaming_screenPixels.jpg?1556726980)

## Animation Basics

Animation is a HUGE topic! It can be overwhelming, in fact, to consider all there is that goes into creating beautiful animation. The good thing is that we can keep it very simple and still learn a lot and get going fast.

At its most basic, animation is the illusion of motion our brains trick us into perceiving when we view multiple still frames of artwork played back in quick succession. A flipbook you can doodle in the corner of your notebook is a great example of how this works and how simple it can be.

![](https://cdn-learn.adafruit.com/assets/assets/000/075/135/medium800thumb/gaming_flipbookBall_03.jpg?1556837812)

Typical film animation is created with somewhere between 12 and 24 unique frames per second, which can give it an incredibly fluid look, but is a heck of a lot of work, too!

![](https://cdn-learn.adafruit.com/assets/assets/000/075/138/medium800/gaming_rwWalk.jpg?1556818329 from The Animator's Survival Kit by Richard Williams)

![](https://cdn-learn.adafruit.com/assets/assets/000/075/139/medium800thumb/gaming_mei_walk.jpg?1556819360)

## Game Animation Frames

Pixel sprite animation used in games is normally created with many fewer frames of animation. This means we can typically get away with creating just a handful of unique sprites to convey the action.&nbsp;

One cycle of a character walking may contain just six frames/sprites in a simple game style, and up to twelve or so frames for a more fluid style.

Here's a terrific example from Pedro Medeiros's [MiniBoss Studios tutorial set available here](https://studiominiboss.itch.io/pixel-art-tutorials).

![](https://cdn-learn.adafruit.com/assets/assets/000/095/530/medium800thumb/led_matrices_Walk.jpg?1602259410)

Let's take that example and animate it to walk across the screen. I'll use Aseprite to create the animation, adding left-to-right translation so it doesn't happen standing in place, then we'll look at how to turn it into a sprite sheet for use on the Matrix Portal.

## Walk Across the Screen

Here I've taking that miniboss example page and used Aseprite to re-create the animation, adding left-to-right translation so it doesn't happen standing in place.

When exported as a .gif animation we can play it in the browser as shown below.

![led_matrices_miniboss_walk_big.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/555/medium640/led_matrices_miniboss_walk_big.jpg?1602268155)

![](https://cdn-learn.adafruit.com/assets/assets/000/095/554/medium800/led_matrices_bosswalk_bg_big.gif?1602267866)

## Sprite Sheet

Now, let's create a sprite sheet for use on the Matrix Portal display. A sprite sheet is a lot like a traditional film strip, it is a long (or wide, or gridded) strip of images, with each image representing a frame of animation.

In Aseprite, I've used the **File \> Export Sprite Sheet** command to take the entire animation and stitch it into a long, vertical sprite sheet.

Warning: 

## Sprite Sheet

Now, let's create a sprite sheet for use on the Matrix Portal display. A sprite sheet is a lot like a traditional film strip, it is a long (or wide, or gridded) strip of images, with each image representing a frame of animation.

In Aseprite, I've used the **File \> Export Sprite Sheet** command to take the entire animation and stitch it into a long, vertical sprite sheet.

![led_matrices_walk_sheet_dialog1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/556/medium640/led_matrices_walk_sheet_dialog1.jpg?1602268558)

![led_matrices_walk_sheet_dialog3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/558/medium640/led_matrices_walk_sheet_dialog3.jpg?1602268586)

![led_matrices_walk_sheet_dialog4.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/559/medium640/led_matrices_walk_sheet_dialog4.jpg?1602268597)

![led_matrices_walk_sheet_dialog5.jpg](https://cdn-learn.adafruit.com/assets/assets/000/095/560/medium640/led_matrices_walk_sheet_dialog5.jpg?1602268609)

![](https://cdn-learn.adafruit.com/assets/assets/000/095/561/medium800/led_matrices_walk_sheet_dialog2.jpg?1602268622)

Get ready to do some scrolling! Because, this is what the exported sprite sheet looks like:

![](https://cdn-learn.adafruit.com/assets/assets/000/095/562/medium800/led_matrices_miniboss_walk_big_sheet.jpg?1602268672)

Now, when the Matrix Portal uses the TileGrid code, it will essentially march through and display each "frame" of this single image in order to play back the animation! You can think of it like a film strip moving in front of the bulb and shutter of a film projector.

## LED Matrix Version

Here's a version of the walk that I've adapted for the LED Matrix Portal display. It is now 64x32 pixels in size and on a black background to keep the current draw low.

[miniboss_walk_64x32_sheet.bmp.zip](https://cdn-learn.adafruit.com/assets/assets/000/095/572/original/miniboss_walk_64x32_sheet.bmp.zip?1602276053)
![](https://cdn-learn.adafruit.com/assets/assets/000/095/570/medium800/led_matrices_miniboss_walk_64x32.gif?1602269237)

And here it is being played on the LED matrix display.

![](https://cdn-learn.adafruit.com/assets/assets/000/095/571/medium800thumb/led_matrices_miniboss_walk_led.jpg?1602269674)

Primary: 

## Conversion Process Video
https://youtu.be/hHg9qDo0MZI

Next, we'll code the Matrix Portal for sprite sheet animation playback.

# LED Matrix Display for Bitmap Pixel Art and Animation

## Code the Sprite Sheet Animation Display

Make sure you've set up the Matrix Portal with Circuit Python and the necessary libraries as shown on the **Code the Pixel Art Display** page of this guide. This code uses the same libraries.

## Code

Click the Download: Project Zip File link below in the code window to get a zip file with all the files needed for the project. Copy **code.p**** y **from the zip file and place it on the** CIRCUITPY** drive.

You'll also need to copy the following files to the **CIRCUITPY** drive. See the graphic at the top of the page as to filenames and where they go):

- **/bmps** directory, which contains the sprite sheet .bmp files.

## Sprite Sheet Specs

Make sure your sprite sheets are

- .bmp files
- 64 pixels wide
- multiples of 32 pixels high, depending on how many frames there are
- Export as vertical sprite sheets with no border padding. The code will use these dimensions to display the tiles

![](https://cdn-learn.adafruit.com/assets/assets/000/095/574/medium800/led_matrices_blobbo4_sheet.jpg?1602276761)

![](https://cdn-learn.adafruit.com/assets/assets/000/095/573/medium800/led_matrices_sheet_explainer-0002.gif?1602276689)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Matrix_Sprite_Animation_Player/code.py

## How it Works

### Libraries

Here's how the code works. First we import necessary libraries including `dislpayio` and `adafruit_matrixportal` to handle the TileGrid display.

### Variables

We use a few variables that are user adjustable to fine tune the way the playback works. `DEFAULT_FRAME_DURATION = 0.1` sets the frame-rate to 10fps, a good starting point, as it mimics the default playback rate in many pixel animation programs.

You can also set your own framerate overrides per sprite sheet as shown here:

```python
FRAME_DURATION_OVERRIDES = {
    "three_rings1-sheet.bmp": 0.15,
    "hop1-sheet.bmp": 0.05,
    "firework1-sheet.bmp": 0.03,
}
```

The `AUTO_ADVANCE_LOOPS = 3` variable specifies how many times to run through each animation before advancing to the next one.

### Setup

The display and button setups are next, followed by some variables used to track the state of the playback later.

```python
# --- Display setup ---
matrix = Matrix(bit_depth=4)
sprite_group = displayio.Group(max_size=1)
matrix.display.root_group = sprite_group

# --- Button setup ---
pin_down = DigitalInOut(board.BUTTON_DOWN)
pin_down.switch_to_input(pull=Pull.UP)
button_down = Debouncer(pin_down)
pin_up = DigitalInOut(board.BUTTON_UP)
pin_up.switch_to_input(pull=Pull.UP)
button_up = Debouncer(pin_up)

auto_advance = True

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
```

### Image Loading Fuction

The` load_image()` function is where the first part of the sprite sheet magic happens! The key moment is where the displayio.TileGrid is defined to set the `tile_height = matrix.display.height  `which in the case of our dislpay is 32 pixels. This effectively slices up the sprite sheet into the individual frames for display.

```python
def load_image():
    """
    Load an image as a sprite
    """
    # pylint: disable=global-statement
    global current_frame, current_loop, frame_count, frame_duration
    while sprite_group:
        sprite_group.pop()

    bitmap = displayio.OnDiskBitmap(
        open(SPRITESHEET_FOLDER + "/" + file_list[current_image], "rb")
    )

    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]]

    sprite = displayio.TileGrid(
        bitmap,
        pixel_shader=displayio.ColorConverter(),
        width=1,
        height=1,
        tile_width=bitmap.width,
        tile_height=matrix.display.height,
    )

    sprite_group.append(sprite)
    current_frame = 0
    current_loop = 0
```

The advance\_image() function is used to select the next sprite sheet when it is time.

```python
def advance_image():
    """
    Advance to the next image in the list and loop back at the end
    """
    # pylint: disable=global-statement
    global current_image
    if current_image is not None:
        current_image += 1
    if current_image is None or current_image &gt;= len(file_list):
        current_image = 0
    load_image()
```

And, the final part of setup is the creation of the advance\_frame() function, which allows the sprite sheet to move from "frame" to "frame" as it works it's way down the sprite sheet.

```python
def advance_frame():
    """
    Advance to the next frame and loop back at the end
    """
    # pylint: disable=global-statement
    global current_frame, current_loop
    current_frame = current_frame + 1
    if current_frame &gt;= frame_count:
        current_frame = 0
        current_loop = current_loop + 1
    sprite_group[0][0] = current_frame
```

## Main Loop

The main loop of the program runs the advance image and advance frame functions, while also checking for button\_down and button\_up events.

The Up button stops the auto advance from animation to animations, constantly looping just one animation.

The Down button advances manually to the next animation.

```python
while True:
    if auto_advance and current_loop &gt;= AUTO_ADVANCE_LOOPS:
        advance_image()
    button_down.update()
    button_up.update()
    if button_up.fell:
        auto_advance = not auto_advance
    if button_down.fell:
        advance_image()
    advance_frame()
    time.sleep(frame_duration)
```

https://youtu.be/03E1Sv8sRQQ


## Featured Products

### Adafruit Matrix Portal - CircuitPython Powered Internet Display

[Adafruit Matrix Portal - CircuitPython Powered Internet Display](https://www.adafruit.com/product/4745)
Folks love our [wide selection of RGB matrices](https://www.adafruit.com/category/327) and accessories, for making custom colorful LED displays... and our RGB Matrix Shields and FeatherWings can be quickly soldered together to make the wiring much easier. But what if we made it...

In Stock
[Buy Now](https://www.adafruit.com/product/4745)
[Related Guides to the Product](https://learn.adafruit.com/products/4745/guides)
### Black LED Diffusion Acrylic Panel 12" x 12" - 0.1" / 2.6mm thick

[Black LED Diffusion Acrylic Panel 12" x 12" - 0.1" / 2.6mm thick](https://www.adafruit.com/product/4594)
A nice whoppin' slab of some lovely black acrylic to add some extra diffusion to your LED Matrix project. This material is 2.6mm (0.1") thick and is made of special cast acrylic that makes it perfect for glowy projects, especially matricies or NeoPixels.

Unlike smoke or...

In Stock
[Buy Now](https://www.adafruit.com/product/4594)
[Related Guides to the Product](https://learn.adafruit.com/products/4594/guides)
### 5V 2.5A Switching Power Supply with 20AWG MicroUSB Cable

[5V 2.5A Switching Power Supply with 20AWG MicroUSB Cable](https://www.adafruit.com/product/1995)
Our all-in-one 5V 2.5 Amp + MicroUSB cable power adapter is the perfect choice for powering single-board computers like Raspberry Pi, BeagleBone, or anything else that's power-hungry!

This adapter was specifically designed to provide 5.25V, not 5V, but we still call it a 5V USB...

In Stock
[Buy Now](https://www.adafruit.com/product/1995)
[Related Guides to the Product](https://learn.adafruit.com/products/1995/guides)
### Micro B USB to USB C Adapter

[Micro B USB to USB C Adapter](https://www.adafruit.com/product/4299)
As technology changes and adapts, so does Adafruit, and speaking of&nbsp;_adapting_, this&nbsp;_ **adapter** _&nbsp;has a Micro B USB jack&nbsp;and a USB C plug.

USB C is the latest industry-standard connector for transmitting data&nbsp;_and_&nbsp;power....

In Stock
[Buy Now](https://www.adafruit.com/product/4299)
[Related Guides to the Product](https://learn.adafruit.com/products/4299/guides)
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

Out of Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)

## Related Guides

- [Adafruit MatrixPortal M4](https://learn.adafruit.com/adafruit-matrixportal-m4.md)
- [RGB Matrix Automatic YouTube ON AIR Sign](https://learn.adafruit.com/rgb-matrix-automatic-youtube-on-air-sign.md)
- [Network Connected RGB Matrix Clock](https://learn.adafruit.com/network-connected-metro-rgb-matrix-clock.md)
- [IoT Twitter Listener Party Parrot](https://learn.adafruit.com/iot-twitter-listener-party-parrot.md)
- [Expressive Pixels for Adafruit Matrix Portal](https://learn.adafruit.com/expressive-pixels-for-matrix-portal.md)
- [Halloween Countdown Display Matrix](https://learn.adafruit.com/halloween-countdown-display-matrix.md)
- [Moon Phase Clock for Adafruit Matrix Portal](https://learn.adafruit.com/moon-phase-clock-for-adafruit-matrixportal.md)
- [Star Trek LCARS Display](https://learn.adafruit.com/star-trek-lcars-display.md)
- [Weather Display Matrix](https://learn.adafruit.com/weather-display-matrix.md)
- [Use an art canvas to diffuse an RGB matrix](https://learn.adafruit.com/use-an-art-canvas-to-diffuse-rgb-matrix.md)
- [ Memory-saving tips for CircuitPython](https://learn.adafruit.com/memory-saving-tips-for-circuitpython.md)
- [Matrix Portal Creature Eyes](https://learn.adafruit.com/matrix-portal-creature-eyes.md)
- [Image Correction for RGB LED Matrices](https://learn.adafruit.com/image-correction-for-rgb-led-matrices.md)
- [Matrix Portal Flow Visualizer](https://learn.adafruit.com/matrix-portal-flow-visualizer.md)
- [Cardboard Window Skull With Animated LED Eyes](https://learn.adafruit.com/cardboard-window-skull-animated-led-eyes.md)
- [Adafruit Protomatter RGB Matrix Library](https://learn.adafruit.com/adafruit-protomatter-rgb-matrix-library.md)
