# MIT Green Building NeoPixel Tetris

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/144/011/medium800/led_pixels_hero-rooftop.jpg?1777385818 )

## Desktop Tetris Building

Play a game of Tetris on a custom 3D printed LED matrix inspired by the&nbsp;[MIT Green Building hack](https://hacks.mit.edu/Hacks/by_year/2012/tetris/). The project is powered by an Adafruit Feather RP2040 PropMaker running CircuitPython and a Mini Gamepad STEMMA QT.

It also features a 1200mAh lipo battery for portable gameplay.

The 9x13 grid is made using a strand of 117 NeoPixel LED pebbles which are fitted into a 3D printed grid and diffused with a piece of black LED acrylic.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/889/medium640/led_pixels_hero-feather-propmaker.jpg?1776788240)

## Gameplay

The gamepad STEMMA QT features standard buttons and a joystick. Use the joystick to move the shapes (Tetrominoes) on the grid, A button to rotate and B button to drop to the bottom of the grid. The start button begins the game and pauses during gameplay.

![](https://cdn-learn.adafruit.com/assets/assets/000/144/012/medium640/led_pixels_hero-front.jpg?1777385832)

## Parts
Featured
### Adafruit RP2040 Prop-Maker Feather with I2S Audio Amplifier

[Adafruit RP2040 Prop-Maker Feather with I2S Audio Amplifier](https://www.adafruit.com/product/5768)
The Adafruit Feather series gives you lots of options for a small, portable, rechargeable microcontroller board. By picking a feather and stacking on a FeatherWing you can create advanced projects quickly. One popular combo is our [Feather M4](https://www.adafruit.com/product/3857)...

In Stock
[Buy Now](https://www.adafruit.com/product/5768)
[Related Guides to the Product](https://learn.adafruit.com/products/5768/guides)
![Video of a white hand pressing a button to briefly turn an LED strip into white lights. Also wired up to the microcontroller are a servo motor and a speaker.](https://cdn-shop.adafruit.com/product-videos/640x480/5768-09.jpg)

Featured
### Adafruit NeoPixel Pebble / Seed LED Strand - 200 LEDs - 2" Pitch

[Adafruit NeoPixel Pebble / Seed LED Strand - 200 LEDs - 2" Pitch](https://www.adafruit.com/product/6024)
We have all&nbsp;sorts of LED strips for a wide range of needs.&nbsp;[_Chonky_](https://www.adafruit.com/product/3869)&nbsp;strips? We got those!&nbsp;[Strips with alligator...](https://www.adafruit.com/?q=neopixel%20alligator%20clips%20stripping%20wires)

In Stock
[Buy Now](https://www.adafruit.com/product/6024)
[Related Guides to the Product](https://learn.adafruit.com/products/6024/guides)
![Demo Shot of the LED RGB Pebble Pixel, Addressable string light/DC5V, 200 LED/pcs.](https://cdn-shop.adafruit.com/640x480/6024-03.jpg)

Featured
### Adafruit Mini I2C Gamepad with seesaw - STEMMA QT / Qwiic

[Adafruit Mini I2C Gamepad with seesaw - STEMMA QT / Qwiic](https://www.adafruit.com/product/5743)
Make a game or robotic controller for any I2C microcontroller or microcomputer&nbsp;with this _tiny_&nbsp;gamepad breakout board. This design has a 2-axis thumb joystick and 6 momentary buttons (4 large and 2 small). The board communicates with your host microcontroller over I2C so...

In Stock
[Buy Now](https://www.adafruit.com/product/5743)
[Related Guides to the Product](https://learn.adafruit.com/products/5743/guides)
![Angled shot of small rectangular gamepad PCB with thumbstick.](https://cdn-shop.adafruit.com/640x480/5743-05.jpg)

Featured
### Breadboard-friendly SPDT Slide Switch

[Breadboard-friendly SPDT Slide Switch](https://www.adafruit.com/product/805)
These nice switches are perfect for use with breadboard and perfboard projects. They have 0.1" spacing and snap in nicely into a solderless breadboard. They're easy to switch no matter what size fingers you have, but not so easy that they'll get flipped by accident. Work great as...

Out of Stock
[Buy Now](https://www.adafruit.com/product/805)
[Related Guides to the Product](https://learn.adafruit.com/products/805/guides)
![Small, black, SPDT slide switch.](https://cdn-shop.adafruit.com/640x480/805-03.jpg)

Featured
### STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long](https://www.adafruit.com/product/5385)
This 4-wire cable is a little over 400mm / 15.7" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5385)
[Related Guides to the Product](https://learn.adafruit.com/products/5385/guides)
![Angled shot of 400mm long STEMMA QT cable.](https://cdn-shop.adafruit.com/640x480/5385-01.jpg)

Featured
### 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...

Out of 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)

### Lithium Ion Polymer Battery - 3.7v 1200mAh

[Lithium Ion Polymer Battery - 3.7v 1200mAh](https://www.adafruit.com/product/258)
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 battery has a capacity of 1200mAh for a total of about 4.5 Wh. If you need a larger battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/258)
[Related Guides to the Product](https://learn.adafruit.com/products/258/guides)
![Lithium Ion Polymer Battery 3.7v 1200mAh with JST 2-PH connector](https://cdn-shop.adafruit.com/640x480/258-02.jpg)

### Silicone Cover Stranded-Core Ribbon Cable - 4 Wires 1 Meter Long

[Silicone Cover Stranded-Core Ribbon Cable - 4 Wires 1 Meter Long](https://www.adafruit.com/product/3892)
For those who are fans of our silicone-covered wires, but are always looking to _up their wiring game_. We now have **Silicone Cover Ribbon cables!** These may look _a lot_ like <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/3892)
[Related Guides to the Product](https://learn.adafruit.com/products/3892/guides)
![Coiled bundle of black, silicone covered, stranded-core ribbon cable.](https://cdn-shop.adafruit.com/640x480/3892-01.jpg)

## Hardware Fasteners

These screws are required for assembling this project.

- 2x M2.5 x 6mm long steel machine screws
- 2x M3 x 6mm long steel machine screws

# MIT Green Building NeoPixel Tetris

## Circuit Diagram

The diagram below provides a general visual reference for wiring of the components once you get to the&nbsp; **Assembly** &nbsp;page. This diagram was created using the software package&nbsp;[Fritzing](http://fritzing.org/download/).

## Adafruit Library for Fritzing

Adafruit uses the Adafruit Fritzing parts library to create circuit diagrams for projects. You can download the library or just grab individual parts. Get the library and parts from&nbsp;[GitHub - Adafruit Fritzing Parts](https://github.com/adafruit/Fritzing-Library/tree/master/parts).

![](https://cdn-learn.adafruit.com/assets/assets/000/143/886/medium800/led_pixels_Circuit-Daigram.jpg?1776698242 )

## Wired Connections

The PropMaker Feather RP2040 is powered by a 3.7v 1200mAh Lithium Ion Polymer Battery. Wires connecting various components:

- **DIN** from NeoPixel strip to **NeoPixel Input** on Feather
- **5V** from NeoPixel strip to **5V** on Feather
- **GND** on NeoPixel strip to **GND** on Feather
- STEMMA JST connector from Gamepad connects to STEMMA JST connector on Feather
- **GND** from Feather to **Pin 1** on Slide Switch
- **EN** from Feather to **Pin 2** on Slide Switch

# MIT Green Building NeoPixel Tetris

## CAD Files

## Building Assembly

The matrix is a 9x13 grid fitted into a building front panel with a piece of black LED acrylic layered in between.

The front panel features rails that allow it to slide into the main building.&nbsp;

The Feather and slide switch are secured to the bottom cover.

The bottom and top covers snap fit into the building.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/892/medium640thumb/led_pixels_CAD-explode.jpg?1776795820)

## Gamepad Assembly

The mini gamepad is fitted into the bottom half of the gamepad enclosure. The top snap fits over the bottom.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/143/894/medium640thumb/led_pixels_gamepad-expode.jpg?1776799269)

## CAD Parts

Individual 3MF files for 3D printing are oriented and ready to print on FDM machines using PLA/PETG filament. Original design source files may be downloaded using the links below.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/893/medium640/led_pixels_CAD-parts.jpg?1776796786)

[Download CAD Source Files](https://cdn-learn.adafruit.com/assets/assets/000/144/013/original/CAD.zip?1777388047)
[Download 3MF Files](https://cdn-learn.adafruit.com/assets/assets/000/144/014/original/3MF.zip?1777388123)
## Build Volume

The parts require a 3D printer with a minimum build volume of&nbsp;203 (X) x 99 (Y) x 248mm (Z).

![](https://cdn-learn.adafruit.com/assets/assets/000/143/895/medium640/led_pixels_bed-volume.jpg?1776799759)

## Acrylic Template

A piece of acrylic will need to be cut down to size in order to fit into the front panel.

This SVG template is available to download and print on paper to help assist with measuring the acrylic.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/997/medium640/led_pixels_acrylic-template.jpg?1777301696)

[acrylic-template.svg](https://cdn-learn.adafruit.com/assets/assets/000/144/015/original/acrylic-template.svg?1777388212)
# MIT Green Building NeoPixel Tetris

## 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.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_feather_rp2040_prop_maker/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/121/865/medium800/adafruit_products_boot_reset.jpg?1686710555)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

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

You will see a new disk drive appear called **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

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

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RPI-RP2. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/101/659/original/flash_nuke.uf2?1618945856)
# MIT Green Building NeoPixel Tetris

## Code

Once you've finished setting up your RP2040 Prop-Maker Feather with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the **Download Project Bundle** button in the window below. It will download to your computer as a zipped folder.

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

## Upload the Code and Libraries to the RP2040 Prop-Maker Feather

After downloading the Project Bundle, plug your RP2040 Prop-Maker Feather into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called **CIRCUITPY**. Unzip the folder and copy the following items to the RP2040 Prop-Maker Feather's **CIRCUITPY** drive.

- **lib** folder
- **code.py**
- **tom-thumb.pcf** (bitmap font)

Your RP2040 Prop-Maker Feather **CIRCUITPY** drive should look like this after copying the **lib** folder, PCF font file, and **code.py** file:

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

## How the CircuitPython Code Works

At the top of the code, the external power pin is enabled and set high so that the NeoPixel terminal block pin is enabled. Then, the `NeoPixel` object is created. This object is passed to the `PixelFramebuffer` object. This allows the NeoPixels to be arranged in a matrix that can take a display buffer.

```python
# enable external power pin
external_power = DigitalInOut(board.EXTERNAL_POWER)
external_power.direction = Direction.OUTPUT
external_power.value = True

# NeoPixel grid setup with pixelframebuffer
NUMPIXELS = 117
BRIGHTNESS = 1
PIN = board.EXTERNAL_NEOPIXELS
ORDER = neopixel.BGR
pixels = neopixel.NeoPixel(PIN, NUMPIXELS, brightness=BRIGHTNESS,
                           auto_write=False, pixel_order=ORDER)
fb = PixelFramebuffer(
    pixels,
    width=9,
    height=13,
    orientation=0,
    rotation=2,
    alternating=True,
    reverse_x=True
)
grid = [0] * (9 * 13)
# font for scrolling text
font = bitmap_font.load_font("tom-thumb.pcf", Bitmap)
```

### Gamepad

The seesaw gamepad breakout is used to control the game. Its buttons are read via a button mask that is sent over I2C with the seesaw library.

```python
# seesaw gamepad
BUTTON_X = const(6)
BUTTON_Y = const(2)
BUTTON_A = const(5)
BUTTON_B = const(1)
BUTTON_SELECT = const(0)
BUTTON_START = const(16)
button_mask = const(
    (1 << BUTTON_X)
    | (1 << BUTTON_Y)
    | (1 << BUTTON_A)
    | (1 << BUTTON_B)
    | (1 << BUTTON_SELECT)
    | (1 << BUTTON_START)
)
i2c_bus = board.STEMMA_I2C()
seesaw = Seesaw(i2c_bus, addr=0x50)
seesaw.pin_mode_bulk(button_mask, seesaw.INPUT_PULLUP)
JOY_CENTER = 512
JOY_EDGE = 200
```

### Tetrominoes

The shapes used in Tetris are called&nbsp;[Tetrominoes](https://en.wikipedia.org/wiki/Tetromino), which are geometric shapes composed of four squares. In the code, they are created with nested byte arrays. This allows for the code to be able to determine the width and height of the Tetrominoes automatically. Black is used as a transparent color (`0x000000`) later in the code.

```python
# Tetrominoes
o_tetro = [
    [0xFFFF00, 0xFFFF00],
    [0xFFFF00, 0xFFFF00],
]
i_tetro = [
    [0x00FFFF],
    [0x00FFFF],
    [0x00FFFF],
    [0x00FFFF],
]
s_tetro = [
    [0x000000, 0xFF0000, 0xFF0000],
    [0xFF0000, 0xFF0000, 0x000000],
]
z_tetro = [
    [0x00FF00, 0x00FF00, 0x000000],
    [0x000000, 0x00FF00, 0x00FF00],
]
l_tetro = [
    [0xFF5500, 0x000000],
    [0xFF5500, 0x000000],
    [0xFF5500, 0xFF5500],
]
j_tetro = [
    [0x000000, 0xFF00FF],
    [0x000000, 0xFF00FF],
    [0xFF00FF, 0xFF00FF],
]
t_tetro = [
    [0x5500FF, 0x5500FF, 0x5500FF],
    [0x000000, 0x5500FF, 0x000000],
]
tetrominoes = [o_tetro, i_tetro, s_tetro, z_tetro,
               l_tetro, j_tetro, t_tetro]
```

### Sprites

The&nbsp;`Sprite` class is used to interface between the byte arrays and the `PixelFramebuffer`. The class supports drawing, moving and rotating the shapes. The `rotate()` method has logic to determine if a shape is close to the left or right edge so that it can still rotate in place.

```python
class Sprite:
    def __init__(self, data, transparent=None, rotation=0):
        if isinstance(data[0], list):
            self.height = len(data)
            self.width = len(data[0])
            self.data = [pixel for row in data for pixel in row]
        else:
            raise ValueError("Sprite data must be a 2D list")
        self.x = 0
        self.y = 0
        self.transparent = transparent
        self.rotation = rotation
```

### Game Logic

There are a few functions that handle the gameplay logic.&nbsp;`can_move()` tracks a piece while its moving to see if there are any obstacles that would prevent it from moving. If an obstacle is detected, then the logic knows that the piece is landing at the bottom of the grid or that the game has ended.

```python
def can_move(s, dx, dy, rot=None):
    check_rot = rot if rot is not None else s.rotation
    px = 0
    py = 0
    for row in range(s.height):
        for col in range(s.width):
            color = s.data[row * s.width + col]
            if color == s.transparent:
                continue
            if check_rot == 0:
                px, py = col, row
            elif check_rot == 1:
                px, py = s.height - 1 - row, col
            elif check_rot == 2:
                px, py = s.width - 1 - col, s.height - 1 - row
            elif check_rot == 3:
                px, py = row, s.width - 1 - col
            nx = s.x + px + dx
            ny = s.y + py + dy
            if nx < 0 or nx >= 9:
                return False
            if ny >= 13:
                return False
            if ny >= 0 and grid_get(nx, ny) != 0:
                return False
    return True
```

The `lock_sprites()` function converts the Sprite to raw pixel data outside of the `PixelFramebuffer` after it stops moving. The bottom of the grid has no concept of the Tetromino shapes and instead is a grid of NeoPixel data. The Sprite is respawned with `spawn_piece()` for every turn.

```python
def lock_sprite(s):
    px = 0
    py = 0
    for row in range(s.height):
        for col in range(s.width):
            color = s.data[row * s.width + col]
            if color == s.transparent:
                continue
            if s.rotation == 0:
                px, py = col, row
            elif s.rotation == 1:
                px, py = s.height - 1 - row, col
            elif s.rotation == 2:
                px, py = s.width - 1 - col, s.height - 1 - row
            elif s.rotation == 3:
                px, py = row, s.width - 1 - col
            grid_set(s.x + px, s.y + py, color)

def spawn_piece():
    seed = random.randint(0, 6)
    piece = Sprite(tetrominoes[seed], transparent=0x000000)
    max_x = 9 - piece.draw_width
    piece.x = random.randint(0, max(0, max_x))
    piece.y = -piece.draw_height  # start above the board
    return piece
```

`clear_rows()` checks if a horizontal row is filled with colors. If it is, then that row is cleared by turning white and disappearing. The rows above then drop down. `is_game_over()` checks if any of the sprite shapes get stuck above the gameplay grid.

```python
def clear_rows(framebuffer):
    rows_cleared = 0
    y = 12
    while y >= 0:
        full = True
        for x in range(9):
            if grid_get(x, y) == 0:
                full = False
                break
        if full:
            rows_cleared += 1
            # flash the row white
            for x in range(9):
                grid_set(x, y, 0xFFFFFF)
            framebuffer.fill(0x000000)
            draw_grid(framebuffer)
            framebuffer.display()
            time.sleep(0.3)
            # shift everything down
            for shift_y in range(y, 0, -1):
                for x in range(9):
                    grid_set(x, shift_y, grid_get(x, shift_y - 1))
            for x in range(9):
                grid_set(x, 0, 0)
        else:
            y -= 1
    return rows_cleared

def is_game_over(s):
    py = 0
    for row in range(s.height):
        for col in range(s.width):
            color = s.data[row * s.width + col]
            if color == s.transparent:
                continue
            if s.rotation == 0:
                py = row
            elif s.rotation == 1:
                py = col
            elif s.rotation == 2:
                py = s.height - 1 - row
            elif s.rotation == 3:
                py = s.width - 1 - col
            if s.y + py < 0:
                return True
    return False
```

### Non-Blocking Text

The text scrolling is handled with the&nbsp;`scroll_text()` function. It can track the number of times that the text fully scrolls across the display. In the loop, it is wrapped in a `ticks` time tracker to be non-blocking.

```python
def scroll_text(the_bitmap, scroll_x, count = 0, counting = False, framebuffer = fb):
    framebuffer.fill(0x000000)
    for col in range(the_bitmap.width):
        px = 9 - scroll_x + col
        if 0 <= px < 9:
            for row in range(the_bitmap.height):
                if the_bitmap[col, row]:
                    framebuffer.pixel(px, ((13 - the_bitmap.height) // 2) + row, 0xFFFFFF)
    framebuffer.display()
    scroll_x = (scroll_x + 1) % (9 + the_bitmap.width)
    if scroll_x == 0:
        count += 1
    if counting:
        return scroll_x, count
    else:
        return scroll_x
```

### The Loop

In the loop, when the code first boots, the text "`IHTFP`", which stands for the [MIT Interesting Hacks to Fascinate People](https://hacks.mit.edu/Hacks/by_topic/), scrolls twice. Then, the text is updated with "`START?`", which scrolls until the start button on the gamepad is pressed.

```python
if first_run:
        while scroll_count < 2:
            if ticks_diff(ticks_ms(), timer) >= 150:
                scroll_x_pos, scroll_count = scroll_text(scroll_bmp, scroll_x_pos,
                                                         scroll_count, counting = True)
                timer = ticks_add(timer, 150)
        first_run = False
        scroll_count = 0
        scroll_label.text = "START?"
        scroll_bmp = scroll_label.bitmap

    if not gameplay:
        if ticks_diff(ticks_ms(), timer) >= 150:
            scroll_x_pos = scroll_text(scroll_bmp, scroll_x_pos)
            timer = ticks_add(timer, 150)
        if just_pressed & (1 << BUTTON_START):
            gameplay = True
            clear_grid()
            sprite = spawn_piece()
            last_fall = ticks_ms()
            scroll_x_pos = 0
            last_buttons = buttons
        continue
```

### Pause/Resume

After start is pressed, gameplay begins. If you press the start button while gameplay is in progress, then the game is paused. You'll see "`PAUSED`" scroll across the display, followed by the number of rows you have cleared so far in the game. Pressing start again resumes gameplay.

```python
# start button toggles pause
    if just_pressed & (1 << BUTTON_START):
        paused = not paused
        if paused:
            timer = ticks_ms()
            scroll_x_pos = 0
            scroll_label.text = f"PAUSED - {score} ROWS"
            scroll_bmp = scroll_label.bitmap
            fb.fill(0x000000)
            draw_grid(fb)
            fb.display()
        else:
            last_fall = ticks_ms()

    if paused:
        if ticks_diff(ticks_ms(), timer) >= 150:
            scroll_x_pos = scroll_text(scroll_bmp, scroll_x_pos)
            timer = ticks_add(timer, 150)
        last_buttons = buttons
        continue
```

### Game Control

The shapes are moved horizontally on the grid with the joystick. The A button rotates the shape and the B button drops the shape to the bottom of the grid.

```python
# rotate on A button press
    if just_pressed & (1 << BUTTON_A):
        sprite.rotate(can_move)

	# joystick left/right
    if x_joy < JOY_CENTER - JOY_EDGE:
        if not joy_moved:
            if can_move(sprite, -1, 0):
                sprite.move(-1, 0)
            joy_moved = True
    elif x_joy > JOY_CENTER + JOY_EDGE:
        if not joy_moved:
            if can_move(sprite, 1, 0):
                sprite.move(1, 0)
            joy_moved = True
    else:
        joy_moved = False

	# hard drop on b button
    if just_pressed & (1 << BUTTON_B):
        while can_move(sprite, 0, 1):
            sprite.move(0, 1)

    last_buttons = buttons
```

### Gameplay Ticks

The movement of the shapes during gameplay is tracked with `ticks`. Every time a row is cleared, the value of score is increased by the value of cleared. When the game is over, the NeoPixels flash white three times and then the score is scrolled across the display twice. The game then resets to play again.

```python
# gravity on timer
    if ticks_diff(ticks_ms(), last_fall) >= FALL_SPEED:
        if can_move(sprite, 0, 1):
            sprite.move(0, 1)
        else:
            lock_sprite(sprite)

            fb.fill(0x000000)
            draw_grid(fb)
            fb.display()

            cleared = clear_rows(fb)
            if cleared > 0:
                last_fall = ticks_ms()
                score += cleared
                fb.fill(0x000000)
                draw_grid(fb)
                fb.display()
            if is_game_over(sprite):
                for _ in range(3):
                    fb.fill(0xFFFFFF)
                    fb.display()
                    time.sleep(0.5)
                    fb.fill(0x000000)
                    fb.display()
                    time.sleep(0.5)
                clear_grid()
                timer = ticks_ms()
                scroll_x_pos = 0
                scroll_label.text = f"{score} ROWS CLEARED!"
                scroll_bmp = scroll_label.bitmap
                while scroll_count < 2:
                    if ticks_diff(ticks_ms(), timer) >= 150:
                        scroll_x_pos, scroll_count = scroll_text(scroll_bmp, scroll_x_pos,
                                                                 scroll_count, counting = True)
                        timer = ticks_add(timer, 150)
                scroll_count = 0
                score = 0
                scroll_label.text = "START?"
                scroll_bmp = scroll_label.bitmap
                gameplay = False

            sprite = spawn_piece()
        last_fall = ticks_add(last_fall, FALL_SPEED)
	    # draw
    fb.fill(0x000000)
    draw_grid(fb)
    sprite.draw(fb)
    fb.display()
```

# MIT Green Building NeoPixel Tetris

## Wiring

## Slide Switch Wires

Prepare a set of two wires about 3.5inches (9cm) in length.

Using wire strippers, remove a bit of insulation from the tips of each wire.

Tin the exposed wire by applying a bit of solder to them.

Snip off one of the leads on the slide switch, either the far left or right but not the middle. Then trim the two remaining leads short, about half their length.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/987/medium640/led_pixels_switch-wire-prep.jpg?1777298783)

## Solder Wires

Solder the two wires to each of the leads on the slide switch.

A&nbsp;[pair of helping hands](https://www.adafruit.com/product/291)&nbsp;can assist while soldering wires in place.

Solder the two wires from the slide to the EN and GND pins on the top of the Feather.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/988/medium640/led_pixels_switch-wire-solder.jpg?1777298826)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/989/medium640/led_pixels_switch-feather-solder.jpg?1777298854)

## Soldered Switch

Take a moment to ensure the wires from the slide switch have been properly soldered.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/986/medium640/led_pixels_feather-switch-soldered.jpg?1777298375)

## First NeoPixel

Locate the first NeoPixel in the strand. The connector should match the one in the photo. You'll need to replace it with the silicon ribbon cable so it can be connected to the screw-block terminal on the PropMaker Feather.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/990/medium640/led_pixels_strip-1st-pixel.jpg?1777298976)

## Create the Cable

Using the 26AWG silicone ribbon cable, create a 3-wire cable and cut it to a desired length. In this project, 12-inches (30cm) was sufficient.&nbsp;

Using wire strippers, remove a bit of insulation from each wire on both ends. Then, twist and tin the exposed wire using a bit of solder - This helps to prevent the wires from fraying when soldering to the NeoPixel strand.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/991/medium640/led_pixels_strip-cable.jpg?1777299052)

## Solder Wires

Cut the cable from the first NeoPixel in the strand and strip the three wires for power, data in, and ground.

The power wire is denoted with small white dot markings, followed by the data wire, and then the ground wire.

Cut three short pieces of heat shrink tubbing and slip them over the silicone ribbon wires.

Solder the three wires from the strand to the silicone ribbon wires.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/143/992/medium640/led_pixels_strip-solder-cable.jpg?1777299108)

## Wired NeoPixel Strip

Double check that the solder joints are solid. Slip heat shrink over them and apply heat to the tubing to set them in place.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/993/medium640/led_pixels_strip-cable-wired.jpg?1777299137)

## Cut Strip

Locate the 117th NeoPixel in the strand and cut the cable in between the 117th and 118th NeoPixel using wire cutters.

Save the remaining strand (that's 83 NeoPixels!) for another project.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/994/medium640/led_pixels_strip-cut.jpg?1777299164)

# MIT Green Building NeoPixel Tetris

## Assembly

## Cut Acrylic

Use the template to cut the piece of acrylic. A scoring knife and safety ruler can help cut clean and straight edges.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/949/medium640/led_pixels_acrylic-cut.jpg?1777290749)

Yellow: Please be very careful when cutting acrylic, both with the blade and in case the sheet fractures and may send shards your way.

## Install LEDs

Orient the frame grid assembly so the bottom surface of the grids are facing up.

Starting with the first NeoPixel LED, firmly press it into pill shaped cutout in the lower right side of the grid.

The NeoPixel LED should sit just below the thickness of the grids surface. If it's pushed in too far, the light will create a sharp spotlight, whereas the ideal effect is for the light to evenly fill the full rectangular cell in the grid.

Continuing with the installation, going from bottom to top, press fit more NeoPixel LEDs up the column.

Take your time, making sure each LED is fitted relatively the same depth as the first.

If the LED doesn't quite fit, you can pinch and flex the wires to get the LED to insert, then pull the wire to seat the LED at the desired depth.

The NeoPixel LEDs are arranged in a zigzag pattern. On the 13th LED, go to the next column on the left, then continue with the installation going from top to bottom.

At the end of the column, at the 26th LED, go to the left column, then continue going from bottom to top.

Repeat the installation process for all 117 LEDs.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/995/medium640/led_pixels_grid-pebble-side.jpg?1777299286)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/996/medium640/led_pixels_grid-pebble-assembled.jpg?1777299362)

## Grid Assembly

Get the front panel, acrylic and matrix frame ready to assemble together.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/950/medium640/led_pixels_front-panel-grid.jpg?1777291814)

## Install Acrylic

Orient the piece of acrylic so the shiny side faces up. Carefully fit the acrylic into the front panel.

Press the down on all the edges so the acrylic is fully seated into the front panel.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/951/medium640/led_pixels_front-panel-acrylic-install.jpg?1777291969)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/952/medium640/led_pixels_front-panel-acrylic-installed.jpg?1777291980)

## Install Matrix

Orient the matrix grid with the front panel noting the starting pixel starts where the front panel has a flush surface.

Press the matrix grid into the front panel so it sits flush with the piece of acrylic.

Double check the orientation of the matrix is installed correctly and that all of the NeoPixels remain seated.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/953/medium640/led_pixels_front-panel-grid-orient.jpg?1777292074)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/954/medium640/led_pixels_front-panel-grid-install.jpg?1777292417)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/955/medium640/led_pixels_front-panel-grid-installed.jpg?1777292974)

## Install Front Panel

Orient the front panel with the building enclosure noting the starting pixel is located near the bottom of the building.

Insert the cable from the starting pixel through the opening in the building.

Slide the front panel through the top of the building, making sure the sides catch into the mating rails.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/956/medium640/led_pixels_building-grid-preinstall.jpg?1777293154)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/957/medium640/led_pixels_building-grid-install.jpg?1777293207)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/958/medium640/led_pixels_building-grid-installing.jpg?1777293308)

## Matrix Building

Pull the cable from the NeoPixel strand out from the bottom of the building.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/959/medium640/led_pixels_building-grid-installed.jpg?1777293366)

## Switch Holder

Insert the switch at an angle and push it into the recess so it sits flush with the holder.

The actuator should be accessible on the other side of the holder.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/960/medium640/led_pixels_switch-holder.jpg?1777293528)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/961/medium640/led_pixels_switch-holder-install.jpg?1777293612)

## Secure Switch Holder

Use two M3 x 6mm long steel machine screws to secure the switch holder to the bottom cover.

Place the switch holder over the area with the two short stand offs so the mounting holes line up.

Insert and fasten the screws to secure the switch holder to the bottom cover.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/962/medium640/led_pixels_bottom-switch-screws.jpg?1777293669)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/963/medium640/led_pixels_bottom-switch-secure.jpg?1777293776)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/964/medium640/led_pixels_bottom-switch-installed.jpg?1777293815)

## Secure Feather

Use two M2.5 x 6mm long steel machine screws to secure the Feather to the bottom cover.

Place the Feather over the four standoffs with the mounting holes lined up.

Insert and fasten the screws to secure the Feather to the bottom cover.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/965/medium640/led_pixels_bottom-feather-screws.jpg?1777296709)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/966/medium640/led_pixels_bottom-feather-secure.jpg?1777296764)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/967/medium640/led_pixels_bottom-feather-installed.jpg?1777296799)

## Battery Holder

Plug in the 1200mAh lipo battery into the Feather.&nbsp;

Fit the battery in-between the extending walls on the bottom cover.

Slide the battery clip over the walls so the rails mate with the nubs.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/968/medium640/led_pixels_bottom-battery-clip.jpg?1777297249)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/969/medium640/led_pixels_bottom-battery-plug.jpg?1777297270)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/970/medium640/led_pixels_battery-clip-install.jpg?1777297306)

