NeoMatrix Square Pixels

Build a square pixel display with Adafruit's 8x8 NeoMatrix and Feather M4. Use Black LED acrylic and 3D printed grid to create an evenly diffused LED effect. Electronics are housed in an elegant looking snap fit case with built-in on/off switch. LED animations are easily customizable with CircuitPython.


Adafruit Feather M4 Express - Featuring ATSAMD51
It's what you've been waiting for, the Feather M4 Express featuring ATSAMD51. This Feather is fast like a swift, smart like an owl, strong like a ox-bird (it's half ox,...
Out of Stock
Black LED Diffusion Acrylic Panel 12" x 12" - 0.1" / 2.6mm thick
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...
In Stock
Adafruit NeoPixel NeoMatrix 8x8 - 64 RGB LED Pixel Matrix
Put on your sunglasses before wiring up this LED matrix - 64 eye-blistering RGB LEDs adorn the NeoMatrix for a blast of configurable color. Arranged in an 8x8 matrix, each pixel is...
In Stock
FeatherWing Proto - Prototyping Add-on For All Feather Boards
A Feather board without ambition is a Feather board without FeatherWings!This is the FeatherWing Proto - a prototyping add-on for all Feather boards. Using our...
In Stock
1 x 1200mAh Battery
3.7V Lipo Battery
1 x Slide Switch
Slide Switch
1 x Header Kit for Feathers
12-pin and 16-pin Female Headers
1 x 10-Wire Ribbon Cable
28AWG Silicone Cover Stranded Core
1 x JST PH 3-Pin Socket
Color Coded Cable - 200mm
1 x M2.5 Hardware Kit
Black Nylon Screw and Stand-off Set
1 x USB Cable
Fully Reversible Pink/Purple USB A to micro B Cable - 1m

The diagram below provides a visual reference for wiring of the components. This diagram was created using the software package Fritzing.

Adafruit Library for Fritzing

Use Adafruit's Fritzing parts library to create circuit diagrams for your projects. Download the library or just grab individual parts. Get the library and parts from GitHub - Adafruit Fritzing Parts.

Wired Connections

The Feather M4 Express is installed on top of the Proto FeatherWing using Headers. The NeoMatrix is wired to the Proto FeatherWing so that the Feather can be easily swapped.

  • 5V from NeoMatrix to 3V on Proto FeatherWing
  • GND from NeoMatrix to GND on Proto FeatherWing
  • DIN from NeoMatrix to Pin #6 on Proto FeatherWing
  • Switch to EN and GND on Proto FeatherWing


The Adafruit board can be powered via USB or JST using a 3.7v lipo battery. In this project, a 1200mAh lipo battery is used. The lipo battery is rechargeable via the USB port on the board. The switch is wired to the enable and ground pins on the board.

Parts List

STL files for 3D printing are oriented to print "as-is" on FDM style machines. Parts are designed to 3D print without any support material. Original design source may be downloaded using the links below.

File names

  • cover.stl
  • pcb-mount.stl
  • neomatrix-grid.stl
  • acrylic.stl

CAD assembly

The Proto FeatherWing is secured to the pcb-mount with M2.5 hardware screws (standoffs are optional). The Feather M4 snaps into the female headers on the Proto FeatherWing. The NeoMatrix is fitted into the built-in standoffs in the pcb-mount. The neomatrix-grid is fitted over the NeoMatrix PCB. The piece of acrylic is placed inside the cover. The cover is fitted over the neomatrix-grid and snap fits onto the edges of the pcb-mount.

Slicing Parts

No supports are required. Slice with setting for PLA material. 

The parts were sliced using CURA using the slice settings below.

  • PLA filament 220c extruder
  • 0.2 layer height
  • 10% gyroid infill
  • 60mm/s print speed
  • 60c heated bed

Design Source Files

The project assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, STL and more. Electronic components like Adafruit's board, displays, connectors and more can be downloaded from the Adafruit CAD parts GitHub Repo.

CircuitPython is a derivative of MicroPython 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.

The following instructions will show you how to install CircuitPython. If you've already installed CircuitPython but are looking to update it or reinstall it, the same steps work for that as well!

Set up CircuitPython Quick Start!

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

Click the link above and download the latest UF2 file.

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

Plug your Feather 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 next to the USB connector on your board, and you will see the NeoPixel RGB LED turn green. If it turns red, check the USB cable, try another USB port, etc. Note: The little red LED next to the USB connector will pulse red. That's ok!

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

You will see a new disk drive appear called FEATHERBOOT.




Drag the adafruit_circuitpython_etc.uf2 file to FEATHERBOOT.

The LED will flash. Then, the FEATHERBOOT drive will disappear and a new disk drive called CIRCUITPY will appear.

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

Further Information

For more detailed info on installing CircuitPython, check out Installing CircuitPython.

As we continue to develop CircuitPython and create new releases, we will stop supporting older releases. Visit to download the latest version of CircuitPython for your board. You must download the CircuitPython Library Bundle that matches your version of CircuitPython. Please update CircuitPython and then visit to download the latest Library Bundle.

Each CircuitPython program you run needs to have a lot of information to work. The reason CircuitPython is so simple to use is that most of that information is stored in other files and works in the background. These files are called libraries. Some of them are built into CircuitPython. Others are stored on your CIRCUITPY drive in a folder called lib. Part of what makes CircuitPython so awesome is its ability to store code separately from the firmware itself. Storing code separately from the firmware makes it easier to update both the code you write and the libraries you depend.

Your board may ship with a lib folder already, it's in the base directory of the drive. If not, simply create the folder yourself. When you first install CircuitPython, an empty lib directory will be created for you.

CircuitPython libraries work in the same way as regular Python modules so the Python docs are a great reference for how it all should work. In Python terms, we can place our library files in the lib directory because its part of the Python path by default.

One downside of this approach of separate libraries is that they are not built in. To use them, one needs to copy them to the CIRCUITPY drive before they can be used. Fortunately, we provide a bundle full of our libraries.

Our bundle and releases also feature optimized versions of the libraries with the .mpy file extension. These files take less space on the drive and have a smaller memory footprint as they are loaded.

Installing the CircuitPython Library Bundle

We're constantly updating and improving our libraries, so we don't (at this time) ship our CircuitPython boards with the full library bundle. Instead, you can find example code in the guides for your board that depends on external libraries. Some of these libraries may be available from us at Adafruit, some may be written by community members!

Either way, as you start to explore CircuitPython, you'll want to know how to get libraries on board.

You can grab the latest Adafruit CircuitPython Bundle release by clicking the button below.

Note: Match up the bundle version with the version of CircuitPython you are running - 3.x library for running any version of CircuitPython 3, 4.x for running any version of CircuitPython 4, etc. If you mix libraries with major CircuitPython versions, you will most likely get errors due to changes in library interfaces possible during major version changes.

If you need another version, you can also visit the bundle release page which will let you select exactly what version you're looking for, as well as information about changes.

Either way, download the version that matches your CircuitPython firmware version. If you don't know the version, look at the initial prompt in the CircuitPython REPL, which reports the version. For example, if you're running v4.0.1, download the 4.x library bundle. There's also a py bundle which contains the uncompressed python files, you probably don't want that unless you are doing advanced work on libraries.

After downloading the zip, extract its contents. This is usually done by double clicking on the zip. On Mac OSX, it places the file in the same directory as the zip.

Open the bundle folder. Inside you'll find two information files, and two folders. One folder is the lib bundle, and the other folder is the examples bundle.

Now open the lib folder. When you open the folder, you'll see a large number of mpy files and folders

Example Files

All example files from each library are now included in the bundles, as well as an examples-only bundle. These are included for two main reasons:

  • Allow for quick testing of devices.
  • Provide an example base of code, that is easily built upon for individualized purposes.

Copying Libraries to Your Board

First you'll want to create a lib folder on your CIRCUITPY drive. Open the drive, right click, choose the option to create a new folder, and call it lib. Then, open the lib folder you extracted from the downloaded zip. Inside you'll find a number of folders and .mpy files. Find the library you'd like to use, and copy it to the lib folder on CIRCUITPY.

This also applies to example files. They are only supplied as raw .py files, so they may need to be converted to .mpy using the mpy-cross utility if you encounter MemoryErrors. This is discussed in the CircuitPython Essentials Guide. Usage is the same as described above in the Express Boards section. Note: If you do not place examples in a separate folder, you would remove the examples from the import statement.

If a library has multiple .mpy files contained in a folder, be sure to copy the entire folder to CIRCUITPY/lib.

Example: ImportError Due to Missing Library

If you choose to load libraries as you need them, you may write up code that tries to use a library you haven't yet loaded.  We're going to demonstrate what happens when you try to utilise a library that you don't have loaded on your board, and cover the steps required to resolve the issue.

This demonstration will only return an error if you do not have the required library loaded into the lib folder on your CIRCUITPY drive.

Let's use a modified version of the blinky example.

import board
import time
import simpleio

led = simpleio.DigitalOut(board.D13)

while True:
    led.value = True
    led.value = False

Save this file. Nothing happens to your board. Let's check the serial console to see what's going on.

We have an ImportError. It says there is no module named 'simpleio'. That's the one we just included in our code!

Click the link above to download the correct bundle. Extract the lib folder from the downloaded bundle file. Scroll down to find simpleio.mpy. This is the library file we're looking for! Follow the steps above to load an individual library file.

The LED starts blinking again! Let's check the serial console.

No errors! Excellent. You've successfully resolved an ImportError!

If you run into this error in the future, follow along with the steps above and choose the library that matches the one you're missing.

Library Install on Non-Express Boards

If you have a Trinket M0 or Gemma M0, you'll want to follow the same steps in the example above to install libraries as you need them. You don't always need to wait for an ImportError as you probably know what library you added to your code. Simply open the lib folder you downloaded, find the library you need, and drag it to the lib folder on your CIRCUITPY drive.

You may end up running out of space on your Trinket M0 or Gemma M0 even if you only load libraries as you need them. There are a number of steps you can use to try to resolve this issue. You'll find them in the Troubleshooting page in the Learn guides for your board.

Updating CircuitPython Libraries/Examples

Libraries and examples are updated from time to time, and it's important to update the files you have on your CIRCUITPY drive.

To update a single library or example, follow the same steps above. When you drag the library file to your lib folder, it will ask if you want to replace it. Say yes. That's it!

A new library bundle is released every time there's an update to a library. Updates include things like bug fixes and new features. It's important to check in every so often to see if the libraries you're using have been updated.


This project uses the LED animation rainbow example code from the CircuitPython LED Animation guide. The code is modified slightly to accommodate the additional pixels used in the sign.

Download the Adafruit CircuitPython Library Bundle

In order to run the code, we'll need to download a few libraries. Libraries contain code to help interface with hardware a lot easier for us.

Use the Adafruit M4 Express page on Installing Libraries to get the library that matches the major version of CircuitPython you are using noted above.

To run the code for this project, we need the three libraries in the Required Libraries list below. Unzip the library bundle and search for the libraries. Drag and drop the files into a folder named lib on the CIRCUITPY drive (which appears when your board is plugged into your computer via a known good USB cable) if the directory is not already on the Feather M4 Express).

