# "Mother of all Demos" USB Keyset

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/137/169/medium800thumb/3d_printing_demoB.jpg?1748361611 )

https://youtu.be/A8RW3y0CIgw

## Custom USB HID

This is a take on a custom computer input device, inspired by the [original Doug Engelbert "Mother of all Demos" keyset from the 1960's](https://www.youtube.com/watch?v=UhpTiWyVa6k) that never quite caught on. This 5-finger keyset lets you type without moving your hand, entering full words and phrases by pressing multiple keys simultaneously as a chord.

It connects to a computer (PC, Mac, Linux, iOS) and appears as an additional keyboard. CircuitPython makes it easy to create keyboard devices with microcontrollers containing native USB.

## 3D Printed Chording Keyset

It features an Adafruit QT Py RP2040 running CircuitPython code. The case design is fully 3D printed and uses CHOC low-profile key switches. The piano-style keys are inspired by a hinged lever mechanism that is commonly used in traditional piano instruments.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/137/171/medium640/3d_printing_hero-keyset.jpg?1748363164)

## Nod to Mother of All Demos

This project is inspired by&nbsp;[Ken Shirriff's](https://www.righto.com/2025/03/mother-of-all-demos-usb-keyset-interface.html) blog post. Our remake pays homage to the original keyset from the Zerox Alto computer. It features similar dimensions and piano-style keys.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/170/medium640/3d_printing_usb-keyset-interface.jpg?1748361806)

# Parts
### Adafruit QT Py RP2040

[Adafruit QT Py RP2040](https://www.adafruit.com/product/4900)
What a cutie pie! Or is it... a QT Py?&nbsp;This diminutive dev board comes with one of our new favorite chip, the RP2040. It's been made famous in the new [Raspberry Pi Pico](https://www.adafruit.com/pico) _and_ our [Feather...](http://www.adafruit.com/product/4884)

In Stock
[Buy Now](https://www.adafruit.com/product/4900)
[Related Guides to the Product](https://learn.adafruit.com/products/4900/guides)
![Video of hand holding a QT Py PCB in their hand. An LED glows rainbow colors.](https://cdn-shop.adafruit.com/product-videos/640x480/4900-06.jpg)

### Kailh CHOC Low Profile White Clicky Key Switches

[Kailh CHOC Low Profile White Clicky Key Switches](https://www.adafruit.com/product/5114)
For crafting your very own custom keyboard, these **&nbsp;Kailh Choc Low Profile Clicky White&nbsp;mechanical key switches** &nbsp;are super slim, with ultra-low profile compared to MX compatible switches!

Please note these are&nbsp; **NOT MX...**

In Stock
[Buy Now](https://www.adafruit.com/product/5114)
[Related Guides to the Product](https://learn.adafruit.com/products/5114/guides)
![Angled shot of ten white Kailh Choc V1 keycaps.](https://cdn-shop.adafruit.com/640x480/5114-00.jpg)

### Switch Sockets for Kailh CHOC Compatible Keys - 10 Pack

[Switch Sockets for Kailh CHOC Compatible Keys - 10 Pack](https://www.adafruit.com/product/5118)
Back in _my_ day, if you wanted to make a mechanical keyboard, you had to solder in expensive key switches onto your PCB - and woe to the person who decided they wanted to change their linear keys instead of clicky ones! Bah humbug, kids these days have no idea, what with their...

In Stock
[Buy Now](https://www.adafruit.com/product/5118)
[Related Guides to the Product](https://learn.adafruit.com/products/5118/guides)
![Angled shot of ten Choc switch sockets.](https://cdn-shop.adafruit.com/640x480/5118-00.jpg)

### Silicone Cover Stranded-Core Wire - 50ft 30AWG White

[Silicone Cover Stranded-Core Wire - 50ft 30AWG White](https://www.adafruit.com/product/3169)
//www.youtube.com/embed/W85OajXuDRA
?start=10

Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3169)
[Related Guides to the Product](https://learn.adafruit.com/products/3169/guides)
![A spool of white AWG wire.](https://cdn-shop.adafruit.com/640x480/3169-01.jpg)

### Silicone Cover Stranded-Core Wire - 50ft 30AWG Blue

[Silicone Cover Stranded-Core Wire - 50ft 30AWG Blue](https://www.adafruit.com/product/3166)
Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness has to...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3166)
[Related Guides to the Product](https://learn.adafruit.com/products/3166/guides)
![A spool of light blue AWG wire.](https://cdn-shop.adafruit.com/640x480/3166-01.jpg)

### Part: USB-C Cable
quantity: 1
Blue USB Type C to USB A Cable with 540 Degree Rotating End - 1 meter long
[USB-C Cable](https://www.adafruit.com/product/6278)

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

# "Mother of all Demos" USB Keyset

## Circuit Diagram

The diagram below provides a general visual reference for wiring of the components once you get to the **Assembly** page. This diagram was created using the software package [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 [GitHub - Adafruit Fritzing Parts](https://github.com/adafruit/Fritzing-Library/tree/master/parts).

![](https://cdn-learn.adafruit.com/assets/assets/000/137/154/medium800/3d_printing_circuit-diagram.jpg?1748349964 )

## Wired Connections

- **Switch 1** to&nbsp; **A1** &nbsp;pin on **QTPy RP2040**
- **Switch 2** to&nbsp; **A2** &nbsp;pin on **QTPy RP2040**
- **Switch 3** to **A3** &nbsp;pin on **QTPy RP2040**
- **Switch 4** to **MI** pin on **QTPy RP2040**
- **Switch 5** to **MO** pin o **n QTPy RP2040**
- **GND** pin from **Switches** are shared (connected together)
- **Switch 5** &nbsp;to **GND** pin on **QTPy RP2040**

The **QTPy RP2040** is powered via USB.

# "Mother of all Demos" USB Keyset

## CAD Files

## CAD Assembly

The main assembly is available in Fusion 360 and STEP file formats. This includes all of the 3D printed parts and electronic components used in the project. Use the main assembly to create any edits, updates, or modifications.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/137/197/medium640thumb/3d_printing_cad.jpg?1748432202)

## 3D Printed Parts

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

![](https://cdn-learn.adafruit.com/assets/assets/000/137/156/medium640/3d_printing_slice-parts.jpg?1748352221)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/180/medium640/3d_printing_3d-parts.jpg?1748363799)

[3MF.zip](https://cdn-learn.adafruit.com/assets/assets/000/137/307/original/3MF.zip?1748881838)
[CAD.zip](https://cdn-learn.adafruit.com/assets/assets/000/137/308/original/CAD.zip?1748881912)
## Build Volume

The parts require a 3D printer with a minimum build volume of:

- 130mm (X) x 110mm (Y) x 122mm (Z)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/198/medium640/3d_printing_slice-size.jpg?1748432309)

## Design Source Files

The project assembly was designed in Fusion 360. Once opened in Fusion 360, It can be exported in different formats like STEP, STL and more.

Electronic components like Adafruit's boards, displays, connectors and more can be downloaded from the&nbsp;[Adafruit CAD parts GitHub Repo](https://github.com/adafruit/Adafruit_CAD_Parts/).

![](https://cdn-learn.adafruit.com/assets/assets/000/137/199/medium640thumb/3d_printing_4900_QTPY-RP2040.jpg?1748432446)

# "Mother of all Demos" USB Keyset

## 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_qtpy_rp2040/)
 **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/101/680/medium800/adafruit_products_QTRP_buttons.jpg?1618956837)

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)
# "Mother of all Demos" USB Keyset

## Code the Keyset

![](https://cdn-learn.adafruit.com/assets/assets/000/137/191/medium800/3d_printing_code.jpg?1748374233 )

Once you've finished setting up your QT Py RP2040 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/Mother_Of_All_Demos_Keyset/code.py

## Upload the Code and Libraries to the QT Py RP2040

After downloading the Project Bundle, plug your QT Py RP2040 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 QT Py RP2040's **CIRCUITPY** drive.

- **lib** folder
- **code.py**

Your QT Py RP2040 **CIRCUITPY** drive should look like this after copying the **lib** folder and **code.py** file:

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

## How the Code Works

There is a dictionary at the top of the code called `macros`. In `macros`, the keys and strings are listed out. If you want to change the default macros, you'll want to edit this dictionary.

```python
macros = {
    # Single key macros
    (0,): "good",
    (1,): "great",
    (2,): "nice",
    (3,): "awesome",
    (4,): "cool",

    # Combination macros
    (0, 2, 4): "looks good to me",
    (0, 2): "be right back",
    (2, 4): "see you soon",
    (1, 3): "sounds good",
}
```

### Keypad

The keypad module is used to handle the key presses. These key events will be passed to the USB HID keyboard object in the loop.

```python
KEY_PINS = (
    board.A1,
    board.A2,
    board.A3,
    board.MISO,
    board.MOSI,
)

keys = keypad.Keys(
    KEY_PINS,
    value_when_pressed=False,
    pull=True,
    interval=0.01,
    max_events=64,
    debounce_threshold=3
)

keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)
```

### Timing

There are a few timing variables that are used in the loop to figure out if you are pressing a single key macro or a multi key macro. Instead of creating a new event each time a key is pressed in the loop, a reusable event is used. This way the multi key macros will work.

```python
# need to wait longer for 3 key combos
LARGER_COMBOS = {
    (0, 2): (0, 2, 4),
    (2, 4): (0, 2, 4),
}

# How long to wait for possible additional keys in a combo (ms)
COMBO_WAIT_TIME = 150  # Wait 150ms to see if more keys are coming

# How long to wait for a single key before executing (ms)
SINGLE_KEY_TIMEOUT_MS = 80

# Minimum time between macro executions (ms)
MACRO_COOLDOWN_MS = 300

# Store the current state of all keys
key_states = {i: False for i in range(len(KEY_PINS))}

# Create a reusable Event object to avoid memory allocations
reusable_event = keypad.Event()

# Track timing and state
last_macro_time = 0
key_combo_start_time = 0
waiting_for_combo = False
last_executed_combo = None
```

### The Loop

In the loop, a check is done to see if new keys have been pressed. The time is tracked with ticks to determine if a single key or multi key macro is being executed. When the keys are released, all of the tracking is reset.

```python
while True:
    # Process all events in the queue
    keys_changed = False

    while keys.events:
        if keys.events.get_into(reusable_event):
            # Check if key state actually changed
            old_state = key_states[reusable_event.key_number]
            key_states[reusable_event.key_number] = reusable_event.pressed

            if old_state != reusable_event.pressed:
                print(f"Key {reusable_event.key_number} " +
                f"{'pressed' if reusable_event.pressed else 'released'}")
                keys_changed = True

    # Get currently pressed keys as a sorted tuple
    current_pressed_keys = tuple(sorted(k for k, v in key_states.items() if v))
    current_time = supervisor.ticks_ms()
    
        # When all keys are released, reset tracking
    if not current_pressed_keys:
        waiting_for_combo = False
        last_executed_combo = None
        time.sleep(0.01)
        continue

    # If this is a new key pattern or we just started
    if keys_changed:
        # If we weren't tracking before, start now
        if not waiting_for_combo:
            key_combo_start_time = current_time
            waiting_for_combo = True

        # If the pressed keys have changed, update the timer
        if current_pressed_keys != last_executed_combo:
            key_combo_start_time = current_time

    # Skip if we've already executed this exact combination
    if current_pressed_keys == last_executed_combo:
        time.sleep(0.01)
        continue
```

When the macro type has been determined, the matching string from the `macros` dictionary is sent as a USB HID message.

```python
# Determine if we should execute a macro now
    should_execute = False
    wait_more = False

    # If this is a potential part of a larger combo, wait longer
    if current_pressed_keys in LARGER_COMBOS:
        # Only wait if we've been waiting less than the combo wait time
        if (current_time - key_combo_start_time) &lt; COMBO_WAIT_TIME:
            wait_more = True
        else:
            # We've waited long enough, go ahead and execute
            should_execute = True
    # Immediate execution for multi-key combinations that aren't potential parts of larger combos
    elif len(current_pressed_keys) &gt; 1:
        should_execute = True
    # Execute single key after timeout
    elif waiting_for_combo and (current_time - key_combo_start_time) &gt;= SINGLE_KEY_TIMEOUT_MS:
        should_execute = True

    # If we need to wait more, skip to the next iteration
    if wait_more:
        time.sleep(0.01)
        continue

    # Execute the macro if conditions are met
    if should_execute and current_pressed_keys in macros:
        # Only execute if cooldown period has passed
        if current_time - last_macro_time &gt;= MACRO_COOLDOWN_MS:
            print(f"MACRO: {macros[current_pressed_keys]}")
            keyboard_layout.write(macros[current_pressed_keys])
            last_macro_time = current_time
            last_executed_combo = current_pressed_keys

    time.sleep(0.01)
```

# "Mother of all Demos" USB Keyset

## Assembly

## Wire Connections

Use the white colored spool of wire to create a set of five wires that are approximately 4" inches (101mm) long.

Use the blue colored spool of wire to create four wires that are approximately 1" inch (25mm) long.

Cut a single blue wire to 4" inches (101mm) in length.

Use wire strippers to remove a bit of insulation from the tips of each wire then apply a bit of solder to tin them.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/121/medium640/3d_printing_wires-cut.jpg?1748289861)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/122/medium640/3d_printing_wires-tinned.jpg?1748289881)

## Install Key Switches&nbsp;

Snap the five CHOC key switches into the 3D printed key plate oriented as shown here.

Ensure all of the keys are installed in the same orientation.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/123/medium640/3d_printing_keyplate-sw.jpg?1748289902)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/124/medium640/3d_printing_keyplate-sw-install.jpg?1748289929)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/125/medium640/3d_printing_keyplate-sw-installed.jpg?1748289930)

## Install Key Sockets

Remove the protective cover from the cut tape reel of key sockets.

Insert the key sockets into CHOC key switches being very careful not to bend the pins.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/183/medium640/3d_printing_key-sockets.jpg?1748367050)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/184/medium640/3d_printing_key-sockets-installing.jpg?1748367159)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/185/medium640/3d_printing_key-sockets-installed.jpg?1748367170)

## Solder Wires to Sockets

Use the short blue wires to connect ground pins together on the switches.

Use the white wires to connect to the signal pins on the switches.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/126/medium640/3d_printing_sw-wires-installed.jpg?1748289951)

## Solder Wires to QT Py

Connect the signal wires from the switches to the GPIO pins on the QT Py RP2040.

Solder the long blue wire to **GND** on the QT Py.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/131/medium640/3d_printing_qtpy-wiring.jpg?1748290213)

## Install QT Py to Holder

Snap fit the QT Py into the 3D printed holder.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/132/medium640/3d_printing_qtpy-holder.jpg?1748290236)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/133/medium640/3d_printing_qtpy-holder-install.jpg?1748290248)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/134/medium640/3d_printing_qtpy-holder-installed.jpg?1748290281)

## Secure QT Py Holder

Place the QT Py holder onto the 3D printed base with the mounting holes lined up.

Use two M3 x 6mm long machine screws to secure the QT Py holder to the 3D printed base.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/135/medium640/3d_printing_qtpy-case-fit.jpg?1748290320)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/136/medium640/3d_printing_qtpy-case-secure.jpg?1748290337)

## Install Hinge Rest

Place the hinge rest into the designated spot in the 3D printed base with the three mounting holes lined up.

Use three M3 x 6mm long machine screws to secure the hinge rest to the base.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/137/medium640/3d_printing_rest-case-install.jpg?1748290357)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/138/medium640/3d_printing_rest-case-secure.jpg?1748290370)

## Install Key Dowel

Insert the dowel pin through the holes of the five keys.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/127/medium640/3d_printing_dowel-keys.jpg?1748289990)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/128/medium640/3d_printing_dowel-keys-install.jpg?1748290004)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/129/medium640/3d_printing_dowel-keys-intalled.jpg?1748290166)

## Install Keyset

Place the dowel pin onto the hinge rest with each key fitting into their designated spaces.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/139/medium640/3d_printing_keys-rest-install.jpg?1748290392)

## Secure Key Plate

Orient the key plate and place it over the mounting tabs with the mounting holes lined up.

Insert and fasten two M3 x 6mm long machine screws to secure the key plate to the 3D printed base.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/140/medium640/3d_printing_keyplate-install.jpg?1748290409)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/141/medium640/3d_printing_keyplate-secure.jpg?1748290420)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/142/medium640/3d_printing_keyplate-case-secured.jpg?1748290449)

