USB Circuit Python Controllers

In this guide, we'll build a USB foot switch controller. This can be used as an addition to your keyboard or as a way to free up your hands. I'm using it to do overhead photography so I can trigger the camera and use my hands at the same time.

It’s powered by Adafruit’s Trinket M0 which is a tiny microcontroller that can run CircuitPython. Just connect over USB and load it as a flash drive. All of the code and libraries are accessible on the drive so you can make small edits and iterate quickly. The Adafruit HID library simulates USB devices so it can send keypress just like a mouse and keyboard.

Prerequisite Guides

If your new to electronics and soldering, I suggest walking through the following guides to get the basics. The Adafruit Excellent guide to soldering will walk you through process of learning how to use a soldering iron to make solid electrical connections.

Electronic Components

The Trinket M0 and Foot Switch are the main electronic components used in this project.

1 x Trinket M0
Adafruit Trinket M0 with CircuitPython
1 x Micro Switch
Premium Zippy 3-Terminal

Hardware and Supplies

Just a few screws, wires and some handy supplies. 

4 x M2.5 x .45 x 5mm
Metric Flat Head Phillips Machine Screws
2 x #4-40 x 5/8"
Imperial Flat Head Phillips Machine Screws
1 x 26AWG Wire
Silicone Cover Stranded-Core Wire - 25ft
1 x Solder Wire
Solder Spool - 1/4 lb SAC305 RoHS lead-free / 0.031" rosin-core - 0.25 lb / 100 g
1 x Heat Shrink Tubing
Multi-Colored Heat Shrink Pack - 3/32" + 1/8" + 3/16" Diameters

Cool Tools!

These help make the project a smooth building experience. You don't need them all of them, but I recommend them.

1 x Wire Strippers
Hakko Professsional Quality 20-30 AWG Wire Strippers - CSP-30-1
1 x Wire Cutters
Flush diagonal cutters - CHP170
1 x Soldering Iron
Adjustable 30W 110V soldering iron - XY-258 110V
1 x Panavise
Panavise Jr. - PV-201
1 x Helping Third Hands
Helping Third Hand Magnifier W/Magnifying Glass Tool - MZ101
1 x Ultimaker 2+
3D Printer

Circuit Diagram

This provides a visual reference for wiring of the components. They aren't true to scale, just meant to be used as reference. Generic micro switches follow a standard pin out with visible markings on the body of the switch. Here's each label markings:

  • (C1) – "common ground".
  • (NO2) – "normally open".
  • (NC3) – "normally closed".

Wired Connections

Just two wired connections are needed for this circuit, which makes it very easy!

  • (C 1) Common from micro switch to Ground on Trinket M0
  • NO 2) Normally open from micro switch to #0 on on Trinket M0
As we continue to develop CircuitPython and create new releases, we will stop supporting older releases. If you are running an older version of CircuitPython, you need to update. Click the button below to download the latest!

CircuitPython is a derivative of MicroPython designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. The trinket M0 is the second board that comes pre-loaded with CircuitPython. Simply copy and edit files on the CIRCUITPY drive to iterate.

Your Trinket M0 already comes with CircuitPython but maybe there's a new version, or you overwrote your Trinket M0 with Arduino code! In that case, see the below for how to reinstall or update CircuitPython. Otherwise you can skip this and go straight to the next page

If you've already plugged your board into your computer, you should see a drive called CIRCUITPY. The drive will contain a few files. If you want to make a 'backup' of the current firmware on the device, drag-off and save the CURRENT.UF2 file. Other that that you can ignore the index.htm and info_uf2.txt files. They cannot be deleted and are only for informational purposes.

If you have already plugged in your board, start by ejecting or "safely remove" the CIRCUITPY drive. This is a good practice to get into. Always eject before unplugging or resetting your board!

Set up CircuitPython Quick Start!

Follow this quick step-by-step for super-fast Python power :)

Click the link above and download the latest UF2 file.

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

Plug your Trinket 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 small Reset button next to the Trinket M0 name printed 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. Note: The little LED below the USB connector will be red - this is ok!

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

You will see a new disk drive appear called TRINKETBOOT.




Drag the adafruit_circuitpython_etc.uf2 file to TRINKETBOOT

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

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

Further Information

For more detailed info on installing CircuitPython, check out Installing CircuitPython.

Trinket Default Zip Install

Trinket M0 is limited on space. As you begin working on projects, you may run out of space. Operating systems can create hidden files that take up space. To prevent these files from being added to your Trinket, we suggest installing the Trinket Default Zip.

Click the link above to download the default zip.


Download and save it to your desktop, or wherever is handy!

If you haven't already, plug your Trinket into your computer using a known-good USB cable.


Make sure your CIRCUITPY drive appears.

Once downloaded, double-click the file to extract the contents.

Double click newly extracted folder to open it.

To load the files that will keep the system from adding hidden files to your drive, highlight these three files:





Drag them to your CIRCUITPY drive. If it asks to replace any, say yes!

If you'd like to reset your Trinket to the same files it shipped with, you can do that with these files. If you changed, and you want to keep your changes, back up first.

Highlight all the files in this folder. Drag them all to your CIRCUITPY drive.

If it asks to replace anything, say yes.

Download Project Bundle

Once you've installed the latest version of CircuitPython onto your board, you'll need to grab the code, libraries and any assets included with the project.

Click the download project bundle button below to get the code, libraries and assets all in one!

# SPDX-FileCopyrightText: 2022 Ruiz Bros for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import digitalio
import board
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

# The button pins we'll use, each will have an internal pullup
buttonpins = [board.D0]

