Leverless Controller
2026-07-28 | By Adafruit Industries
License: See Original Project Microcontrollers 3D Printing Qwiic Raspberry Pi MCU STEMMA QT Py
Courtesy of Adafruit
Guide by John Park
Overview
So called "leverless" controllers are popular among fighting game enthusiasts for their speed and accuracy compared to traditional lever-style joysticks. You can build your own with the Adafruit QT Py RP2040 and GP2040-CE firmware.
Mini arcade buttons are mounted to a 3D printed case (or BYOB(ox)) to make for a playable, ergonomic design. And by wiring the buttons to the QT Py Terminal Block BFF using quick-connect cables, you can keep the build manageable and nearly solder-free -- the only soldering required is the QT Py header pins.
Since the GP2040-CE firmware can be configured from a web browser, this project is essentially code free -- just drag and drop the UF2 and you're ready to play.
Parts
3D Print the Case
3MF files for 3D printing are oriented and ready to print on FDM machines using PLA filament. Original design source files may be downloaded using the links below.
Slice with settings for PLA material
The parts were sliced using BambuStudio using the slice settings below.
PLA filament 220c extruder
0.2 layer height
15% grid infill
200mm/s print speed
Circuit Diagram
The wiring is straightforward since you'll be using one GPIO pin on the QT Py per button. The diagram above shows the wires connected to the QT Py for clarity, but you'll be using the Terminal Block BFF for the real thing.
Software
Install Firmware and Customize Settings
GP2040-CE is an open-source gamepad firmware that's compatible with RetroPie, Mac/PC/Linux, PlayStation 3/4/5, Nintendo Switch/Switch 2, Xbox 360/One/Series, mini consoles, and others. It runs on a number of microcontrollers which use Raspberry Pi RP2040/RP2305 chips, such as The QT Py, Pico, KB2040 Kee Boar, and more.
First, you'll flash the QT Py RP2040 with the drag-and-drop .uf2 file and then customize settings within a web editor.
Download Firmware
There isn't an official build for the QT Py RP2040 yes, but you can use this pre-release version by clicking the GP2040-CE_0.7.12_AdafruitQTPyRP2040.uf2 file.
This will save a file named GP2040-CE_0.7.12_AdafruitQTPyRP2040.uf2 to your download location.
Firmware Installation
This page gives detailed instructions on installation, but the basic steps are:
Plug the QT Py RP2040 into your computer with a known good data and power USB cable
While holding the BOOTSEL button down, press and release the RESET button this puts the board into BOOTSEL/USB drive mode
A new removable drive named RPI-RP2 will appear on your computer
Drag-and-drop the GP2040-CE_0.7.12_AdafruitQTPyRP2040.uf2 (or later) firmware .uf2 file onto the RPI-RP2 drive and wait for it to copy the file and reboot itself
Pin Mapping
The default pin mapping in GP2040-CE for the QT Py RP2040 is shown here.
Button Test
This is a great time to test the controller to make sure basic button presses are working.
Plug the QT Py RP2040 into your computer with a known good USB-C data and power cable. Head to this gamepad tester in your browser to see the button presses.
You can now use a jumper wire to short any mapped GPIO pin to ground -- those button presses will register on the controller tester.
Build the Controller
Solder the QT Py Headers
Solder the male header pins on to the QT Py RP2040 as shown here.
You can optionally use short headers for a slightly lower profile, but the default pins included with the QT Py work just fine.
See the guide How To Solder Headers for how-to and tips.
Mount the Terminal Block BFF to the Case
Mount the Terminal Block BFF with the larger battery JST connector facing up as shown. Screw the M2.5 x 10mm screws in from the top into standoffs or nuts on the inside of the case.
Use a small, slotted screwdriver to open all of the terminal positions by unscrewing them counterclockwise in prep for wiring later.
Add QT Py
Press the QT Py into the terminal block BFF with the USB port facing up as shown.
Arcade Buttons
Insert an arcade button into to the case from the top and then screw on the retaining nut.
Repeat this for the remaining buttons.
Cable Prep
Prepare the cables by first cutting off the white plastic JST connectors (be sure to keep the terminal connector ends intact), thereby separating each pair into two individual cables.
Then, strip about 4mm of insulation from the bare end of each cable.
Twist the wire strands so they don't fray and potentially short against neighboring pins when inserted into the terminal block later.
Repeat these steps for all remaining wires for a total of 22 (that's two wires per button).
Connect Button GPIO
Following the diagram carefully, wire one terminal of each button to it's associated pin on the QT Py via the Terminal Block BFF.
First, press the cable's crimp connector onto one of the button's two switch terminals (these are the two at the top of the switch, not the one's at the bottom with the arrows and +/- signs, those are for the LEDs, which we won't be using).
Then, run that wire through the case and to the terminal block pin for that button. Screw the terminal screw down tight.
Repeat for remaining 10 buttons.
Ground Run
Cut a 20cm length of 22AWG stranded wire (this spool set is handy to have around), then strip about 4mm of insulation from each end.
Feed this wire through the case and into the GND position on the QT Py/BFF. Screw it in place.
Then, inside the case, connect the other end of this wire to any position on the 3-wire block connector.
Chain together all of the block connectors using 6cm lengths of stranded wire with 4mm of insulation stripped from each end.
Cover Lots of Ground Fast
Now you can press the remaining 11 crimp connector cables onto the second switch position of each arcade button (again, avoiding the lower two LED legs).
For each button's ground wire, connect the free end to any open position on a block connector.
Case Closed
Press fit the bottom onto the case as shown.
Configure and Use the Controller
Web Configurator
Press and hold the START (S2) button (the one wired to QT Py RP2040 pin SCK (GP06) ) and then press and release the RESET button. This puts the QT Py into configuration mode. After a moment, you can release the START button.
This causes the QT Py's GP2040-CE firmware to launch a web server you can access from your computer's web browser by visiting http://192.168.7.1
GPIO Pin Mapping
Click Configuration > GPIO Pin Mapping to make any changes to the button configuration.
If you do make changes, press Save to commit them on the QT Py's flash memory.
Hotkeys
Click Settings > Hotkey Settings. Here you'll see the default Fn + S2 = S1 Button that I included in the QT Py RP2040 configuration. This is what allows the BOOT button (on QT Py) modifier + the Start button to act as the Select button.
If you want, you can add as many other hotkey combos as you like. For example, here I've added Fn + Up = Home Button in order to press the Home/PS/Xbox button.
Remember to hit Save when done.
Input Modes
You can use the leverless controller on a variety of consoles and systems. By default, it will present itself as an XInput controller / Xbox 360 controller.
Click Settings > Boot Input Modes to see the assigned input modes that you can pick during startup. Simply hold down the assigned button while plugging in -- e.g., hold B1 while plugging in to Nintendo Switch, B2 for Xinput, B3 for PlayStation 3, or B4 for PlayStation 4.
Reboot
When you're done changing settings, press the Reboot button in the upper right corner. You'll see a popup that lets you choose the mode into which you reboot: USB BOOTSEL, Web-config (the same mode you're already in) or Controller so you can play!
Fight!
Now, plug your leverless controller into your computer or console and serve up a whooping!
Remember, if you need to use the Select button press Fn (BOOT on the QT PY) + START.

