Build a protest/demonstration sign that can be seen at night. This project makes it simple to use your own graphics on the sign -- it's as easy as dragging and dropping .bmp image files into a folder.

CircuitPython running on the Feather M4 with the RGB Matrix FeatherWing drives any of our RGB LED matrix panels.

You can use the large 6mm pitch version and 3D print the provided brackets to hold LED diffusing plastic. Screw a yardstick or other thin strip of wood to the panel and you can go out and march.

Parts

Adafruit Matrix Portal - CircuitPython Powered Internet Display
Folks love our wide selection of RGB matrices and accessories, for making custom colorful LED displays... and our RGB Matrix Shields...
$24.95
In Stock
64x32 RGB LED Matrix - 6mm pitch
Bring a little bit of Times Square into your home with this sweet 64x32 square RGB LED matrix panel. These panels are normally used to make video walls, here in New York we see them on...
$64.95
In Stock
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
Adafruit RGB Matrix Featherwing Kit
Ahoy! It's time to create a dazzling light up project with our new RGB Matrix FeatherWing. Now you can quickly and easily create...
$7.50
In Stock
8 x AA battery holder with 5.5mm/2.1mm Plug and On/Off Switch
Make a portable power brick with plenty of juice! Use Alkaline AA's for a 12V 3000-4000mAh power supply, or rechargeable NiMH for 2000mAh 9.6V supply. Either one is good for running...
$5.95
In Stock
UBEC DC/DC Step-Down (Buck) Converter - 5V @ 3A output
Your power supply problems just got SOLVED! This little circuit board may look tiny but inside is a high efficiency DC/DC step-down converter which can output up to 3 Amp at 5V without...
$9.95
In Stock
Panel Mount 2.1mm DC barrel jack
This power jack is designed to easily attach to a panel up to 8mm thick (0.315" or 5/16") and fit 2.1mm power plugs snugly and securely. Perfect for adding a power connector...
$2.95
In Stock
5.5 / 2.1mm Barrel Connector - DC Power Plug
DIY? How about D-I-Wire! This barrel jack plug is great for adding a common power connector to the end of your wires. The jack is compatible with 5.5mm barrel jacks that have a...
$0.95
In Stock
Heat Shrink Pack
Heat shrink is the duct tape of electronics, it keeps your stuff all safe and kept together. Especially when wiring and soldering, use heat shrink to add mechanical strength to cables....
$4.95
In Stock
Black Nylon Machine Screw and Stand-off Set – M2.5 Thread
Totaling 380 pieces, this M2.5 Screw Set is a must-have for your workstation. You'll have enough screws, nuts, and hex standoffs to fuel your maker...
Out of Stock

Additional Materials

In addition to the parts above, you'll need:

  • 8 ea. AA NiMH rechargeable batteries
  • A length of 2" x 1/4" wood for a handle, such as a yard stick
  • 6 ea. M3 x 8mm screws for securing the brackets (these can be the typical Phillips head, but I really like hex drive screws)
  • 2 ea. M3 x 12mm screws for attaching the handle
  • Sheet of diffusing acrylic 385mm x 190mm x 3mm such as Chemcast Black LED Acrylic
  • Velcro or double stick foam tape to secure the battery holder
  • Zip ties

3D Printing

For the brackets and Feather cover, you'll need access to a 3D printer and some PLA or similar filament.

Tools

You'll need:

  • screwdriver
  • soldering iron and solder
  • wire strippers
  • hand drill

You can build this project using the Feather M4 Express. For a detailed list of all parts needed for this project, check out the Overview.

64x32 RGB LED Matrix - 6mm pitch
Bring a little bit of Times Square into your home with this sweet 64x32 square RGB LED matrix panel. These panels are normally used to make video walls, here in New York we see them on...
$64.95
In Stock
Adafruit RGB Matrix Featherwing Kit
Ahoy! It's time to create a dazzling light up project with our new RGB Matrix FeatherWing. Now you can quickly and easily create...
$7.50
In Stock

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.

You can build this project with an all-in-one Matrix Portal board, its definitely the easiest and least-expensive way to go about it.

You will need a matrix portal, matrix, and USB C power/data cable

Adafruit Matrix Portal - CircuitPython Powered Internet Display
Folks love our wide selection of RGB matrices and accessories, for making custom colorful LED displays... and our RGB Matrix Shields...
$24.95
In Stock
64x32 RGB LED Matrix - 4mm pitch
Bring a little bit of Times Square into your home with this sweet 64 x 32 square RGB LED matrix panel. These panels are normally used to make video walls, here in New York we see them...
$39.95
In Stock
USB Type A to Type C Cable - approx 1 meter / 3 ft long
As technology changes and adapts, so does Adafruit. This  USB Type A to Type C cable will help you with the transition to USB C, even if you're still...
$4.95
In Stock

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.

Power Terminals

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

  • red wire goes to +5V 
  • black wire goes to GND

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.

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.

 

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

For info on adding LED diffusion acrylic, see the page LED Matrix Diffuser.

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.

Set up CircuitPython Quick Start!

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

Further Information

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

Click the link above and download the latest UF2 file.

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

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!

You will see a new disk drive appear called MATRIXBOOT.

 