# The keycode sent for each button, will be paired with a control key
buttonkeys = [
    Keycode.SPACE # Space

keyboard = Keyboard(usb_hid.devices)

# our array of button objects
buttons = []

# make all pin objects, make them inputs w/pullups
for pin in buttonpins:
    button = digitalio.DigitalInOut(pin)
    button.direction = digitalio.Direction.INPUT
    button.pull = digitalio.Pull.UP

print("Waiting for button presses")

while True:
    # check each button
    for button in buttons:
        if not button.value:  # pressed?
            i = buttons.index(button)

            print("Button #%d Pressed" % i)

            while not button.value:
                pass  # wait for it to be released!
            # type the keycode!
            k = buttonkeys[i]  # get the corresp. keycode

Upload Code, Libraries and Assets

Unzip the project bundle and upload the files to the CIRCUITPY drive.

Your CIRCUITPY drive should look like this after you've uploaded the code, libraries and assets.

List of USB HID Keycodes

The long list of available keyboard characters are listed in the webpage linked below. Most of the characters are for USA keyboard only. Function keys and modifiers can be used but only some special characters are not supported.

What If I Don't Have A 3D Printer?

Not to worry! You can use a 3D printing service such as 3DHubs or MakeXYZ to have a local 3D printer operator 3D print and ship you parts to you. This is a great way to get your parts 3D printed by local makers. You could also try checking out your local Library or search for a Maker Space.

Slice Settings

These parts have been tested and 3D printed on an Ultimaker 2+ and 3 using PLA filament. The parts were sliced using CURA 3.x with the following slice settings.

  • 220C extruder temp
  • 65c bed temp
  • 0.2 layer height
  • 0.38 line width
  • 2 Wall Line Count – 0.4 nozzle
  • 20% infill
  • 70mm/s print speed
3D printed support material is required for the top cover, turn it on in your slicing software.

Support Material / Overhangs

The top cover requires support material. The overhang angles on the support material can be increased to 60 degrees which will use less material and reduce the printing time. Features on the sides of the top cover part are 60 degrees so they don't need any supports.

Design Source Files

The spool holder carousel assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, SAT and more.

3D Printed Parts

All of the parts are 3D printed with FDM type 3D printers using various colored filaments. All of the parts are separated into pieces to make 3D printing easier. Assembly is pretty easy and straight forward. Use the links below to download the STLs files.

Design Source Files

The enclosure assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, SAT and more. Electronic components like the board, displays, connectors and more can be downloaded from our Fusion 360 CAD parts github repo.

Wires for Micro Switch

We'll need two pieces of wires to connect the micro switch to the Adafruit Trinket M0. These can be about 10 cm in length. I'm using 30AWG silicone covered wires in this project.

Wire Strippers

In order to connect the wires to the electrical leads and pins on the components, we'll need to strip the ends to expose the bare metal wire. Use wire strippers to remove a bit of insulation from the tips.

Tinning Wires

To prevent the strands of wires from fraying when soldering, we can add a small amount of solder to fuse them. I'm used third helping hands tools to hold the wires in place which makes soldering more conformable.

Tinning Micro Switch

We can do the same process for the leads on the micro switch. Since we'll only be using two of the leads, we only need to tin the NO3(Normally Open) and C1(Common) labeled leads.

Wiring Micro Switch

Now we can attach the wires from the Trinket M0 to the micro switch by heating up the leads and placing the wires  down onto them. I used a Panavise Jr to hold the micro switch steady while soldering.

Wired Micro Switch

Now we have a wired micro switch, nice work! Double check your solder joints and make sure the wires a fully connected and for any shorts.

Trinket Tinning

We'll need to connect the wires from the micro switch to the pins on the Trinket M0. I like to add a bit of solder to the pins and then insert the wires.

Wiring Trinket M0

Solder the C1(common) wire to the ground (G) labeled pin and NO3(normally open) wire to pin number 0. 

Wired Trinket M0 and Micro Switch

Now our micro switch is connected to the Trinket M0, high five! Now we can start putting our circuit into the 3D printed enclosure. Before we get started, let's double check our work and make sure we have solid connections.

Hardware for Micro Switch

First up we'll need to get that micro switch secured to the mounting bracket. We have two long screws that will be inserted through the body of the switch and into the holes of the mounting bracket.

Secure Micro Switch to Bracket

Grab the two parts and line up the holes so ones on the micro switch are matching with the bracket. The actuator of the switch should face away from the 'L' shape of the bracket.

Micro Switch Bracket

Here's a better view of the orientation. Note how the C1(common) lead is parallel with surface of the 'L' bracket . 

Installing Bracket

Next we'll work on mounting the bracket to the base part. We'll need two short M2.5 machine screws to secure the parts together.

Installed Bracket

Place the bracket over the center of the base with the micro switch facing away from the circular post. Line up the mounting holes and insert machine screws. Fasten the screws until they're fully tightened with the two parts jointed and flush.

Tap Mounting Holes

We'll need to secure the Trinket M0 to the base with machine screws. It's easier if the screws are pre-fastened into the Trinket first. You may need to tap the mounting holes with the screws.

Secure Trinket M0

Place the Trinket M0 over the four standoffs on the base with the USB port facing the cut opening. Line up the holes on and fasten the machine secures until fully tightened.

Install Top Cover

All that's left todo now is to install the top cover. Grab the parts and line up the hinges with each other, you'll notice the top has extrusion while the base has dimpled features. Firmly press the parts together until the hinges click into place. They should join together nicely. 

USB Port

Squeeze the top and base together to test out the micro switch. The hinges should be frictionless. The USB port is accessible through the open and the top accommodates for microUSB cables.

This guide was first published on Mar 21, 2018. It was last updated on Mar 21, 2018.