## Secure NeoPixel Cable

Get the cable from the NeoPixel strand ready to install onto the Feather.

Insert the three wires into their corresponding pins on the Feather screw-block terminals.

Use a small flat head screw driver to secure the wires to the Feather screw-block terminals.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/971/medium640/led_pixels_feather-pebble-cable.jpg?1777297387)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/972/medium640/led_pixels_feather-pebble-secure.jpg?1777297419)

## Secure Gamepad

Get the two halves of the gamepad case ready.

Insert the gamepad PCB into the bottom half of the case at an angle to fit the corners underneath the clips.

Slightly flex the bottom cover to allow the gamepad PCB to fit under the remaining set of corner clips.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/973/medium640/led_pixels_gamepad-case.jpg?1777297576)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/974/medium640/led_pixels_gamepad-pcb-install.jpg?1777297603)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/975/medium640/led_pixels_gamepad-pcb-installed.jpg?1777297659)

## Assemble Gamepad Case

Orient the top half of the gamepad case with the bottom.

Fit the top over the gamepad PCB and press down to snap fit the two halves together.

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/143/976/medium640/led_pixels_gamepad-top-install.jpg?1777297822)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/977/medium640/led_pixels_gamepad-top-installed.jpg?1777297854)

## Connect Gamepad

Plug the long STEMMA QT cable into the gamepad PCB.