Required Libraries 

  • neopixel.mpy
  • adafruit_led_animation

The Mu Python Editor

Mu is a simple Python editor that works with Adafruit CircuitPython hardware. It's written in Python and works on Windows, MacOS, Linux and Raspberry Pi. The serial console is built right in, so you get immediate feedback from your board's serial output! While you can use any text editor with your code, Mu makes it super simple. Instructions for Mu are available here.

Installing or upgrading CircuitPython

You should ensure you have CircuitPython 5.0 or greater on your board. Plug your board in with a known good data + power cable (not the cheesy USB cable that comes with USB power packs, they are power only). You should see a new flash drive pop up.

If the drive is CIRCUITPY, then open the boot_out.txt file to ensure the version number is 5.0 or greater. 

Adafruit CircuitPython 5.3.1 on 2020-07-13; Adafruit Feather M4 Express with samd51j19

Click on the download link below to grab the project code directly from GitHub.

# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT

This example shows usage of the PixelMap helper to easily treat a single strip as a horizontal or
vertical grid for animation purposes.

For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using
a different form of NeoPixels. Note that if you are using a number of pixels other than 32, you
will need to alter the PixelMap values as well for this example to work.

This example does not work on SAMD21 (M0) boards.
import board
import neopixel

from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from import Chase
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation import helper
from adafruit_led_animation.color import PURPLE, JADE, AMBER