## Install Keys

Press the five 3D printed keys to test the actuation of each CHOC key. Rearrange the wires if they are preventing the keys from being actuated properly.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/186/medium640thumb/3d_printing_key-press.jpg?1748370826)

## Install Case Cover

Orient the cover with the base so the nubs line up with the mounting holes.

Firmly press the cover into the sides of the base so the nubs snap into the mounting holes.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/143/medium640/3d_printing_case-cover-installing.jpg?1748290466)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/144/medium640/3d_printing_case-cover-installed.jpg?1748290495)

## Install Rubber Feet

Place the four rubber feet onto the corners on the bottom of the 3D printed base.

![](https://cdn-learn.adafruit.com/assets/assets/000/137/145/medium640/3d_printing_bumpers.jpg?1748290521)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/146/medium640/3d_printing_bumpers-installed.jpg?1748290775)

## USB Connection

Plug in the USB cable into the QT Py and then into a USB port on a computer, laptop or mobile device.

You're ready to start typing!

![](https://cdn-learn.adafruit.com/assets/assets/000/137/189/medium640/3d_printing_usb-connect.jpg?1748373376)

![](https://cdn-learn.adafruit.com/assets/assets/000/137/190/medium640/3d_printing_usb-connected.jpg?1748373389)


## Featured Products

### Adafruit QT Py RP2040

[Adafruit QT Py RP2040](https://www.adafruit.com/product/4900)
What a cutie pie! Or is it... a QT Py?&nbsp;This diminutive dev board comes with one of our new favorite chip, the RP2040. It's been made famous in the new [Raspberry Pi Pico](https://www.adafruit.com/pico) _and_ our [Feather...](http://www.adafruit.com/product/4884)

In Stock
[Buy Now](https://www.adafruit.com/product/4900)
[Related Guides to the Product](https://learn.adafruit.com/products/4900/guides)
### Kailh CHOC Low Profile White Clicky Key Switches

[Kailh CHOC Low Profile White Clicky Key Switches](https://www.adafruit.com/product/5114)
For crafting your very own custom keyboard, these **&nbsp;Kailh Choc Low Profile Clicky White&nbsp;mechanical key switches** &nbsp;are super slim, with ultra-low profile compared to MX compatible switches!

Please note these are&nbsp; **NOT MX...**

In Stock
[Buy Now](https://www.adafruit.com/product/5114)
[Related Guides to the Product](https://learn.adafruit.com/products/5114/guides)
### Switch Sockets for Kailh CHOC Compatible Keys - 10 Pack

[Switch Sockets for Kailh CHOC Compatible Keys - 10 Pack](https://www.adafruit.com/product/5118)
Back in _my_ day, if you wanted to make a mechanical keyboard, you had to solder in expensive key switches onto your PCB - and woe to the person who decided they wanted to change their linear keys instead of clicky ones! Bah humbug, kids these days have no idea, what with their...

In Stock
[Buy Now](https://www.adafruit.com/product/5118)
[Related Guides to the Product](https://learn.adafruit.com/products/5118/guides)
### Silicone Cover Stranded-Core Wire - 50ft 30AWG White

[Silicone Cover Stranded-Core Wire - 50ft 30AWG White](https://www.adafruit.com/product/3169)
//www.youtube.com/embed/W85OajXuDRA
?start=10

Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3169)
[Related Guides to the Product](https://learn.adafruit.com/products/3169/guides)
### Silicone Cover Stranded-Core Wire - 50ft 30AWG Blue

[Silicone Cover Stranded-Core Wire - 50ft 30AWG Blue](https://www.adafruit.com/product/3166)
Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness has to...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3166)
[Related Guides to the Product](https://learn.adafruit.com/products/3166/guides)
### Blue USB Type C to USB A Cable with 540 Degree Rotating End

[Blue USB Type C to USB A Cable with 540 Degree Rotating End](https://www.adafruit.com/product/6278)
Some days we're feeling extra fancy here at the 'fruit warehouse, and we have a big soft spot for colorful&nbsp;cables that make our projects look like Transformers. Like, peep [this fully reversible pink/purple Blinka-inspired cable](https://www.adafruit.com/product/4111)....

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

## Related Guides

- [Adafruit QT Py RP2040](https://learn.adafruit.com/adafruit-qt-py-2040.md)
- [NeoKey Emoji Keyboard](https://learn.adafruit.com/neokey-emoji-keyboard.md)
- [LED Noodle Holiday Tree](https://learn.adafruit.com/led-noodle-tree.md)
- [NeXT Bus Mouse to USB HID with CircuitPython](https://learn.adafruit.com/next-bus-mouse-to-usb-hid-with-circuitpython.md)
- [MIDI Breath Controller](https://learn.adafruit.com/midi-breath-controller.md)
- [PowerWash Simulator Nozzle Controller](https://learn.adafruit.com/powerwash-simulator-nozzle-controller.md)
- [Kitty Toe Bean Keypad with Color TFT](https://learn.adafruit.com/kitty-toe-bean-paw-keypad-color-tct.md)
- [Audio Synthesis with CircuitPython synthio](https://learn.adafruit.com/audio-synthesis-with-circuitpython-synthio.md)
- [Tandy 1000 Keyboard to USB with CircuitPython](https://learn.adafruit.com/tandy-1000-keyboard-to-usb-with-circuitpython.md)
- [SNES Mouse to USB HID with CircuitPython](https://learn.adafruit.com/snes-mouse-to-usb-hid-with-circuitpython.md)
- [Split Ortho Keyboard with TCA8418 Matrix Expanders](https://learn.adafruit.com/split-ortho-keyboard.md)
- [Animated Edge Lit Acrylic NeoPixel Lamp](https://learn.adafruit.com/acrylic-neopixel-lamp.md)
- [3D Scans for Low Poly Statues](https://learn.adafruit.com/low-poly-3d-scans-for-3d-printing.md)
- [USB Rotary Media Dial](https://learn.adafruit.com/usb-rotary-media-dial.md)
- [PlayStation Spinner Controller](https://learn.adafruit.com/playstation-spinner-controller.md)
- [Tyrell Desktop Synthesizer](https://learn.adafruit.com/tyrell-desktop-synthesizer.md)