Connect the other end of the cable to the STEMMA QT port on the Feather.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/978/medium640/led_pixels_gamepad-stemma-plug.jpg?1777297914)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/979/medium640/led_pixels_feather-stemma-plug.jpg?1777297967)

## Power Test

Use the slide switch to power on the Feather.

Use the gamepad to run a quick play test to ensure everything is working properly.&nbsp;

Power off the Feather when ready to proceed.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/980/medium640/led_pixels_power-test.jpg?1777298007)

## Install Bottom

Orient the bottom cover with the building enclosure.&nbsp;

Fit the STEMMA QT cable through the notch near the lower front of the building.

Press the bottom cover into the building so it snap fits closed.

Make sure none of the wires and cables are being pinched.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/981/medium640/led_pixels_bottom-building-install.jpg?1777298070)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/982/medium640/led_pixels_bottom-building-installed.jpg?1777298083)

## Install Rooftop

The top cover and rooftop are joined together with double-sided tape or adhesives.

Apply the tape or adhesive to the flat surface of the top cover, then attach the two parts together.

![](https://cdn-learn.adafruit.com/assets/assets/000/144/005/medium640/led_pixels_top-roof-parts.jpg?1777385631)

![](https://cdn-learn.adafruit.com/assets/assets/000/144/006/medium640/led_pixels_top-roof-install.jpg?1777385640)

![](https://cdn-learn.adafruit.com/assets/assets/000/144/007/medium640/led_pixels_top-roof-taped.jpg?1777385652)

## Install Top

Orient the top cover with the building enclosure.

Press the top cover into the building so it snap fits closed.

![](https://cdn-learn.adafruit.com/assets/assets/000/144/008/medium640/led_pixels_top-roof-building-install.jpg?1777385763)

![](https://cdn-learn.adafruit.com/assets/assets/000/144/009/medium640/led_pixels_top-roof-building-installed.jpg?1777385774)

## Final Build

Use the slide switch to power on the Feather to begin playing Tetris!

Congratulations on your build (or building).

![](https://cdn-learn.adafruit.com/assets/assets/000/144/010/medium640/led_pixels_play-test-updated.jpg?1777385791)

# MIT Green Building NeoPixel Tetris

## Usage

![](https://cdn-learn.adafruit.com/assets/assets/000/144/001/medium800/led_pixels_play-testr.jpg?1777302432 )

## Intro Text&nbsp;

On boot, the text _ **IHTFP** _ scrolls across the display, paying tribute to the "_Interesting Hacks To Fascinate People_" website that features MIT gallery of hacks. Then the word START? scrolls and loops until gameplay has begun using the start button.

![](https://cdn-learn.adafruit.com/assets/assets/000/144/004/medium800/led_pixels_gamepad-legend.jpg?1777308393 )

## Game Controls

- Start button - Starts the game. Pauses the game while play is in progress.
- Joystick - Moves the Tetrominoes horizontally on the grid
- A button - Rotates the Tetrominoes
- B button - Drops the Tetrominoes to the bottom of the grid

## Score Count

A score is displays on the matrix whenever the game is paused or has ended.


## Guide Products

### Adafruit RP2040 Prop-Maker Feather with I2S Audio Amplifier

[Adafruit RP2040 Prop-Maker Feather with I2S Audio Amplifier](https://www.adafruit.com/product/5768)
The Adafruit Feather series gives you lots of options for a small, portable, rechargeable microcontroller board. By picking a feather and stacking on a FeatherWing you can create advanced projects quickly. One popular combo is our [Feather M4](https://www.adafruit.com/product/3857)...

In Stock
[Buy Now](https://www.adafruit.com/product/5768)
[Related Guides to the Product](https://learn.adafruit.com/products/5768/guides)
### Adafruit NeoPixel Pebble / Seed LED Strand - 200 LEDs - 2" Pitch

[Adafruit NeoPixel Pebble / Seed LED Strand - 200 LEDs - 2" Pitch](https://www.adafruit.com/product/6024)
We have all&nbsp;sorts of LED strips for a wide range of needs.&nbsp;[_Chonky_](https://www.adafruit.com/product/3869)&nbsp;strips? We got those!&nbsp;[Strips with alligator...](https://www.adafruit.com/?q=neopixel%20alligator%20clips%20stripping%20wires)

In Stock
[Buy Now](https://www.adafruit.com/product/6024)
[Related Guides to the Product](https://learn.adafruit.com/products/6024/guides)
### Adafruit Mini I2C Gamepad with seesaw - STEMMA QT / Qwiic

[Adafruit Mini I2C Gamepad with seesaw - STEMMA QT / Qwiic](https://www.adafruit.com/product/5743)
Make a game or robotic controller for any I2C microcontroller or microcomputer&nbsp;with this _tiny_&nbsp;gamepad breakout board. This design has a 2-axis thumb joystick and 6 momentary buttons (4 large and 2 small). The board communicates with your host microcontroller over I2C so...

In Stock
[Buy Now](https://www.adafruit.com/product/5743)
[Related Guides to the Product](https://learn.adafruit.com/products/5743/guides)
### Breadboard-friendly SPDT Slide Switch

[Breadboard-friendly SPDT Slide Switch](https://www.adafruit.com/product/805)
These nice switches are perfect for use with breadboard and perfboard projects. They have 0.1" spacing and snap in nicely into a solderless breadboard. They're easy to switch no matter what size fingers you have, but not so easy that they'll get flipped by accident. Work great as...

Out of Stock
[Buy Now](https://www.adafruit.com/product/805)
[Related Guides to the Product](https://learn.adafruit.com/products/805/guides)
### STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long](https://www.adafruit.com/product/5385)
This 4-wire cable is a little over 400mm / 15.7" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5385)
[Related Guides to the Product](https://learn.adafruit.com/products/5385/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...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4594)
[Related Guides to the Product](https://learn.adafruit.com/products/4594/guides)
### Lithium Ion Polymer Battery - 3.7v 1200mAh

[Lithium Ion Polymer Battery - 3.7v 1200mAh](https://www.adafruit.com/product/258)
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 battery has a capacity of 1200mAh for a total of about 4.5 Wh. If you need a larger battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/258)
[Related Guides to the Product](https://learn.adafruit.com/products/258/guides)
### Silicone Cover Stranded-Core Ribbon Cable - 4 Wires 1 Meter Long

[Silicone Cover Stranded-Core Ribbon Cable - 4 Wires 1 Meter Long](https://www.adafruit.com/product/3892)
For those who are fans of our silicone-covered wires, but are always looking to _up their wiring game_. We now have **Silicone Cover Ribbon cables!** These may look _a lot_ like <a...></a...>

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

## Related Guides

- [Adafruit RP2040 Prop-Maker Feather](https://learn.adafruit.com/adafruit-rp2040-prop-maker-feather.md)
- [Adafruit Mini I2C STEMMA QT Gamepad with seesaw](https://learn.adafruit.com/gamepad-qt.md)
- [MagTag Progress Displays](https://learn.adafruit.com/magtag-progress-displays.md)
- [Motion Sensor Bat](https://learn.adafruit.com/motion-sensor-bat.md)
- [Talking D20 with RP2040 PropMaker Feather](https://learn.adafruit.com/talking-d20-rp2040.md)
- [Building the Assistive Technology Ultimate Remote](https://learn.adafruit.com/building-the-assistive-technology-ultimate-remote.md)
- [Gravity Falls Memory Gun](https://learn.adafruit.com/gravity-falls-memory-gun.md)
- [Sailor Moon Star Locket](https://learn.adafruit.com/sailor-moon-star-locket.md)
- [Cellular Data for CircuitPython with FONA](https://learn.adafruit.com/cellular-data-for-circuitpython-with-fona.md)
- [Light-Up Costumes in Harsh Environments](https://learn.adafruit.com/light-up-costumes-in-harsh-environments.md)
- [IoT Twitter Listener Party Parrot](https://learn.adafruit.com/iot-twitter-listener-party-parrot.md)
- [Soundbox RP2040](https://learn.adafruit.com/soundbox-rp2040.md)
- [Circuit Playground Gizmo Ornaments](https://learn.adafruit.com/display-ornaments-with-circuit-playground.md)
- [Raspberry Pi LED Matrix Sand Toy](https://learn.adafruit.com/matrix-led-sand.md)
- [Textable Sensor with FONA and CircuitPython](https://learn.adafruit.com/textable-sensor-with-fona-and-circuitpython.md)
- [BLE Beacon NeoPixels](https://learn.adafruit.com/ble-beacon-neopixels.md)
- [Purple Air AQI Display](https://learn.adafruit.com/purple-air-aqi-display.md)