Drag the adafruit_circuitpython_etc.uf2 file to MATRIXBOOT.

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

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

As we continue to develop CircuitPython and create new releases, we will stop supporting older releases. Visit https://circuitpython.org/downloads 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 https://circuitpython.org/libraries 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
    time.sleep(0.5)
    led.value = False
    time.sleep(0.5)

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.

Libraries

Once your Feather is set up with CircuitPython 5.3.0 or greater, you'll also need to add some libraries. Follow this page for information on how to download and add libraries to your Feather.

From the library bundle you downloaded in that guide page, transfer the following libraries onto the Feather's /lib directory:

  • adafruit_bus_device
  • adafruit_slideshow.mpy

Text Editor

Adafruit recommends using the Mu editor for using your CircuitPython code with the Feather boards. You can get more info in this guide.

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

Code.py

Copy the code below and paste it into Mu. Then, save it to your Feather as code.py.

import board
import displayio
import framebufferio
import rgbmatrix
from adafruit_slideshow import SlideShow

displayio.release_displays()
matrix = rgbmatrix.RGBMatrix(
    width=64,
    height=32,
    bit_depth=5,
    rgb_pins=[board.D6, board.D5, board.D9, board.D11, board.D10, board.D12],
    addr_pins=[board.A5, board.A4, board.A3, board.A2],
    clock_pin=board.D13,
    latch_pin=board.D0,
    output_enable_pin=board.D1,
)

display = framebufferio.FramebufferDisplay(matrix, auto_refresh=True)

slideshow = SlideShow(
    display,
    backlight_pwm=None,
    folder="/images",
    loop=True,
    order=0,
    fade_effect=False,
    dwell=8,
    auto_advance=True,
)


while slideshow.update():
    pass

The code is quite short! We are using the displayio library along with framebufferio and rgbmatrix to do the heavy lifting.

The adafruit_slideshow library makes it simple to auto-play any images in the specified folder. Here's more detail on how to use SlideShow.

Image Files

You can get started using the included image files, or make your own.

From the project .zip, drag the images folder onto the Feather's CIRCUITPY drive.

The program will automatically use any .bmp files in the /images directory. Make sure they have legal names (no spaces or weird characters!) and are 64x32 pixel .bmp files. 16-bit or 24-bit both work fine.

Now we'll assemble the sign. These steps include:

  • Powering the LED panel and Feather/FeatherWing
  • Connecting the Feather and FeatherWing to the panel
  • 3D printing brackets to attach the diffusion plastic
  • Attaching a handle

Power

The panel draws about 2A of current at 5V. The UBEC (universal battery elimination circuit) is a buck converter that will take our roughly ~9.6V of power from the 8 x AA NiMH battery pack and step it down to 5V.

Solder a barrel jack connector so the center leg goes to the positive input wire of the UBEC, and the sleeve leg goes to UBEC ground.

Solder the barrel plug so that the UBEC positive output (red) wire goes to center and the ground to sleeve.

You can then protect the entire circuit with a length of heat shrink tubing as shown here.

Battery Pack

Use Velcro or double-stick foam tape to secure the battery pack, to the sign handle as shown. Make sure to adhere the back side of the battery pack, leaving the lid free to replace batteries as needed.

Add Handle

Measure and mark for two ~3mm holes on the top of the handle. Then drill these out and secure the handle using the two M3 x 12mm screws.

Feather Prep

Solder male header pins under the Feather as shown here. The Feather will stack on top of the RGB Matrix FeatherWing

3D print the Feather protector linked below and then use short M2.5 standoffs and screws to secure the Feather to it.

FeatherWing Prep

Solder female headers to the top of the FeatherWing as shown, and the box header to the underside. This will allow us to stack the Feather on top of the FeatherWing and plug the show shebang into the panel.

Screw the red and black power wires to the terminal block's positive and ground connections respectively. This cable will plug into the power connector on the matrix panel.

Connect to Sign

Plug the FeatherWing into the sign's IDC connector -- make sure to orient it as shown in the photo! (The added resistor and Kapton tape are present due to a reset fix for the gen. 1 board).

Then, stack the Feather on top of the FeatherWing.

Connect the battery pack to the UBEC buck converter and then to the power input of the FeatherWing.

Plug the RGB Matrix FeatherWing power output cable into the panel as shown, and then neaten and secure the UBEC and power wiring with a couple of zip ties.

Add Batteries

Throw in a freshly recharged set of NiMH batteries -- these should last about 2-3 hours of constant sign use with typical graphics (full white on all LEDs is the worst case scenario and will deplete the batteries in about an hour), so carry an extra set if you need.

The sign will definitely work in this state, but let's go the extra step and add a sheet of LED diffusion acrylic. This offers the LEDs some protection, and makes the sign much easier to see, especially on video and in pictures. 3D print one set of the brackets linked here to hold the sheet in place.

Diffusion Sheet

Lay the diffusion plastic sheet on top of the LED panel as shown with the matte side up.

Slide the 3D printed brackets on, then flip the sign over and fasten them in with the M3 x 8mm screws.

This guide was first published on Jun 23, 2020. It was last updated on Jun 23, 2020.