# ItsyBitsy Keybow Mechanical Keypad

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/091/690/medium800/gaming_keybitsy-2663.jpg?1591117605)

Use the ItsyBitsy M4/M0 as a custom USB mechanical keypad with CircuitPython!

The Pimoroni Keybow is a 12 mechanical keyswitch USB HID keyboard controller designed to work with a Raspberry Pi Zero.

We'll build a custom Pi Bonnet to adapt the Keybow for use with the Adafruit ItsyBitsy M4 or M0 microcontroller board and programmable in CircuitPython.

You can create custom key mapping, macros, media control and your own DotStar RGB lighting with this simple, fast booting, super-charged keypad!

## Adaptation Options

You've got a couple of options of how to adapt the Keybow to work with an ItsyBitsy M4 -- you can wire up the pins on a ProtoBonnet as shown in this guide, or [order this nifty PCB](https://oshpark.com/shared_projects/kxhinWVZ) (printed circuit board) designed by John Park for this exact purpose.

![](https://cdn-learn.adafruit.com/assets/assets/000/092/090/medium800/gaming_keybitsy_pcb-2738.jpg?1591885472)

Here are the Eagle CAD files for the board:

[ItsyBitsy_Keybow_04.brd](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ItsyBitsy/ItsyBitsy_Keybow/ItsyBitsy_Keybow_04.brd)
[ItsyBitsy_Keybow04.sch](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ItsyBitsy/ItsyBitsy_Keybow/ItsyBitsy_Keybow_04.sch)
## Parts
### Adafruit ItsyBitsy M4 Express featuring ATSAMD51

[Adafruit ItsyBitsy M4 Express featuring ATSAMD51](https://www.adafruit.com/product/3800)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M4 Express** featuring the **Microchip ATSAMD51**! Small, powerful, with a ultra fast ATSAMD51 Cortex M4 processor running at 120 MHz - this microcontroller board is perfect...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3800)
[Related Guides to the Product](https://learn.adafruit.com/products/3800/guides)
![Adafruit ItsyBitsy M4 Express featuring ATSAMD51 connected to a small breadboard. ](https://cdn-shop.adafruit.com/product-videos/640x480/3800-04.jpg)

### Adafruit Perma Proto Bonnet Mini Kit

[Adafruit Perma Proto Bonnet Mini Kit](https://www.adafruit.com/product/3203)
Design your own Bonnet or pHAT, attach custom circuitry and otherwise dress your Pi Zero with this jaunty prototyping Bonnet kit!

To add to&nbsp;the [Adafruit Bonnet party](https://www.adafruit.com/categories/929), we have this Perma-Proto inspired plug in daughter board. It...

In Stock
[Buy Now](https://www.adafruit.com/product/3203)
[Related Guides to the Product](https://learn.adafruit.com/products/3203/guides)
![Angled shot of a Adafruit Perma Proto Bonnet on a Pi zero](https://cdn-shop.adafruit.com/640x480/3203-02.jpg)

### "Wire Wrap" Thin Prototyping & Repair Wire - 200m 30AWG Blue

["Wire Wrap" Thin Prototyping & Repair Wire - 200m 30AWG Blue](https://www.adafruit.com/product/1446)
This stuff is called "wire-wrap wire" because it used to be used for wire-wrapping high-speed digital circuits on a special kind of contact board. It's pretty rare to see wire-wrapping in these days of low-cost PCB fabrication but the wire is still really handy for prototyping work. It's...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1446)
[Related Guides to the Product](https://learn.adafruit.com/products/1446/guides)
![Large spool of Wire Wrap Thin Prototyping & Repair Wire](https://cdn-shop.adafruit.com/640x480/1446-03.jpg)

# ItsyBitsy Keybow Mechanical Keypad

## CircuitPython on ItsyBitsy

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

## Set up CircuitPython Quick Start!
Follow this quick step-by-step for super-fast Python power :)

[Download the latest version of CircuitPython for this board via CircuitPython.org](https://circuitpython.org/board/itsybitsy_m4_express/)
## Further Information
For more detailed info on installing CircuitPython, check out [Installing CircuitPython](../../../../welcome-to-circuitpython/installing-circuitpython).

 **Click the link above and download the latest UF2 file.**

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

![adafruit_products_uf2.png](https://cdn-learn.adafruit.com/assets/assets/000/055/475/medium640/adafruit_products_uf2.png?1529260343)

Plug your Itsy M4 into your computer using a known-good USB cable.

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

Double-click the **Reset** button on your board, and you will see the DotStar RGB LED turn green. If it turns red, check the USB cable, try another USB port, etc.

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

![adafruit_products_3800.gif](https://cdn-learn.adafruit.com/assets/assets/000/055/476/medium640thumb/adafruit_products_3800.jpg?1529260376)

You will see a new disk drive appear called **ITSYBOOT**.

Drag the **adafruit\_circuitpython\_etc.uf2** file to **ITSYBOOT.**

![adafruit_products_itsyboot.png](https://cdn-learn.adafruit.com/assets/assets/000/055/477/medium640/adafruit_products_itsyboot.png?1529260440)

![adafruit_products_drag.png](https://cdn-learn.adafruit.com/assets/assets/000/055/478/medium640/adafruit_products_drag.png?1529260485)

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

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

![adafruit_products_circuitpy.png](https://cdn-learn.adafruit.com/assets/assets/000/055/479/medium640/adafruit_products_circuitpy.png?1529260731)

# ItsyBitsy Keybow Mechanical Keypad

## CircuitPython Libraries

Danger: 

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

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/961/medium800/circuitpython_WtCP_CIRCUITPY_contents.png?1635281033)

CircuitPython libraries work in the same way as regular Python modules so the [Python docs](https://docs.python.org/3/tutorial/modules.html) are an excellent reference for how it all should work. In Python terms, you can place our library files in the **lib** directory because it's part of the Python path by default.

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

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

Due to the regular updates and space constraints, Adafruit does not ship boards with the entire bundle. Therefore, you will need to load the libraries you need when you begin working with your board. You can find example code in the guides for your board that depends on external libraries.

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

# The Adafruit Learn Guide Project Bundle

The quickest and easiest way to get going with a project from the Adafruit Learn System is by utilising the Project Bundle. Most guides now have a **Download Project Bundle** button available at the top of the full code example embed. This button downloads all the necessary files, including images, etc., to get the guide project up and running. Simply click, open the resulting zip, copy over the right files, and you're good to go!

The first step is to find the Download Project Bundle button in the guide you're working on.

Info: 

![](https://cdn-learn.adafruit.com/assets/assets/000/111/837/medium800/circuitpython_PB_download_project_bundle_button.png?1652915277)

Warning: 

The Download Project Bundle button downloads a zip file. This zip contains a series of directories, nested within which is the **code.py** , any applicable assets like images or audio, and the **lib/** folder containing all the necessary libraries. The following zip was downloaded from the Piano in the Key of Lime guide.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/838/medium800/circuitpython_PB_downloaded_and_expanded_zip.png?1652915317)

Info: 

When you open the zip, you'll find some nested directories. Navigate through them until you find what you need. You'll eventually find a directory for your CircuitPython version (in this case, 7.x). In the version directory, you'll find the file and directory you need: **code.py** and **lib/**. Once you find the content you need, you can copy it all over to your **CIRCUITPY** drive, replacing any files already on the drive with the files from the freshly downloaded zip.

Info: 

Once you copy over all the relevant files, the project should begin running! If you find that the project is not running as expected, make sure you've copied ALL of the project files onto your microcontroller board.

That's all there is to using the Project Bundle!

# The Adafruit CircuitPython Library Bundle

Adafruit provides CircuitPython libraries for much of the hardware they provide, including sensors, breakouts and more. To eliminate the need for searching for each library individually, the libraries are available together in the Adafruit CircuitPython Library Bundle. The bundle contains all the files needed to use each library.

## Downloading the Adafruit CircuitPython Library Bundle

You can download the latest Adafruit CircuitPython Library Bundle release by clicking the button below. The libraries are being constantly updated and improved, so you'll always want to download the latest bundle.&nbsp;

**Match up the bundle version with the version of CircuitPython you are running.** For example, you would download the 6.x library bundle if you're running any version of CircuitPython 6, or the 7.x library bundle if you're running any version of CircuitPython 7, etc. If you mix libraries with major CircuitPython versions, you will get incompatible mpy errors due to changes in library interfaces possible during major version changes.

[Click to visit circuitpython.org for the latest Adafruit CircuitPython Library Bundle](https://circuitpython.org/libraries)
 **Download the bundle version that matches your CircuitPython firmware version.** If you don't know the version, check the version info in **boot\_out.txt** file on the **CIRCUITPY** drive, or the initial prompt in the CircuitPython REPL. For example, if you're running v7.0.0, download the 7.x library bundle.

There's also a **py** bundle which contains the uncompressed python files, you probably _don't_ want that unless you are doing advanced work on libraries.

# The CircuitPython Community Library Bundle

The CircuitPython Community Library Bundle is made up of libraries written and provided by members of the CircuitPython community. These libraries are often written when community members encountered hardware not supported in the Adafruit Bundle, or to support a personal project. The authors all chose to submit these libraries to the Community Bundle make them available to the community.

**These libraries are maintained by their authors and are not supported by Adafruit.** As you would with any library, if you run into problems, feel free to file an issue on the GitHub repo for the library. Bear in mind, though, that most of these libraries are supported by a single person and you should be patient about receiving a response. Remember, these folks are not paid by Adafruit, and are volunteering their personal time when possible to provide support.

## Downloading the CircuitPython Community Library Bundle

You can download the latest CircuitPython Community Library Bundle release by clicking the button below. The libraries are being constantly updated and improved, so you'll always want to download the latest bundle.

[Click for the latest CircuitPython Community Library Bundle release](https://github.com/adafruit/CircuitPython_Community_Bundle/releases)
The link takes you to the latest release of the CircuitPython Community Library Bundle on GitHub. There are multiple versions of the bundle available. **Download the bundle version that matches your CircuitPython firmware version.** If you don't know the version, check the version info in **boot\_out.txt** file on the **CIRCUITPY** drive, or the initial prompt in the CircuitPython REPL. For example, if you're running v7.0.0, download the 7.x library bundle.

# Understanding the Bundle

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/908/medium800/circuitpython_WtCP_lib_bundle_extracted.png?1635183852)

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/909/medium800/circuitpython_WtCP_lib_zip_contents.png?1635183864)

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/910/medium800/circuitpython_WtCP_lib_bundle_folder_contents.png?1635183871)

## Example Files

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

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/911/medium800/circuitpython_WtCP_examples_bundle_directory_contents.png?1635184002)

## Copying Libraries to Your Board

First open the **lib** folder on your **CIRCUITPY** drive. Then, open the **lib** folder you extracted from the downloaded zip. Inside you'll find a number of folders and **.mpy** files. Find the library you'd like to use, and copy it to the **lib** folder on **CIRCUITPY**.

If the library is a directory with multiple **.mpy** files in it, be sure to **copy the entire folder to CIRCUITPY/lib**.

This also applies to example files. Open the **examples** folder you extracted from the downloaded zip, and copy the applicable file to your **CIRCUITPY** drive. Then, rename it to **code.py** to run it.

Info: 

# Understanding Which Libraries to Install

You now know how to load libraries on to your CircuitPython-compatible microcontroller board. You may now be wondering, how do you know _which_ libraries you need to install? Unfortunately, it's not always straightforward. Fortunately, there is an obvious place to start, and a relatively simple way to figure out the rest. First up: the best place to start.

When you look at most CircuitPython examples, you'll see they begin with one or more `import` statements. These typically look like the following:

- `import library_or_module`

However, `import` statements can also sometimes look like the following:

- `from library_or_module import name`
- `from library_or_module.subpackage import name`
- `from library_or_module import name as local_name`

They can also have more complicated formats, such as including a `try` / `except` block, etc.

The important thing to know is that **an** `import` **statement will always include the name of the module or library that you're importing**.

Therefore, the best place to start is by reading through the `import` statements.

Here is an example import list for you to work with in this section. There is no setup or other code shown here, as the purpose of this section involves only the import list.

```python
import time
import board
import neopixel
import adafruit_lis3dh
import usb_hid
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode
```

Keep in mind, not all imported items are libraries. Some of them are almost always built-in CircuitPython modules. How do you know the difference? Time to visit the REPL.

In the [Interacting with the REPL section](https://learn.adafruit.com/welcome-to-circuitpython/the-repl#interacting-with-the-repl-2977486-14) on [The REPL page](https://learn.adafruit.com/welcome-to-circuitpython/the-repl) in this guide, the `help("modules")` command is discussed. This command provides a list of all of the built-in modules available in CircuitPython for your board. So, if you connect to the serial console on your board, and enter the REPL, you can run `help("modules")` to see what modules are available for your board. Then, as you read through the `import` statements, you can, for the purposes of figuring out which libraries to load, ignore the statement that import modules.

The following is the list of modules built into CircuitPython for the Feather RP2040. Your list may look similar or be anything down to a significant subset of this list for smaller boards.

![](https://cdn-learn.adafruit.com/assets/assets/000/105/967/medium800/circuitpython_WtCP_CP_libs_help_modules_feather_rp2040.png?1635369618)

Now that you know what you're looking for, it's time to read through the import statements. The first two, `time` and `board`, are on the modules list above, so they're built-in.

The next one, `neopixel`, is not on the module list. That means it's your first library! So, you would head over to the bundle zip you downloaded, and search for **neopixel**. There is a **neopixel.mpy** file in the bundle zip. Copy it over to the **lib** folder on your **CIRCUITPY** drive. The following one, `adafruit_lis3dh`, is also not on the module list. Follow the same process for **adafruit\_lis3dh** , where you'll find **adafruit\_lis3dh.mpy** , and copy that over.

The fifth one is `usb_hid`, and it is in the modules list, so it is built in. Often all of the built-in modules come first in the import list, but sometimes they don't! Don't assume that everything after the first library is also a library, and verify each import with the modules list to be sure. Otherwise, you'll search the bundle and come up empty!

The final two imports are not as clear. Remember, when `import` statements are formatted like this, the first thing after the `from` is the library name. In this case, the library name is `adafruit_hid`. A search of the bundle will find an **adafruit\_hid _folder_**. When a library is a folder, you must copy the **entire folder and its contents&nbsp;_as it is in the bundle_** to the **lib** folder on your **CIRCUITPY** drive. In this case, you would copy the entire **adafruit\_hid** folder to your **CIRCUITPY/lib** folder.

Notice that there are _two_ imports that begin with `adafruit_hid`. Sometimes you will need to import more than one thing from the same library. Regardless of how many times you import the same library, you only need to load the library by copying over the **adafruit\_hid** folder _once_.

That is how you can use your example code to figure out what libraries to load on your CircuitPython-compatible board!

There are cases, however, where libraries require other libraries internally. The internally required library is called a _dependency_. In the event of library dependencies, the easiest way to figure out what other libraries are required is to connect to the serial console and follow along with the `ImportError` printed there. The following is a very simple example of an `ImportError`, but the concept is the same for any missing library.

# Example: `ImportError` Due to Missing Library

If you choose to load libraries as you need them, or you're starting fresh with an existing example, you may end up with code that tries to use a library you haven't yet loaded.&nbsp; This section will demonstrate what happens when you try to utilise a library that you don't have loaded on your board, and cover the steps required to resolve the issue.

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

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

```auto
import board
import time
import simpleio

led = simpleio.DigitalOut(board.LED)

while True:
    led.value = True
    time.sleep(0.5)
    led.value = False
    time.sleep(0.5)
```

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/964/medium800/circuitpython_WtCP_serial_console_ImportError.png?1635355664)

You have an `ImportError`. It says there is `no module named 'simpleio'`. That's the one you just included in your code!

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

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

![](https://cdn-learn.adafruit.com/assets/assets/000/105/965/medium800/circuitpython_WtCP_CP_libraries_ImportError_resolved.png?1635355829)

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

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

# Library Install on Non-Express Boards

If you have an M0 non-Express board such as Trinket M0, Gemma M0, QT Py M0, or one of the M0 Trinkeys, you'll want to follow the same steps in the example above to install libraries as you need them. Remember, you don't need to wait for an `ImportError` if you know what library you added to your code. Open the library bundle you downloaded, find the library you need, and drag it to the **lib** folder on your **CIRCUITPY** drive.

You can still end up running out of space on your M0 non-Express board even if you only load libraries as you need them. There are a number of steps you can use to try to resolve this issue. You'll find suggestions on the [Troubleshooting page](https://learn.adafruit.com/welcome-to-circuitpython/troubleshooting).

# Updating CircuitPython Libraries and Examples

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

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

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

## CircUp CLI Tool

There is a command line interface (CLI) utility called [CircUp](https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup) that can be used to easily install and update libraries on your device. Follow the directions on the [install page within the CircUp learn guide](https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup/install-circup). Once you've got it installed you run the command `circup update` in a terminal to interactively update all libraries on the connected CircuitPython device. See the [usage page in the CircUp guide](https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup/usage) for a full list of functionality

# ItsyBitsy Keybow Mechanical Keypad

## Assemble the Bonnet

![](https://cdn-learn.adafruit.com/assets/assets/000/091/630/medium800/gaming_keybitsy-2432.jpg?1591025386)

The Keybow was designed to use power, ground, twelve IO pins for the switches, and the two SPI clock and data lines (for the DotStar LEDs) from the Raspberry Pi Zero.

To use the Keybow with the ItsyBitsy M4 or M0, we will redirect those Keybow pins from the 2x20 connector to an ItsyBitsy's layout. The Adafruit ProtoBonnet works well for adapting the Keybow's switch and DotStar pinout to the ItsyBitsy M4/M0.

Here's how the pins are mapped:

| Pi GPIO | Pi Physical Pin | ItsyBitsy M4 |
| 5V | 2 | Vhi |
| GPIO17 | 11 | A2 |
| GPIO27 | 13 | A1 |
| GPIO22 | 15 | A5 |
| GPIO23 | 16 | A0 |
| GPIO24 | 18 | A4 |
| MOSI | 19 | MO |
| SCLCK | 23 | SCK |
| GPIO5 | 29 | A3 |
| GPIO6 | 31 | D10 |
| GPIO12 | 32 | D9 |
| GPIO13 | 33 | D7 |
| GPIO16 | 36 | D12 |
| GPIO26 | 37 | D2 |
| GPIO20 | 38 | D11 |
| GND | (many) | GND |

The Keybow to ItsyBitsy pin mapping looks like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/091/625/medium800/gaming_12keyeagle.png?1591024560)

![](https://cdn-learn.adafruit.com/assets/assets/000/091/621/medium800/gaming_12keyfritz_scheme.png?1591023838)

Here is the same circuit diagrammed on the PermaBonnet:

![](https://cdn-learn.adafruit.com/assets/assets/000/091/632/medium800/gaming_12keyfritzC.png?1591026497)

![](https://cdn-learn.adafruit.com/assets/assets/000/091/623/medium800/gaming_12keyfritz.png?1591024305)

Alternately, here's what a PCB for the adapter looks like. It's included here as it may make the connections a bit clearer to follow than the wire diagram above.

![](https://cdn-learn.adafruit.com/assets/assets/000/091/626/medium800/gaming_12keypcbTop.png?1591024623)

![](https://cdn-learn.adafruit.com/assets/assets/000/091/627/medium800/gaming_12keypcbBottom.png?1591024627)

## Cable Testing
Initially, I tested the connections using M/F jumper cables and an ItsyBitsy M4 with male header pins soldered on (the final build required a fresh ItsyBitsy due to the different header pin orientation used).

This was good for proving out the pin assignments, but not entirely as ergonomic a package as desired.

![gaming_keybitsy-2418.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/631/medium640/gaming_keybitsy-2418.jpg?1591026093)

## Adapter Board Build

Now, we'll build the adapter board to use the ItsyBitsy seamlessly with the Keybow.

![](https://cdn-learn.adafruit.com/assets/assets/000/091/636/medium800/gaming_keybitsy-2409.jpg?1591026882)

## ProtoBonnet Headers
To build the proper adapter board, we'll use the ProtoBonnet. To it, solder the 2x20 male header pins and the two 14 pin, single-row headers spaced for the ItsyBitsy as shown here.

A good way to align the single-row pins is to tape the ItsyBitsy to the board as shown, then flip the board over for soldering.

Wait until the end to solder the ItsyBitsy itself onto the male headers, so that you can have room to solder the wiring in place.

![gaming_keybitsy-2417.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/633/medium640/gaming_keybitsy-2417.jpg?1591026720)

![gaming_keybitsy-2413.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/639/medium640/gaming_keybitsy-2413.jpg?1591026947)

## Wiring
Carefully follow the wiring diagrams and begin soldering short lengths of wire to make the connections between the Pi pin breakout row on the ProtoBonnet and the associated pins of the ItsyBitsy.

I found it easier to tack-solder some of the wires from the bottom side before flipping over to fully solder.

You'll notice there is one Pi pin we need to use that isn't broken out to the ProtoBonnet -- GPIO 26, which runs to D2 on the ItsyBitsy. For this one, we'll solder the wire directly to the header pin as shown.

![gaming_keybitsy-2411.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/640/medium640/gaming_keybitsy-2411.jpg?1591027007)

![gaming_keybitsy-2412.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/641/medium640/gaming_keybitsy-2412.jpg?1591027209)

![gaming_keybitsy-2426.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/642/medium640/gaming_keybitsy-2426.jpg?1591027251)

Warning: 

## Circuit Check

Once you're done soldering the circuit, use your multimeter in continuity mode to check each connection. Set one probe on a GPIO header pin and the other one on the associated ItsyBitsy header pin to make sure you have continuity.

Additionally, check to make sure all ground connections are shared, and that there are no shorts between power and ground.

## Solder the ItsyBitsy to the Board
Now you can place the ItsyBitsy M4/M0 back onto the header pins and solder them all in place.

![gaming_keybitsy-2428.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/643/medium640/gaming_keybitsy-2428.jpg?1591027680)

![gaming_keybitsy-2430.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/644/medium640/gaming_keybitsy-2430.jpg?1591027691)

## Trim the Excess Pin Lengths
While wearing eye protection, use diagonal flush cutters to trim the excess lengths of the ItsyBitsy header pins ONLY! Do not trim the 2x20 Raspberry Pi Bonnet headers!!

![gaming_keybitsy-2431.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/645/medium640/gaming_keybitsy-2431.jpg?1591027745)

![gaming_keybitsy-2434.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/646/medium640/gaming_keybitsy-2434.jpg?1591027766)

## Fit Check
Before connecting the ItsyBitsy adapter board to the acrylic base, do a test fit to make sure the board connects properly to the Keybow.

![gaming_keybitsy-2435.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/647/medium640/gaming_keybitsy-2435.jpg?1591027865)

![gaming_keybitsy-2436.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/648/medium640/gaming_keybitsy-2436.jpg?1591027872)

## Enclosure
Now, you can connect the ItsyBitsy adapter board to the Keybow base and fully assemble the board using M2.5 nylon standoffs and screws.

Follow the [original Keybow instructions](https://learn.pimoroni.com/tutorial/sandyj/assembling-keybow) for this, substituting the ItsyBitsy adapter board for the Pi Zero. Since the wiring and header pins make this board a bit taller than the Pi Zero you may need an extra bit of room to fit it by adding a longer screws in a couple of spots. The nylon M2.5 screw and standoff kit is great for this.

![gaming_keybitsy-2438.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/649/medium640/gaming_keybitsy-2438.jpg?1591027949)

![gaming_keybitsy-2439.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/650/medium640/gaming_keybitsy-2439.jpg?1591027957)

![](https://cdn-learn.adafruit.com/assets/assets/000/091/689/medium800/gaming_keybitsy-2659.jpg?1591117573)

# PCB Adapter Build

If you choose to order a PCB adapter instead, here's how you'll assemble it.

## Pi Headers

Place the 2x20 male Pi header pins into the board as shown.

You can use the Keybow to hold the pins in place as you solder them from the back side of the board.

![gaming_keybitsy_pcb-2742.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/091/medium640/gaming_keybitsy_pcb-2742.jpg?1591885661)

![gaming_keybitsy_pcb-2741.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/092/medium640/gaming_keybitsy_pcb-2741.jpg?1591885682)

## Itsy Headers

Next, fit the two ItsyBitsy male header pin rows into the board as shown.

You can hold them in place with some poster putty or tape and then flip the board over and solder the pins in from the back. Push the pins flush with the board with the soldering iron as you go for the best fit, or trim the extra points off later with some flush cutters. (The Pi Zero we're replacing has a totally flat back.)

If you want to go the extra mile, do not solder the ItsyBitsy in place yet! We're going to remove the headers' black plastic spacers to get a super low profile so the ItsyBitsy will fit neatly in the case.

Alternately, you can solder the ItsyBitsy to the unmodified pins, but you may need some extra spacers for the acrylic case.

Carefully pry up the black plastic spacers, you'll be left with bare pins (or a very tiny bed of nails depending on your perspective).

Now, solder the ItsyBitsy M4 to the pins, and then trim off the excess.

![gaming_keybitsy_pcb-2744.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/093/medium640/gaming_keybitsy_pcb-2744.jpg?1591885790)

![gaming_keybitsy_pcb-2745.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/094/medium640/gaming_keybitsy_pcb-2745.jpg?1591886338)

![gaming_keybitsy_pcb-2746.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/095/medium640/gaming_keybitsy_pcb-2746.jpg?1591886435)

![gaming_keybitsy_pcb-2747.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/096/medium640/gaming_keybitsy_pcb-2747.jpg?1591886514)

![gaming_keybitsy_pcb-2748.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/097/medium640/gaming_keybitsy_pcb-2748.jpg?1591886531)

## Mounting

You can now mount the Itsy/Pi adapter to the acrylic case -- it has the same dimensions as the Pi Zero it is replacing.

Affix the Keybow to the board and off we go!

![gaming_keybitsy_pcb-2750.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/099/medium640/gaming_keybitsy_pcb-2750.jpg?1591886650)

![gaming_keybitsy_pcb-2749.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/100/medium640/gaming_keybitsy_pcb-2749.jpg?1591886659)

![gaming_keybitsy_pcb-2752.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/101/medium640/gaming_keybitsy_pcb-2752.jpg?1591886681)

![gaming_keybitsy_pcb-2753.jpg](https://cdn-learn.adafruit.com/assets/assets/000/092/102/medium640/gaming_keybitsy_pcb-2753.jpg?1591886691)

![](https://cdn-learn.adafruit.com/assets/assets/000/092/103/medium800/gaming_keybitsy_pcb-2755.jpg?1591886706)

Next, we'll code the ItsyBitsy Keybow in CircuitPython so it can be customized to send HID USB keyboard commands and light the DotStar LEDs.

# ItsyBitsy Keybow Mechanical Keypad

## Code and Use the ItsyBitsy Keyboard

![](https://cdn-learn.adafruit.com/assets/assets/000/091/701/medium800/gaming_IMG_2656.jpg?1591138410)

## Libraries
Once your ItsyBitsy is set up with CircuitPython 5.3.0 or greater, you'll also need to add some libraries. [Follow this page](https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries) for information on how to download and add libraries to your ItsyBitsy.

From the library bundle you downloaded in that guide page, transfer the following libraries onto the ItsyBity **/lib** directory on the **CIRCUITPY** drive:

- **adafruit\_bus\_device**
- **adafruit\_dotstar**
- **adafruit\_hid**
- **adafruit\_led\_animation**
- **neopixel**
- **simpleio**

![gaming_keybowlibs.png](https://cdn-learn.adafruit.com/assets/assets/000/091/692/medium640/gaming_keybowlibs.png?1591119165)

## Text Editor

Adafruit recommends using the Mu editor for using your CircuitPython code with the ItsyBitsy boards. 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.

## Code.py

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

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

https://youtu.be/lbQvlTmO7cg

## Testing
With the code.py loaded onto your ItsyBitsy M4/M0, you'll see the Keybow DotStar LEDs light up with a startup animation, and then they'll settle into their color coded default stated.

Try pressing the four amber top row keys -- they control media play/pause, mute, and volume up/down.

To test the dark blue copy/paste keys, first select some text and hit the left copy key. Then, place your cursor in a text field and press the right paste key.

The magenta keys are up/down/left/right arrows for navigation.

Be careful with the purple key, it's the delete key!

And the cyan key is the spacebar.

![gaming_keybitsy-2672b.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/694/medium640/gaming_keybitsy-2672b.jpg?1591121060)

https://youtu.be/h4GYleur6JQ

## Customizing the Code
There are nearly limitless customization you can do to make your ItsyBitsy Keybow work the way you want! Here are a few to try:

- color
- key assignments
- orientation
- animation

![gaming_keybitsy-2662.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/707/medium640/gaming_keybitsy-2662.jpg?1591138743)

![gaming_keybitsy-2661.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/708/medium640/gaming_keybitsy-2661.jpg?1591138750)

## Keybow Orientation
We can use the Keybow in a vertical or horizontal orientation by re-assigning the relationship in code between the physical pins and their logical representations. This means that we can rotate the board by only changing a single variable and the key colors and assignments will update automatically.

So, for example, if we use this assignment in vertical orientation:

`a b c`

`d e f`

`g h 1`

`2 3 4`

It will become this when set to horizontal orientation:

`a b c d`

`e f g h`

`1 2 3 4`

![gaming_orientkeypad_vertical.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/696/medium640/gaming_orientkeypad_vertical.jpg?1591128673)

![gaming_orientkeypad_horizontal.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/697/medium640/gaming_orientkeypad_horizontal.jpg?1591128686)

This is accomplished by setting the `orientation` variable to `0` or `1`, which then chooses which `pins` list to use. These set the logical order from 0-11 to use the physical pins on the ItsyBitsy that are wired via the ProtoBonnet to the Keybow.

```python
orientation = 0  # 0 = portrait/vertical, 1 = landscape/horizontal

# Pin definitions
if orientation == 0:  # 0 = portrait/vertical
    pins = [
        board.D11,
        board.D12,
        board.D2,
        board.D10,
        board.D9,
        board.D7,
        board.A5,
        board.A4,
        board.A3,
        board.A2,
        board.A1,
        board.A0,
    ]
if orientation == 1:  # 1 = landscape/horizontal
    pins = [
        board.A2,
        board.A5,
        board.D10,
        board.D11,
        board.A1,
        board.A4,
        board.D9,
        board.D12,
        board.A0,
        board.A3,
        board.D7,
        board.D2,
    ]
```

Here's an example of the vertical orientation and some alternate keycaps.

![](https://cdn-learn.adafruit.com/assets/assets/000/091/704/medium800/gaming_keybitsy-2183.jpg?1591138570)

The `orientation` variable also is used to remap the DotStar physical order to the appropriate logical order.

The physical order of the DotStar LEDs can be seen in the diagram to the left.

So, to use these with our keymap ordering, the code below is used, with the if `orientation == 1:` list:

![gaming_orientkeypad_dots.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/700/medium640/gaming_orientkeypad_dots.jpg?1591129937)

```python
if orientation == 0:
    key_dots = [0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11]
    # 0  #4  #8
    # 1  #5  #9
    # 2  #6  #10
    # 3  #7  #11
if orientation == 1:
    key_dots = [3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8]
    # 3  #2  #1  #0
    # 7  #6  #5  #4
    # 11 #10 #9  #8
```

Info: 

## HID Keyboard Basics

[This guide page](https://learn.adafruit.com/adafruit-gemma-m0/circuitpython-hid-keyboard-and-mouse) has a great intro to CircuitPython HID Keyboard.

For even more details, check out the documentation at [https://circuitpython.readthedocs.io/projects/hid/en/latest/](https://circuitpython.readthedocs.io/projects/hid/en/latest/) which includes all of the keycodes and media codes you can use.

By importing the **adafruit\_hid** library into our program we can make calls to send keyboard keys and media keys.

## Keyboard Press/Release

Using the HID library in CircuitPtyhon, we can send this command to "type" the letter 'a':

`kbd.press(Keycode.A)`

`kbd.release(Keycode.A)`

This would send a lowercase 'a' to the computer just as if you had typed it yourself. To send a capital 'A', we'd add the shift key to the command like this:

`kbd.press(Keycode.SHIFT, Keycode.A)`

`kbd.release(Keycode.SHIFT, Keycode.A)`

This is pretty cool, since it means we can layer on lots of keys all at the same time, just like you do on your physical keyboard when using keyboard shortcuts!

So, if there's some keyboard shortcut you want to use (or create for yourself in something like Quicksilver or AutoKeys) that is **command+option+ctrl+a** the CircuitPython code would look like this:

`kbd.press(Keycode.GUI, Keycode.ALT, Keycode.CONTROL, Keycode.A)`

`kbd.release(Keycode.GUI, Keycode.ALT, Keycode.CONTROL, Keycode.A)`

Primary: 

## Media Control
There is a second command we'll use when we want to adjust volume, play/pause, skip tracks, and so on with media such as songs and videos. These are often represented on a physical keyboard as icons silkscreened onto the rightmost function keys.

In USB HID speak, these are known as "Consumer Control codes". To play or pause a track we'll use this command:

`cc.send(ConsumerControlCode.PLAY_PAUSE)`

![gaming_keybitsy-2656.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/705/medium640/gaming_keybitsy-2656.jpg?1591138671)

![gaming_keybitsy-2657.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/706/medium640/gaming_keybitsy-2657.jpg?1591138678)

## Key Assignements

With that in mind, you can now fully customize the function of each key by editing this section of the code:

```python
keymap = {
    (0): (AMBER, MEDIA, ConsumerControlCode.PLAY_PAUSE),
    (1): (AMBER, MEDIA, ConsumerControlCode.MUTE),
    (2): (AMBER, MEDIA, ConsumerControlCode.VOLUME_DECREMENT),
    (3): (AMBER, MEDIA, ConsumerControlCode.VOLUME_INCREMENT),
    (4): (BLUE, KEY, (Keycode.GUI, Keycode.C)),
    (5): (BLUE, KEY, (Keycode.GUI, Keycode.V)),
    (6): (MAGENTA, KEY, [Keycode.UP_ARROW]),
    (7): (PURPLE, KEY, [Keycode.BACKSPACE]),
    (8): (BLUE, KEY, [Keycode.SPACE]),
    (9): (MAGENTA, KEY, [Keycode.LEFT_ARROW]),
    (10): (MAGENTA, KEY, [Keycode.DOWN_ARROW]),
    (11): (MAGENTA, KEY, [Keycode.RIGHT_ARROW]),
}
```

Note, in order to use a single stroke keycode, you'll surround it in [brackets], while a multi-stroke keycode will have its own (parentheses) as shown here:

```python
(4): (BLUE, KEY, [Keycode.C]),
(5): (BLUE, KEY, (Keycode.SHIFT, Keycode.C)),
```

Since we can use the orientation variable as shown above, the keymap values pertain to the keys starting at the origin key in the upper left corner of the board and moving left to right, top to bottom toward the last key in the lower right corner in either case.

## Colors

On easy way to customize colors is to simply change the `keymap` color assignments, or, you can create your own colors to augment this list:

```python
RED = 0xFF0000
AMBER = 0xAA9900
BLUE = 0x0066FF
MAGENTA = 0xFF00FF
PURPLE = 0x3B0F85
BLACK = 0x000000
```

## Animation

In this code we're doing a simple animation at startup by calling the `dot_on()` function with different color settings.

However, if you want to get HIGHLY FANCY, -- and who doesn't?! -- you can use the adafruit\_led\_animation library to create beautiful effects. Here's a great guide for getting started with [CircuitPython LED Animation](https://learn.adafruit.com/circuitpython-led-animations/overview)

Here's an example of some adafruit\_led\_animation library sequences running on the ItstyBitsy Keybow's DotStars. (Note, this is an animation example only and doesn't have key functions.)

https://youtu.be/1hGkHdum1Ao

```python
import board
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.chase import Chase
from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.helper import PixelMap
from adafruit_led_animation.color import RED, BLUE, GREEN
import adafruit_dotstar as dotstar

dots = dotstar.DotStar(board.SCK, board.MOSI, 12, brightness=0.85, auto_write=False)

pixel_grid = PixelMap(dots, [
    [3],  [2],  [1],  [0],
    [7],  [6],  [5],  [4],
    [11], [10], [9],  [8],
], individual_pixels=True)

blink = Blink(pixel_grid, speed=0.5, color=BLUE)
comet = Comet(pixel_grid, speed=0.03, color=RED, tail_length=12)
chase = Chase(pixel_grid, speed=0.1, color=GREEN, size=1, spacing=3)
animations = AnimationSequence(chase, comet, blink, advance_interval=2, auto_clear=True)

while True:
    animations.animate()
```


## Featured Products

### Adafruit ItsyBitsy M4 Express featuring ATSAMD51

[Adafruit ItsyBitsy M4 Express featuring ATSAMD51](https://www.adafruit.com/product/3800)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M4 Express** featuring the **Microchip ATSAMD51**! Small, powerful, with a ultra fast ATSAMD51 Cortex M4 processor running at 120 MHz - this microcontroller board is perfect...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3800)
[Related Guides to the Product](https://learn.adafruit.com/products/3800/guides)
### Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE

[Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE](https://www.adafruit.com/product/3727)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M0 Express**! Small, powerful, with a rockin' ATSAMD21 Cortex M0 processor running at 48 MHz - this microcontroller board is perfect when you want something very compact, but still...

In Stock
[Buy Now](https://www.adafruit.com/product/3727)
[Related Guides to the Product](https://learn.adafruit.com/products/3727/guides)
### Pimoroni Keybow Mini Mechanical Keyboard Kit with Raspberry Pi

[Pimoroni Keybow Mini Mechanical Keyboard Kit with Raspberry Pi](https://www.adafruit.com/product/4144)
 **Discontinued** - [you can grab this&nbsp;Adafruit MacroPad RP2040 Starter Kit - 3x4 Keys + Encoder + OLED - ADABOX019 Essentials instead!](https://www.adafruit.com/product/5128)

Glow up for keyboards! Pimoroni's **Keybow** is a solderless mini mechanical...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/4144)
[Related Guides to the Product](https://learn.adafruit.com/products/4144/guides)
### Adafruit Perma Proto Bonnet Mini Kit

[Adafruit Perma Proto Bonnet Mini Kit](https://www.adafruit.com/product/3203)
Design your own Bonnet or pHAT, attach custom circuitry and otherwise dress your Pi Zero with this jaunty prototyping Bonnet kit!

To add to&nbsp;the [Adafruit Bonnet party](https://www.adafruit.com/categories/929), we have this Perma-Proto inspired plug in daughter board. It...

In Stock
[Buy Now](https://www.adafruit.com/product/3203)
[Related Guides to the Product](https://learn.adafruit.com/products/3203/guides)
### "Wire Wrap" Thin Prototyping & Repair Wire - 200m 30AWG Blue

["Wire Wrap" Thin Prototyping & Repair Wire - 200m 30AWG Blue](https://www.adafruit.com/product/1446)
This stuff is called "wire-wrap wire" because it used to be used for wire-wrapping high-speed digital circuits on a special kind of contact board. It's pretty rare to see wire-wrapping in these days of low-cost PCB fabrication but the wire is still really handy for prototyping work. It's...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1446)
[Related Guides to the Product](https://learn.adafruit.com/products/1446/guides)
### Break-away 0.1" 2x36-pin strip dual male header (10 pieces)

[Break-away 0.1" 2x36-pin strip dual male header (10 pieces)](https://www.adafruit.com/product/1539)
Breakaway header is like the duct tape of electronics. Its great for connecting things together, soldering to perf-boards, fits into any breadboard, etc. We go through these guys real fast, and thought that given how handy they are, we'd offer them in a pack of ten!  
  
Each pack...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/1539)
[Related Guides to the Product](https://learn.adafruit.com/products/1539/guides)

## Related Guides

- [Introducing ItsyBitsy M0 Express](https://learn.adafruit.com/introducing-itsy-bitsy-m0.md)
- [A CLI in CircuitPython](https://learn.adafruit.com/a-cli-in-circuitpython.md)
- [Multi-tasking with CircuitPython](https://learn.adafruit.com/multi-tasking-with-circuitpython.md)
- [CircuitPython Animated Sprite Pendants](https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters.md)
- [USB HID Crank Controller](https://learn.adafruit.com/usb-hid-crank-controller.md)
- [Using MCP23008 & MCP23017 with CircuitPython](https://learn.adafruit.com/using-mcp23008-mcp23017-with-circuitpython.md)
- [MakeCode Maker](https://learn.adafruit.com/makecode-maker.md)
- [Faderwave Synthesizer](https://learn.adafruit.com/faderwave-synthesizer.md)
- [A NeoPixel Pomodoro Timer](https://learn.adafruit.com/a-neopixel-pomodoro-timer.md)
- [Motorized Turntable](https://learn.adafruit.com/motorized-turntable-circuitpython.md)
- [CircuitPython with Jupyter Notebooks](https://learn.adafruit.com/circuitpython-with-jupyter-notebooks.md)
- [Sensor Plotting with Mu and CircuitPython](https://learn.adafruit.com/sensor-plotting-with-mu-and-circuitpython.md)
- [How to Program SAMD Bootloaders](https://learn.adafruit.com/how-to-program-samd-bootloaders.md)
- [How to train new TensorFlow Lite micro speech models](https://learn.adafruit.com/how-to-train-new-tensorflow-lite-micro-speech-models.md)
- [Using Python on Windows 10](https://learn.adafruit.com/using-python-on-windows-10.md)
- [A Logger for CircuitPython](https://learn.adafruit.com/a-logger-for-circuitpython.md)
