Create a handheld, interactive NeoPixel control station with your PyGamer (or PyBadge/PyBadge LC) to set colors and animation on your RGB LEDs!

Using the on-board JST connector, its simple to plug in a NeoPixel strip and control it from the PyBadge. Using MakeCode Arcade, we'll build an interface for setting the NeoPixel strip length, and then be able to hover our cursor over 15 color swatches to quickly change the strip colors.

A second control page allows us to switch between NeoPixel animations.

And, you can use the settings page to change the number of NeoPixels to use on your strip.


Adafruit NeoPixel LED Strip with 3-pin JST PH Connector lit up rainbow
Plug in and glow, this Adafruit NeoPixel LED Strip with JST PH Connector has 30 total LEDs in a "60 LED per meter" spacing,...
In Stock
Angled shot of Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino.
What fits in your pocket, is fully Open Source, and can run CircuitPython, MakeCode Arcade or Arduino games you write yourself? That's right, it's the Adafruit...
Out of Stock
Adafruit PyGamer Starter Kit with PCB, enclosure, buttons, and storage bag
Please note: you may get a royal blue or purple case with your starter kit (they're both lovely colors)What fits in your pocket, is fully Open...
Out of Stock
Lithium Ion Polymer Battery 3.7v 350mAh with JST 2-PH connector and short cable
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This...
Out of Stock
Angled shot of a Adafruit PyBadge for MakeCode Arcade, CircuitPython, or Arduino.
What's the size of a credit card and can run CircuitPython, MakeCode Arcade or Arduino? That's right, its the Adafruit PyBadge! We wanted to see how much we...
Out of Stock
Angled Shot of Adafruit PyBadge - Low Cost.
What's the size of a credit card and can run CircuitPython, MakeCode Arcade or Arduino even when you're on a budget? That's right, it's the Adafruit...
Out of Stock

There are lots of ways to plug things into the PyGamer and PyBadge boards, including the Feather header pins, two JST connectors, and STEMMA connector. We'll use a NeoPixel strip that terminates in the three pin JST connector so we can plug it directly into one of the two JST ports.

The JST connectors on the PyGamer allow us to access pins D2 and D3 (these are also analog A8 & A9, incidentally). We'll plug our NeoPixel strip into the JST port marked D3. This will provide us with power, ground, and data for the NeoPixels.

The JST connector is keyed, or polarized, so it can only fit in one way.

Looking at the back side of the board, we'll use the three-pin JST port on the right side, which is labeled "D3".

Go ahead and plug in the JST connector.

MakeCode Arcade

MakeCode Arcade is a free Microsoft block programming environment designed specifically to make games, but we can also use it for non-game application development. Learning to use MakeCode is easy & fun.

If you're not already familiar with the basics of MakeCode Arcade, check out this guide on creating a character sprite and moving it with controls.

To start, open a new Chrome browser window (Chrome works best) and go to MakeCode Arcade.

These MakeCode Arcade guides are designed to take you through the fundamentals before tackling more complex games -- even though this NeoPixel Strip Control isn't a game, most of the techniques apply:

For intermediate-level techniques, check out:

Only use the Google Chrome browser with MakeCode!

NeoPixel Strip Control

To begin, let's load the code and check it out.

Start by launching MakeCode Arcade using the Google Chrome web browser. Then, download the led_strips_arcade-PyGamer-NeoPixel-Controller.png image cartridge file above by right-clicking on the image and saving it to your computer.

Load the Code

This is a special .png file that contains not only an image, but the entire game is embedded in it as well!

Simply drag it from the location to which you saved the image on your computer (such as the desktop as shown here) onto the Chrome browser window that is already running MakeCode Arcade (MCA). Note that the image in this graphic is of a different game, but you'll be dragging the NeoPixel_Strip.png file.

This will open the code into the MCA editor.

If you're ever unsure where a MakeCode block comes from, you can often find it by matching the block's color to a category on the left side of the editor. You can also use the handy search function!

Application Design

This is the overview of how the NeoPixel Controller application will work. We'll start with the concept of pages.





We'll organize the functionality into a settings page, color picker page, and animation page.

The user can press the Select, A, and B buttons, respectively, to move between these pages.

The thumbstick will control the cursor on all three pages, and by simply hovering over the counter arrows, color swatches, and animation icons, they can adjust things. It's quick, easy, and efficient!


Since MakeCode Arcade has lots of capabilities around using sprites, that's how we'll develop our user interface (UI) elements. Each arrow, color swatch, and animation icon used will be its own sprite. The player will control the cursor sprite with the thumbstick.

By using on sprite of kind Player overlaps other sprite of kind ___ blocks, we can set up a unique event to occur based on any selection. For example, if the user is on the color picker page, when the Player cursor sprite overlaps the swatch_orange sprite, the NeoPixels will be set to orange.


Each time the user switches pages, we need to clear the sprites from the previous page. To facilitate this, we'll create arrays of sprites each time a page is made. Then, we can loop through that array to run the destroy sprite block on each sprite.

Test Drive

Upload the code to you PyGamer. When the PyGamer starts up it'll give you instructions on using the NeoPixel Controller -- you can move the cursor to the up or down arrows on the tens and ones places to specify the number of NeoPixels in your strip -- the default is 30.

Then, press A to switch to the color swatch picker page, then move the cursor to light up your strip.

Press B to use the animation picker page -- the strip will play whichever animation your cursor is hovering over!


This program makes use of some extensions to MakeCode Arcade: Feather, SevenSeg and Light.

If you're starting from scratch, Head to Advanced > Extensions + and then click on those two extensions to add them to your session. If you're opening the provided .png image cartridge there's no need, they're already added to the session.

Feather Pins

The Feather extension gives us access to many digital and analog input and output pins on the PyGamer, including the D3 pin on the JST port we'll use.

Code Tour

To keep the code organized, function blocks are used throughout the program. You can start with the on start block and look at the code and functions it calls.

Here's what happens on start:

  • Set the background image to a custom sprite of a NeoPixel strip
  • splash screen with the application title
  • show long text with instructions on the settings page, color picker page, and animation page
  • call pixelCounterSetup function which creates the counter digits
  • set the background image to black
  • create a variable called page with a value of 0
  • call pageSetup function with a parameter value the page variable (in this case 0) which makes the settings page, and then calls the arrowSetup function to create the arrow sprites over and under the digits
  • set bright_strip variable to 60 which will be used to control the strip brightness
  • set bright_onboard variable to 10 which will be used to control the onboard NeoPixel brightness on the board
  • call StripSetup function with a parameter value of the value the myCounter seven segment counter is set to
  • call cursorSetup function

At this point, the NeoPixels are setup (and lit white) and the user is on the settings page where they can adjust the strip's LED count.

Pressing A or B will call the pageSetup functions necessary to clean the screen and build the sprites for the next page.

Now, all the user needs to do is hover the cursor over a color swatch or animation and be transported into a magically colorful world of RGB goodness!

You are at the bleeding edge of handheld, open source, game playing hardware and software, what with your PyBadge/PyBadge LC or PyGamer! Congratulations! It's fun and exciting! It is also changing and improving all the time, so please update your bootloaders before proceeding to put your MakeCode Arcade games on the board!!

Among lots of other reasons, update the bootloader to prevent a problem with MacOS 10.14.4, to fix button problems, and get the thumbstick to work!

PyBadge/PyBadge LC Bootloader

If you have a PyBadge or PyBadge LC, please go to this page for instructions on updating the bootloader.

A HUUUUUUGE number of people have problems because they pick a 'charge only' USB cable rather than a "Data/Sync" cable. Make 100% sure you have a good quality syncing cable. Srsly, I can't even express how many times people have nearly given up due to a flakey USB cable! Enter Alert Text...

Hardware Checks

If, after updating your board's bootloader, you still think you may have a hardware problem, here's a great way to test out all of the functions. From buttons, to the light sensor, thumbstick (PyGamer only), accelerometer (PyGamer and PyBadge only, not the LC), and more, we've got a super nifty set of hardware test .UF2 files you can use.

Click on the link for your board below for more info and a link to the appropriate UF2 file.

Another way to do a hardware check is with the handy, dandy MakeCode Arcade Basic Hardware Test. This was created with MakeCode Arcade and you can use it to check that your d-pad buttons or thumb joystick can move the yellow face around the screen, and that the A and B buttons work to play a sound (just make sure you have a speaker plugged in to the PyGamer first).

You can open this link to get to it, or download the UF2 file below and drag it onto your board's USB drive in bootloader mode.

Let's load a game! For example, here's a link to Run, Blinka, Run! To open the game in the MakeCode Arcade editor, first, click the share link below. This will allow you to play the game in the browser right away.

Then, click on the Show Code button in the upper left corner. The shows the code for the game, and by clicking the Edit button in the upper right corner, it'll open into the editor where you can upload it to your PyGamer/PyBadge.

Once you have a game working on the MakeCode Arcade web editor, it's time to download it and flash it onto your board.

Please only use the Google Chrome browser with MakeCode! It has WebUSB support and seems to work best

Board Definition

In order to load a game made in MakeCode Arcade onto the PyBadge, first choose the proper board definition inside of MakeCode. Click the ellipsis (...) next to DOWNLOAD and then the Choose Hardware item.

Change Board screen

Click on the image of your board, either the PyBadge/PyBadge LC or the PyGamer

This will cause the game .uf2 file for your particular board to be saved to your hard drive. You only need to do this the first time you use a new board. Thereafter you can simply click the Download button on the MakeCode Arcade editor page.

A HUUUUUUGE number of people have problems because they pick a 'charge only' USB cable rather than a "Data/Sync" cable. Make 100% sure you have a good quality syncing cable. Srsly, I can't even express how many times people have nearly given up due to a flakey USB cable!

Bootloader Mode

Now, we'll put the board into bootloader mode so we can drag on the saved .uf2 file. On the back side of the board you'll see a reset button at the top. Make sure the board is plugged into your computer via USB with a USB micro B to A data cable. Also, be sure the board is turned on.


Then, press the reset button. This will initiate bootloader mode.


When the board is in bootloader mode you'll see a screen similar to this one show up.

Drag and Drop

Now that the board is in bootloader mode, you should see a BADGEBOOT drive show up on your computer as a USB flash drive. Simply drag the arcade game .uf2 file onto the drive.


That's all there is to it! Once the file is copied over the board will restart and launch the game!

Keep an eye on for additional game related content.

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 flash drive to iterate.

The following instructions will show you how to program a PyGamer with the NeoPixel Strip Controller with CircuitPython, instead of MakeCode. The user interface looks a bit different from the MakeCode Arcade version, but perform the same functions.

Set up CircuitPython on PyGamer

If you haven't yet set up your PyGamer with CircuitPython, follow this quick step-by-step page:

You'll also want to install a code editor for use with CircuitPython. Mu is a simple code editor that works with the Adafruit CircuitPython boards. 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!

Mu is our recommended editor - please use it (unless you are an experienced coder with a favorite editor already!)

Install CircuitPython Libraries

You'll need to install a few libraries used by the CircuitPython code.

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  Our introduction guide has a great page on how to install the library bundle for both express and non-express boards.

You should manually install these necessary libraries from the bundle:

  • adafruit_cursorcontrol.mpy
  • cursorcontrol_cursormanager.mpy
  • adafruit_button
  • neopixel

Before continuing make sure your board's lib folder or root filesystem has the above files copied over.

Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.

CircuitPython Usage

To demonstrate the usage of the CursorControl library, we'll use the example below. Save the file below to a file. Then, upload the file to the CIRCUITPY drive.

# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries
# SPDX-License-Identifier: MIT

# PyGamer NeoPixel Strip Control with CusorControl
# Adapted from by Kattni Rembor
import time
import board
from adafruit_button import Button
import displayio
import neopixel
from adafruit_cursorcontrol.cursorcontrol import Cursor
from adafruit_cursorcontrol.cursorcontrol_cursormanager import DebouncedCursorManager

# Set the NeoPixel brightness

# Set up the NeoPixel strip
strip = neopixel.NeoPixel(board.D3, 30, brightness=NEO_BRIGHTNESS)

# Turn off NeoPixels to start

# Create the display
display = board.DISPLAY

# Create the display context
splash = displayio.Group()

# Button colors
RED = (255, 0, 0)
ORANGE = (255, 34, 0)
YELLOW = (255, 170, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
VIOLET = (153, 0, 255)
MAGENTA = (255, 0, 51)
PINK = (255, 51, 119)
AQUA = (85, 125, 255)
WHITE = (255, 255, 255)
OFF = (0, 0, 0)

# Button properties
btn_x = 40
btn_y = 40

spots = [
    {"label": "1", "pos": (0, 5), "size": (btn_x, btn_y), "color": RED},
    {"label": "2", "pos": (40, 5), "size": (btn_x, btn_y), "color": ORANGE},
    {"label": "3", "pos": (80, 5), "size": (btn_x, btn_y), "color": YELLOW},
    {"label": "4", "pos": (120, 5), "size": (btn_x, btn_y), "color": GREEN},
    {"label": "5", "pos": (0, 45), "size": (btn_x, btn_y), "color": CYAN},
    {"label": "6", "pos": (40, 45), "size": (btn_x, btn_y), "color": BLUE},
    {"label": "7", "pos": (80, 45), "size": (btn_x, btn_y), "color": VIOLET},
    {"label": "8", "pos": (120, 45), "size": (btn_x, btn_y), "color": MAGENTA},
    {"label": "9", "pos": (0, 85), "size": (btn_x, btn_y), "color": PINK},
    {"label": "10", "pos": (40, 85), "size": (btn_x, btn_y), "color": AQUA},
    {"label": "11", "pos": (80, 85), "size": (btn_x, btn_y), "color": WHITE},
    {"label": "12", "pos": (120, 85), "size": (btn_x, btn_y), "color": OFF},

buttons = []
for spot in spots:
    button = Button(

# initialize the mouse cursor object
mouse_cursor = Cursor(display, display_group=splash)

# initialize the cursormanager
cursor = DebouncedCursorManager(mouse_cursor)

# Show splash group
display.root_group = splash

prev_btn = None
while True:
    if cursor.is_clicked is True:
        for i, b in enumerate(buttons):
            if b.contains((mouse_cursor.x, mouse_cursor.y)):
                b.selected = True
                print("Button %d clicked" % i)
                prev_btn = b
    elif prev_btn is not None:
        prev_btn.selected = False

After saving the to your CIRCUITPY drive, you should see a cursor appear on your device's display along with 12 colorful buttons.

Move the cursor around by pressing the PyBadge's D-Pad buttons or moving the PyGamer's Joystick!

Move the cursor to a color and press the A button to click one of the buttons on the display. The NeoPixel strand will light up with the button's color.

Changing the cursor's speed

Is the cursor moving too slowly across the display? You can increase (or decrease) the cursor's speed by changing this line:

mouse_cursor = Cursor(display, display_group=splash)


mouse_cursor = Cursor(display, display_group=splash, cursor_speed=10)

Setting a larger cursor_speed will increase the speed of the cursor, setting a smaller cursor_speed will decrease the cursor's speed.

Changing the cursor's size

Having trouble seeing the cursor? You can increase the cursor's size by changing the following line:

mouse_cursor = Cursor(display, display_group=splash)


mouse_cursor = Cursor(display, display_group=splash, cursor_speed=10, scale=2)

Setting a larger scale value will scale the cursor in both dimensions. For example, when scale=2 each pixel will be represented by 2x2 pixels.

Code Overview

This code combines the CircuitPython CursorControl module with a pre-existing project - the PyPortal NeoPixel Color Picker. 

If you run into trouble with MakeCode Arcade, here are some resources for getting help:

Only use the Google Chrome browser with MakeCode!

This guide was first published on Jul 26, 2019. It was last updated on Jul 15, 2024.