# Modal MIDI Keyboard

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/103/280/medium800/projects_modal_midi2.jpg?1625082421)

https://youtu.be/84mCSbIzd6k

https://youtu.be/fkyYH2uwIVQ

Play great sounding melodies and chords on a synthesizer without lots of piano lessons by sticking with notes that sound good together! Modes, such as **Major/Ionian, Minor/Aeolian, Dorian,** and **Mixolydian** , to name a few, are sets of relative note intervals designed for this purpose, and now you can build your own keyboard that will play within whichever key and mode you choose -- you can't hit a wrong note!

Your modal keyboard sends notes over USB MIDI to any software synthesizer, or hardware synth with USB MIDI Host capabilities. Pick your key and mode on startup and then start your jam!

For more on modes, [check out this video](https://www.youtube.com/watch?v=a6d7dWwawd8) and take a look at [this page](https://learningmusic.ableton.com/advanced-topics/modes.html).

## Parts
## PCB

You can order these using the Gerber files found later in the guide from a board house such as JLCPCB, or by visiting [this OSH Park link](https://oshpark.com/shared_projects/W2AiS0yO). You only need one PCB per keyboard, but most board houses make them in multiples of three or five for a minimum order.

![projects_oshparkpcbs.jpg](https://cdn-learn.adafruit.com/assets/assets/000/103/293/medium640/projects_oshparkpcbs.jpg?1625243092)

![projects_Pico_jlcPCBs_2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/103/294/medium640/projects_Pico_jlcPCBs_2.jpg?1625243170)

The keyboard uses 21 keyswitches and keycaps.

### Kailh Mechanical Key Switches - 10 packs - Cherry MX Compatible

[Kailh Mechanical Key Switches - 10 packs - Cherry MX Compatible](https://www.adafruit.com/product/4996)
For crafting your very own custom keyboard, these **&nbsp;Kailh mechanical key switches** &nbsp;are deeee-luxe!

Come&nbsp;in a pack of 10 switches, plenty to make a small keyboard, or grab a few packs to build a full keyboard.

- Use these with our&nbsp;<a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/4996)
[Related Guides to the Product](https://learn.adafruit.com/products/4996/guides)
![Top down view of four piles of Kailh key switches in Red, Black, Brown, and Black variations.](https://cdn-shop.adafruit.com/640x480/4996-00.jpg)

### DSA Keycaps for MX Compatible Switches in Various Colors

[DSA Keycaps for MX Compatible Switches in Various Colors](https://www.adafruit.com/product/5097)
Dress up your mechanical keys in your favorite colors, with a wide selection of stylish DSA key caps. Here is a 10 pack different colored keycaps for your next mechanical keyboard or [NeoKey](https://www.adafruit.com/?q=neokey&sort=BestMatch) project. Snap 'em onto...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5097)
[Related Guides to the Product](https://learn.adafruit.com/products/5097/guides)
![Array of many different colored keycaps](https://cdn-shop.adafruit.com/640x480/5097-03.jpg)

### Raspberry Pi Pico RP2040

[Raspberry Pi Pico RP2040](https://www.adafruit.com/product/4864)
The Raspberry Pi foundation changed single-board computing [when they released the Raspberry Pi computer](https://www.raspberrypi.org/archives/723), now they're ready to do the same for microcontrollers with the release of the brand new **Raspberry Pi Pico**. This...

In Stock
[Buy Now](https://www.adafruit.com/product/4864)
[Related Guides to the Product](https://learn.adafruit.com/products/4864/guides)
![Angle shot of Raspberry Pi Pico RP2040](https://cdn-shop.adafruit.com/640x480/4864-00.jpg)

### Tactile Switch Buttons (6mm tall) x 10 pack

[Tactile Switch Buttons (6mm tall) x 10 pack](https://www.adafruit.com/product/1490)
Super-tall clicky momentary switches are standard input "buttons" on electronic projects. These work best in a PCB but [can be used on a solderless breadboard as shown in this tutorial](http://www.ladyada.net/learn/arduino/lesson5.html). The pins are normally open...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1490)
[Related Guides to the Product](https://learn.adafruit.com/products/1490/guides)
![Angled shot of 10 6mm tactile switch buttons.](https://cdn-shop.adafruit.com/640x480/1490-02.jpg)

 **M2.5 x 16mm screws x4**

Get at a hardware store or from McMaster-Carr [here](https://www.mcmaster.com/91292A115/).

![projects_raspberry_pi_91292A115p1-b01-digitall_1x_637016046960757740.png](https://cdn-learn.adafruit.com/assets/assets/000/103/295/medium640/projects_raspberry_pi_91292A115p1-b01-digitall_1x_637016046960757740.png?1625243514)

### Part: Little Rubber Bumper Feet
quantity: 1
Pack of 4
[Little Rubber Bumper Feet](https://www.adafruit.com/product/550)

### Part: USB cable
quantity: 1
USB A to Micro-B
[USB cable](https://www.adafruit.com/product/592)

### Part: Brass M2.5 Standoffs 16mm tall
quantity: 2
pack of 2
[Brass M2.5 Standoffs 16mm tall](https://www.adafruit.com/product/2337)

### Part: Black Nylon Machine Screw and Stand-off Set
quantity: 1
M2.5
[Black Nylon Machine Screw and Stand-off Set](https://www.adafruit.com/product/3299)

### Part: Black Nylon Machine Screw and Stand-off Set – M3 Thread Black Nylon Machine Screw and Stand-off Set 
quantity: 1
M3
[Black Nylon Machine Screw and Stand-off Set – M3 Thread Black Nylon Machine Screw and Stand-off Set ](https://www.adafruit.com/product/4685)

# Modal MIDI Keyboard

## Installing 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 working on your board.

[Download the latest version of CircuitPython for the Raspberry Pi Pico from circuitpython.org](https://circuitpython.org/board/raspberry_pi_pico/)
 **Click the link above and download the latest UF2 file.**

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

![circuitpython_Cat_UF2_download.png](https://cdn-learn.adafruit.com/assets/assets/000/098/753/medium640/circuitpython_Cat_UF2_download.png?1611157944)

Start with your Pico unplugged from USB. Hold down the **BOOTSEL** button, and while continuing to hold it (don't let go!), plug the Pico into USB. **Continue to hold the BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, unplug your Pico and go through the above process again.

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

![raspberry_pi_one_one_two.png](https://cdn-learn.adafruit.com/assets/assets/000/125/993/medium640/raspberry_pi_one_one_two.png?1699493528)

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

&nbsp;

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

![circuitpython_Cat_RPI-RP2_drive.png](https://cdn-learn.adafruit.com/assets/assets/000/098/756/medium640/circuitpython_Cat_RPI-RP2_drive.png?1611158210)

![circuitpython_Cat_drag_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/098/758/medium640/circuitpython_Cat_drag_UF2.png?1611158274)

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

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

![circuitpython_Cat_CIRCUITPY.png](https://cdn-learn.adafruit.com/assets/assets/000/098/759/medium640/circuitpython_Cat_CIRCUITPY.png?1611158312)

## Flash Resetting UF2

If your Pico ever gets into a really _weird_ state and doesn't even show up as a disk drive when installing CircuitPython, try installing this 'nuke' UF2 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 nuking, re-install CircuitPython

[flash_nuke.uf2](https://datasheets.raspberrypi.com/soft/flash_nuke.uf2)
# Modal MIDI Keyboard

## Build the Modal MIDI Keyboard

This [guide](https://learn.adafruit.com/diy-pico-mechanical-keyboard-with-fritzing-circuitpython/overview) is dedicated to designing and building the 21-Key Pico Keyboard. You can jump straight to ordering PCBs using [this section of the guide](https://learn.adafruit.com/diy-pico-mechanical-keyboard-with-fritzing-circuitpython/21-key-pico-keyboard#pcb-layout-3084613-7), and then follow the steps for [assembly on this page](https://learn.adafruit.com/diy-pico-mechanical-keyboard-with-fritzing-circuitpython/pico-keyboard-assembly).

![](https://cdn-learn.adafruit.com/assets/assets/000/103/288/medium800/projects_picokb-0130.jpg?1625242773)

![](https://cdn-learn.adafruit.com/assets/assets/000/103/290/medium800/projects_picokb-0232.jpg?1625242814)

![](https://cdn-learn.adafruit.com/assets/assets/000/103/291/medium800/projects_picokb-0291.jpg?1625242839)

![](https://cdn-learn.adafruit.com/assets/assets/000/103/292/medium800/projects_picokb-0306.jpg?1625242859)

# Modal MIDI Keyboard

## Code the Modal MIDI Controller

## Text Editor

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

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

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries and the&nbsp; **code.py** &nbsp;file. In order to get the libraries you need, click on the&nbsp; **Download Project Bundle** &nbsp;link below, and uncompress the .zip file.

Drag the contents of the uncompressed bundle directory onto your board's **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

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

## Use the Modal MIDI Keyboard

To test the keyboard, plug it into your computer and launch this [handy Chrome browser MIDI Monitor web app](https://www.midimonitor.com/#) to check that it is working.

![](https://cdn-learn.adafruit.com/assets/assets/000/103/296/medium800/projects_midimon.jpg?1625244126)

## Make Some Sound

MIDI note messages are fun to look at, but even better when the make some sound! Use a software synthesizer that accepts MIDI messages (pretty much all of them do!).

Here are some examples of free, open source synths for Linux, Windows, and mac os: &nbsp;

- [Helm](https://tytel.org/helm/) &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;
- [VCV Rack](https://vcvrack.com/)
- [Pure Data](https://puredata.info/)
- [Ardour](https://ardour.org/)

Launch your software synth and select the Pico CircuitPython keyboard as your MIDI source.

This video shows how root and mode selection work on startup. You can start over again at any time by pressing the reset button.

https://youtu.be/fkyYH2uwIVQ

## Root Note Selection

On startup, you can press each of the first 12 keys starting from the upper left corner of the keyboard to preview/select your scale root note.

Press the bottom right key to enter/commit the most recently previewed note.

## Mode Selection

Once your root note is picked, the Modal MIDI keyboard goes into mode selection configuration. Press each of the keys on the top row of the keyboard to preview each mode:

- Major/Ionian
- Minor/Aeolian
- Dorian
- Phrygian
- Lydian
- Mixolydian
- Locrian

You'll hear each note of the selected mode play. Once you like your choice, press the lower right key to enter.

Now, you can start playing all three octaves!

# Modal MIDI Keyboard

## How It Works

### Libraries

First, you'll import libraries for `time`, `board`, `digitalio`, `usb_midi`, `adafruit_midi`, and the `adafruit_debouncer`.

Next, you set your `MIDI_CHANNEL` variable to whichever real-world MIDI channel you want to use. This can be anything from 1-16.

The `midi` object is created to send over USB.

```python
import time
import board
from digitalio import DigitalInOut, Direction, Pull
import usb_midi
import adafruit_midi
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
from adafruit_debouncer import Debouncer

print("---Pico MIDI Modal Mech Keyboard---")

MIDI_CHANNEL = 1  # pick your MIDI channel here

midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=MIDI_CHANNEL-1)
```

### MIDI Panic

The `send_midi_panic()` function can be used to send a **noteOff** command on all 128 MIDI notes, which is used in rare cases where a note or notes get "stuck" in the on state. You'll trigger this function with a special keyboard shortcut.

```python
def send_midi_panic():
    print("All MIDI notes off")
    for x in range(128):
        midi.send(NoteOff(x, 0))
```

### Key Setup

You'll create a list of the 21 GPIO `pins` that will be used on the Pico, and then set them all as digital input debouncer objects in a list named `keys[]`.

```python
pins = (
    board.GP0,
    board.GP1,
    board.GP2,
    board.GP3,
    board.GP4,
    board.GP5,
    board.GP6,
    board.GP7,
    board.GP8,
    board.GP9,
    board.GP10,
    board.GP11,
    board.GP12,
    board.GP13,
    board.GP14,
    board.GP16,
    board.GP17,
    board.GP18,
    board.GP19,
    board.GP20,
    board.GP21,
)

keys = []
for pin in pins:
    tmp_pin = DigitalInOut(pin)
    tmp_pin.pull = Pull.UP
    keys.append(Debouncer(tmp_pin))
```

### Note Lists

These variables are lists of MIDI note numbers and names, as well as state variables.

```python
root_notes = (48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59)  # used during config
note_numbers = (48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
                60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
                72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83)
note_names = ("C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2",
              "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3",
              "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4",)
scale_root = root_notes[0]  # default if nothing is picked
root_picked = False  # state of root selection
mode_picked = False  # state of mode selection
mode_choice = 0
```

### User Config: Note Selection

You'll allow the user to select a root note using this section of code. It will wait until the user presses the bottom right key, a.k.a. `keys[20]`, until it move on.

```python
print("Pick the root using top twelve keys, then press bottom right key to enter:")
print(". . . . . . .")
print(". . . . . o o")
print("o o o o o o .")

while not root_picked:
    for i in range(12):
        keys[i].update()
        if keys[i].fell:
            scale_root = root_notes[i]
            midi.send(NoteOn(root_notes[i], 120))
            print("Root is", note_names[i])
        if keys[i].rose:
            midi.send(NoteOff(root_notes[i], 0))
    keys[20].update()

    if keys[20].rose:
        root_picked = True
        print("Root picked.\n")
```

### Mode Lists

You'll create lists of the interval formulas of the seven modes, which are relative to the root note. The `modes[]` list is a dictionary of these.

```python
major = ( 0, 2, 4, 5, 7, 9, 11 )
minor = ( 0, 2, 3, 5, 7, 8, 10 )
dorian = ( 0, 2, 3, 5, 7, 9, 10 )
phrygian = ( 0, 1, 3, 5, 7, 8, 10 )
lydian = (0 , 2, 4, 6, 7, 9, 11 )
mixolydian = ( 0, 2, 4, 5, 7, 9, 10)
locrian = ( 0, 1, 3, 5, 6, 8, 10)

modes = []
modes.append(major)
modes.append(minor)
modes.append(dorian)
modes.append(phrygian)
modes.append(lydian)
modes.append(mixolydian)
modes.append(locrian)

mode_names = ("Major/Ionian",
              "Minor/Aeolian",
              "Dorian",
              "Phrygian",
              "Lydian",
              "Mixolydian",
              "Locrian")

intervals = list(mixolydian)  # intervals for Mixolydian by default
```

### User Config: Mode Selection

The user now picks among the seven modes, with a preview played for each. The bottom right key confirms the selected mode and then moves on.

```python
print("Pick the mode with top seven keys, then press bottom right key to enter:")
print(". . . . . . .")
print("o o o o o o o")
print("o o o o o o .")

while not mode_picked:
    for i in range(7):
        keys[i].update()
        if keys[i].fell:
            mode_choice = i
            print(mode_names[mode_choice], "mode")
            for j in range(7):
                intervals[j] = modes[i][j]
            # play the scale
            for k in range(7):
                midi.send(NoteOn(scale_root+intervals[k], 120))
                note_index = note_numbers.index(scale_root+intervals[k])
                print(note_names[note_index])
                time.sleep(0.15)
                midi.send(NoteOff(scale_root+intervals[k], 0))
                time.sleep(0.15)
            midi.send(NoteOn(scale_root+12, 120))
            note_index = note_numbers.index(scale_root+12)
            print(note_names[note_index], "\n")
            time.sleep(0.15)
            midi.send(NoteOff(scale_root+12, 0))
            time.sleep(0.15)

    keys[20].update()
    if keys[20].rose:
        print(mode_names[mode_choice], "mode picked.\n")
        mode_picked = True
```

### Main Loop

In the main loop of the program the keys are checked for updates with the debouncer. If a key is pressed (fell) the associated **noteOn** message is sent, and when it it released (rose) the **noteOff** message is sent.

```python
for i in range(num_keys):
        keys[i].update()
        if keys[i].fell:
            try:
                midi.send(NoteOn(midi_notes[i], 120))
                note_index = note_numbers.index(midi_notes[i])
                print("MIDI NoteOn:", note_names[note_index])
            except ValueError:  # deals w six key limit
                pass

        if keys[i].rose:
            try:
                midi.send(NoteOff(midi_notes[i], 0))
                note_index = note_numbers.index(midi_notes[i])
                print("MIDI NoteOff:", note_names[note_index])
            except ValueError:
                pass
```

### Panic Key Combo

If the five key pattern of the outer corners and the center key are pressed, the `send_midi_panic()` function runs, turning off all notes.

```python
#  Key combo for MIDI panic
    # . o o o o o .
    # o o o . o o o
    # . o o o o o .

    if (not keys[0].value and
            not keys[6].value
            and not keys[10].value
            and not keys[14].value
            and not keys[20].value):
        send_midi_panic()
        time.sleep(1)
```


## Featured Products

### Kailh Mechanical Key Switches - 10 packs - Cherry MX Compatible

[Kailh Mechanical Key Switches - 10 packs - Cherry MX Compatible](https://www.adafruit.com/product/4996)
For crafting your very own custom keyboard, these **&nbsp;Kailh mechanical key switches** &nbsp;are deeee-luxe!

Come&nbsp;in a pack of 10 switches, plenty to make a small keyboard, or grab a few packs to build a full keyboard.

- Use these with our&nbsp;<a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/4996)
[Related Guides to the Product](https://learn.adafruit.com/products/4996/guides)
### DSA Keycaps for MX Compatible Switches in Various Colors

[DSA Keycaps for MX Compatible Switches in Various Colors](https://www.adafruit.com/product/5097)
Dress up your mechanical keys in your favorite colors, with a wide selection of stylish DSA key caps. Here is a 10 pack different colored keycaps for your next mechanical keyboard or [NeoKey](https://www.adafruit.com/?q=neokey&sort=BestMatch) project. Snap 'em onto...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5097)
[Related Guides to the Product](https://learn.adafruit.com/products/5097/guides)
### Raspberry Pi Pico RP2040

[Raspberry Pi Pico RP2040](https://www.adafruit.com/product/4864)
The Raspberry Pi foundation changed single-board computing [when they released the Raspberry Pi computer](https://www.raspberrypi.org/archives/723), now they're ready to do the same for microcontrollers with the release of the brand new **Raspberry Pi Pico**. This...

In Stock
[Buy Now](https://www.adafruit.com/product/4864)
[Related Guides to the Product](https://learn.adafruit.com/products/4864/guides)
### Wire Whisk Style Key Cap Remover / Puller

[Wire Whisk Style Key Cap Remover / Puller](https://www.adafruit.com/product/4977)
So you've got a slew of fun keycaps for your NeoKey or regular mechanical keypad project. You _could_&nbsp;manually replace them all one by one. But maybe you've got bigger&nbsp;hands, or you're nervous you might She-Hulk out on your keyboard. This wire-whisk looking tool...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/4977)
[Related Guides to the Product](https://learn.adafruit.com/products/4977/guides)
### Tactile Switch Buttons (6mm tall) x 10 pack

[Tactile Switch Buttons (6mm tall) x 10 pack](https://www.adafruit.com/product/1490)
Super-tall clicky momentary switches are standard input "buttons" on electronic projects. These work best in a PCB but [can be used on a solderless breadboard as shown in this tutorial](http://www.ladyada.net/learn/arduino/lesson5.html). The pins are normally open...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1490)
[Related Guides to the Product](https://learn.adafruit.com/products/1490/guides)
### Little Rubber Bumper Feet - Pack of 4

[Little Rubber Bumper Feet - Pack of 4](https://www.adafruit.com/product/550)
Keep your electronics from going barefoot, give them little rubber feet! These small sticky bumpers are our favorite accessory for any electronic kit or device. They are sticky, but not impossible to remove. They're small enough to fit onto any board, and have just enough height to give...

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

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

Approximately 3 feet / 1 meter long

In Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
### Brass M2.5 Standoffs 16mm tall - Black Plated - Pack of 2

[Brass M2.5 Standoffs 16mm tall - Black Plated - Pack of 2](https://www.adafruit.com/product/2337)
Finally we get our very own super sweet sixteen... 16 millimeters&nbsp;that is! Our&nbsp; **Black Plated M/F Brass 16mm Standoffs** &nbsp;are engineered specifically to&nbsp;keep [your&nbsp;PiTFT](https://www.adafruit.com/categories/160) or other Pi accessories with <a...></a...>

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

## Related Guides

- [Adafruit Swirly Aluminum Mounting Grid for 0.1" Spaced PCBs](https://learn.adafruit.com/swirly-grid.md)
- [Personal and Portable ESP32-S2 Web Server](https://learn.adafruit.com/wordle-personal-esp32-s2-web-server.md)
- [Light Up Prop with Prop-Maker](https://learn.adafruit.com/prop-maker-light-wand.md)
- [NeoPixel Mini VU Meter](https://learn.adafruit.com/neopixel-mini-vu-meter.md)
- [Raspberry Pi Pico and LED Arcade Button MIDI Controller](https://learn.adafruit.com/raspberry-pi-pico-led-arcade-button-midi-controller-fighter.md)
- [Getting Started with Microsoft Azure and CircuitPython](https://learn.adafruit.com/getting-started-with-microsoft-azure-and-circuitpython.md)
- [Ambient Sound Machine](https://learn.adafruit.com/ambient-machine.md)
- [HalloWing Magic 9 Ball](https://learn.adafruit.com/hallowing-magic-9-ball.md)
- [Holiday Tree with Feather RP2040 Scorpio](https://learn.adafruit.com/holiday-tree-with-scorpio.md)
- [CYBERDECK Expansion Plate](https://learn.adafruit.com/cyberdeck-plate.md)
- [Sketch Drawing Toy with CircuitPython](https://learn.adafruit.com/sketch-drawing-toy.md)
- [How to Build a Testing Jig](https://learn.adafruit.com/how-to-build-a-testing-fixture.md)
- [Pi SSD Media Server](https://learn.adafruit.com/pi-ssd-media-server.md)
- [Pico W YBox3](https://learn.adafruit.com/pico-w-ybox3.md)
- [Ninja Timer: Giant 7-Segment Display](https://learn.adafruit.com/ninja-timer-giant-7-segment-display.md)