# Update to match the pin connected to your NeoPixels
pixel_pin = board.D6
# Update to match the number of NeoPixels you have connected
pixel_num = 32

pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.5, auto_write=False)

pixel_wing_vertical = helper.PixelMap.vertical_lines(
    pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False)
pixel_wing_horizontal = helper.PixelMap.horizontal_lines(
    pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False)

comet_h = Comet(
    pixel_wing_horizontal, speed=0.1, color=PURPLE, tail_length=3, bounce=True
comet_v = Comet(pixel_wing_vertical, speed=0.1, color=AMBER, tail_length=6, bounce=True)
chase_h = Chase(pixel_wing_horizontal, speed=0.1, size=3, spacing=6, color=JADE)
rainbow_chase_v = RainbowChase(
    pixel_wing_vertical, speed=0.1, size=3, spacing=2, step=8
rainbow_comet_v = RainbowComet(
    pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True
rainbow_v = Rainbow(pixel_wing_vertical, speed=0.1, period=2)
rainbow_chase_h = RainbowChase(pixel_wing_horizontal, speed=0.1, size=3, spacing=3)

animations = AnimationSequence(

while True:

Adjust Code

Look for the following lines in the code and adjust to fit the 8x8 NeoMatrix. Use any text editor or favorite IDE to modify the code. We suggest using Mu as noted above.

# Update to match the pin connected to your NeoPixels
pixel_pin = board.D6
# Update to match the number of NeoPixels you have connected
pixel_num = 64

pixel_wing_vertical = helper.PixelMap.vertical_lines(
    pixels, 8, 8, helper.horizontal_strip_gridmap(8, alternating=False)
pixel_wing_horizontal = helper.PixelMap.horizontal_lines(
    pixels, 8, 8, helper.horizontal_strip_gridmap(8, alternating=False)

Upload Code

Ensure the file is named and drop it onto the CIRCUITPY drive main (root) directory that appears when your Feather is plugged into your computer via a known good USB data cable. The code will run properly when all of the files have been uploaded including libraries.

Customizing LED Animations

Take a moment to walk through the LED animation library for CircuitPython learn guide. The guide covers the how to create animations with horizontal and vertical grids.

Acrylic Template

A piece of stock can be from the 12 x 12in sheet can using a table saw or a scoring tool (plastic cutting knife). Our stock was cut to 114x114m to accommodate the size of the Bantamtools CNC spoilboard. Use the SVG file to CNC mill or laser cut the piece. Optionally print the template for reference.

Desktop CNC

Cutting the Black LED acrylic was done using the Bantam Tools Desktop CNC. This guide covers using Fusion 360 and bantam tools software to cut the acrylic. 

Tool Library

Download the tool library from the Bantam Tools website to use in Fusion 360. Install the library by using the Tool Library in the manufacture workspace. Select Local in the side bar and click the Import libraries icon. Navigate and choose the bantam tools Fusion 360 tool library. Use the 1/8in flat end mill to cut the piece of acrylic.

2D Contour

In Fusion 360 manufacture workspace, create a New Setup and set stock mode as relative size box. Add a 2mm to the stock side offset. Use the 2D contour operation to cut the shape out the material. Under the Tool tab, select the 1/8in flat end mill from the imported tools under Local library. Under the geometry tab, in the contour selection area, click on the lower edge of the model. Under the Passes tab, enable Multiple Depths and add 0.1mm to Maximum Roughing. Use the recommended settings for cutting acrylic with a 1/8in flat end mill. Right click on the setup in the browser select post process. Use the othermill as the processor and name your gcode file accordingly. 

  • Tool: 1/8" flat end mill
  • Feed rate: 59 in/min (1500 mm/min)
  • Plunge rate: 1.81 in/min (46 mm/min)
  • Spindle speed: 16,400 RPM
  • Max pass depth: 0.005" (0.13 mm)


Use the open files button and navigate to the exported gcode file from Fusion 360. Set the material to Generic using the dropdown. Enter the dimensions of your stock acrylic in the material size dropdown. Set the X and Y to 0mm and add a 0.2mm to the Z to accommodate for the double-sided tape used to secure the stock to the spoil board. Offset the placement of the gcode file by 2mm in the X and Y. Set the Z to 0.2mm for stock to leave behind. Select the 1/8in flat end mill. Click start milling button when the stock is secured and the 1/8in end mill is installed and probed.

Feather Headers

The Proto FeatherWing is setup with 12-pin and 16-pin female headers. The Feather M4 Express will have a male strip of headers, 12-pin and 16-pin respectively. 

Wiring Switch

The slide switch is wired up to a piece of ribbon cable with two connections going to the middle pin and either side. The wire was peeled off from a roll of 10-wire ribbon cable. The cable length is approximately 5cm (2in) in length.

Wiring JST Cable

A male (socket plug) 3-pin JST-PH cable is setup to connect to the Proto FeatherWing. This wire was peeled from a roll of 10-wire ribbon cable. The cable length is roughly 8cm (3in) in length.

Wiring Proto FeatherWing

The slide switch and 3-pin JST cable is soldered to the bottom of the Proto FeatherWing PCB.

Switch Wired

The slide switch is wired to the EN and GND pins on the Proto FeatherWing. The wires are soldered from the bottom of the PCB. Reference the pin labels on the top of the PCB.

3-Pin JST-PH Cable

The 3-pin JST-PH cable is wired to 3V, GND and D6 pins on the Proto FeatherWing. The wires are soldered from the bottom of the PCB. Reference the pin labels on the top of the PCB.

Wired Proto FeatherWing

Double check the wiring is correct. 

Wiring NeoMatrix

A 3-pin JST (female socket) cable is wired to the 5V, GND and DIN pins on the NeoMatrix PCB. The red wire is connected to the 5V pin, black to the GND pin and white to the DIN pin on the NeoMatrix. The wires are approximately 5cm (2in) in length. 

Wired NeoMatrix

Double check the wiring is correct. Pieces of heat shrink tubing can be used to keep the wires bundled together.

Test Circuit

With the code and libraries uploaded to the Feather, the circuit should power on. Install the Feather on top of the Proto Feather Wing. Plug in the battery to the Feather. Connect the two JST cables together. Use the slide switch to power the circuit on.

Hardware for Proto FeatherWing

The Proto FeatherWing is secured to the PCB mount using screws and hex nuts. Use the following hardware.

  • 4x M2.5 x 8mm screws
  • 4x M2.5 hex nuts

Install FeatherWing

Place the FeatherWing over the four tabs with the mounting holes lined up. Reference the photo for correct placement. While holding in place, insert M2.5 x 8mm screws into mounting holes on the FeatherWing PCB. 

Secure FeatherWing PCB

Install and fasten the M2.5 hex nuts to threads of the screws to secure the FeatherWing to the PCB mount. The FeatherWing was mounted with the USB port close to the edge. Double check the placement of the PCB with the Feather M4 installed on top of the Proto FeatherWing.

Standoffs (Optional for Battery Power)

For battery power, standoffs will provide clearance for fitting a battery in between the Proto FeatherWing and NeoMatrix PCB. Use eight M.25 x 6mm long screws and 10mm tall M2.5 standoffs to secure the FeatherWing to the mounting tabs on the case.

Install Switch

The slide switch is inserted at an angle into the built in holder. The actuator pokes through the little hole on the side of the mount. The body of the slide switch will stay in place when the NeoMatrix PCB installed. It essentially holds the switch in place preventing it from coming out the top.

Install NeoMatrix

The NeoMatrix PCB is fitted into the pcb mount with the mounting holes lined up with the built-in standoffs. Orient the PCB so the mounting holes are lined up. Reference the photos for correct placement. Place the NeoMatrix PCB over the standoffs and press down so the pegs are fitted into the mounting holes.

Installed NeoMatrix

The built-in standoffs provide approximately 4mm of clearance. This in turn makes the PCB mount thick (11.5mm) but overall a design decision that accommodates for  wiring and connectors.

Install Grid

The grid is designed to fit over the NeoMatrix PCB. The walls in the grid feature cut outs specifically sized for the on-board 0805 capacitors on the NeoMatrix PCB. Orient the grid so the cutouts are lined up with the caps on the PCB. Place the grid over the PCB and press the grid into the PCB mount.

Install Acrylic

The piece of acrylic is press fitted into the cover with the matte side facing down and the glossy side facing up. The lip around the bottom surface keeps the acrylic from falling out.

Install Cover

The cover fits over the grid and PCB mount. Orient the cover so the cutout is lined up with the switch on the PCB mount. Snap fits on the edges grasp onto the nubs on the side of the PCB mount.

Connect NeoMatrix to FeatherWing

Connect the JST cable from the NeoMatrix and Proto FeatherWing together.

USB Power

Connect a USB cable to the USB port on the Feather. Use a computers USB port or USB 5V wall adapter to power the Feather. Optionally use a battery.

Final Build

And there you have it! Enjoy your new square pixel display and create something awesome with it! 

This guide was first published on Aug 18, 2020. It was last updated on Aug 18, 2020.