OpenPuck: a $8 NRF52840 Pro Micro that replaces the Steam Controller 2 Puck
Opensource firmware for NRF52840 Pro Micro that copycats the Steam Controller 2 Puck and adds an Xbox and Switch mode
At a glance
- What is it?
- OpenPuck is firmware for an $8 NRF52840 Pro Micro that emulates the Steam Controller 2 Puck and adds Xbox, Switch, PS3, DualSense and DirectInput modes. It is young, LLM-heavy code, and the docs are thinner than the feature list.
- Who is it for?
- Adopt OpenPuck if you already own a Steam Controller 2, cannot buy a spare puck, and want the controller to work in Xbox, Switch, PS3 or Original Xbox mode without Steam running. Do not adopt it if you need a supported accessory with a warranty, if you depend on rumble in DirectInput mode, or if you cannot read C++ when something breaks.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 17, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem OpenPuck solves, and who it is actually for
The Steam Controller 2 ships with a puck that handles wireless communication with the host. According to the README, the puck can pair four controllers at once and runs at a fraction of the controller's Bluetooth latency. It is also not sold separately, and the README predicts it never will be. That leaves two gaps: no replacement if the puck dies or is lost, and no way to avoid Steam Input. The README is blunt about the second one, calling Steam Input a requirement rather than a nicety, and points at Game Pass as the case where a Steam-only controller becomes awkward.
OpenPuck targets the person who already has the controller and wants it to behave like a normal gamepad elsewhere. The README frames the audience through the hardware: a Pro Micro NRF52840, listed at $8 on Amazon and possibly cheaper elsewhere, with a radio close to the one in the controller and puck. If you do not own a Steam Controller 2, this project has nothing for you yet. There is no host-side driver to install and no desktop application; the firmware is the product.
How the firmware turns one radio into ten controller identities
The board runs an Arduino sketch. Once uploaded, it emulates the puck over USB to Steam by default, so the controller pairs normally. The README notes one caveat: lizard mode, the fallback used when Steam is off, may not be 1:1 with the original.
Mode switching happens on the controller itself. Hold all four back buttons and press a face button: A for Steam, B for lizard mode even when Steam is open, X for Xbox 360, Y for Switch Pro with gyro and haptics. The WebUSB panel covers the rest, including Hori Pad, DualSense with gyro and trackpad, DS4/HIDGYRO, PS3 DualShock 3, Original Xbox Controller S, DirectInput and SInput. The README states that Switch, PS3 and Original Xbox modes have been verified on real consoles, and that Switch and PS4/5 modes have gyro wired in.
Two modes deserve attention because they are not impersonations. DirectInput presents the controller as two joysticks across two HID collections on one USB interface, because DirectInput caps a device at eight axes and the controller has more live analog inputs than XInput can carry. Trackpad axes latch in that mode, holding the last touched position until you click the pad to re-centre. SInput speaks Hand Held Legend's open gamepad protocol, which SDL3 and Steam Input bind with a dedicated driver, and reports both trackpads, both triggers, gyro, accelerometer and battery level at once. The README says SInput needs SDL 3.4+ or a current Steam client, and that older hosts fall back to a plain HID gamepad.
Building and flashing OpenPuck: what the Makefile tells you
The README does not walk through installation. The repository does: the Makefile documents the two TinyUSB config values the firmware needs, and points at OpenPuck.ino and docs/BUILD_AND_DEPLOY.md for the build and deploy path. Those are the files to read before you touch a board.
The Makefile's comments name the two overrides explicitly. The Adafruit nRF52 core defaults are too small for what OpenPuck does:
CFG_TUD_HID=6
CFG_TUD_TASK_QUEUE_SZ=64
CFG_TUD_VENDOR_TX_BUFSIZE=256The first gives you four HID interfaces for the puck slots plus one for mouse and one for WebUSB. The second deepens the usbd event queue; the comment states the default of 16 deadlocks the loop task under comms load and triggers a watchdog reset. The third exists because the WebUSB status blob is roughly 118 bytes and the core default of 64 cannot hold it whole.
Formatting is pinned to clang-format 18, and the Makefile explains why: output differs between versions, so a mismatch would make CI reject locally formatted code. The target resolves the binary in order, preferring clang-format-18, then the Homebrew llvm@18 keg, then a bare clang-format. You can override it:
make format CLANG_FORMAT=/path/to/clang-formatGenerated headers such as git_version.h are gitignored and excluded from formatting. If you are porting this to a different NRF52840 board, the three TinyUSB values are the first thing to check against your core's defaults.
Where OpenPuck falls short, and where it is the wrong tool
The README carries a warning that every part of the project heavily used LLMs. That is not a moral judgement, it is a maintenance signal. Code written that way tends to work on the paths the author exercised and fail on the ones nobody tried, and the README's own hedges support that reading: lizard mode might not be 1:1, the right trackpad in Xbox mode acts as a mouse but only on Android and SteamOS.
DirectInput mode has a hard boundary. The README states it is input-only, because DirectInput force feedback is a separate HID class, so rumble is not wired up there. If you are a flight simmer who wants force feedback, this mode is not the one. DirectInput is also a Windows API; on Linux and SteamOS the README points you at SInput instead, which means the mode you want depends on the OS you run.
SInput has a version floor. It needs an SDL build that ships the SInput driver, which the README puts at SDL 3.4+ or a current Steam client. On an older host you get a plain HID gamepad and lose the simultaneous trackpad, gyro and battery reporting that makes the mode worth choosing.
Rumble tuning is deliberately partial. The WebUSB panel can reshape rumble in the translated modes, with Strength defaulting to 200% to match previous firmware, and Style options named mono, heavy, light, punchy and soft. Steam mode relays Steam's haptics untouched, so none of those settings apply there. If you switch modes expecting the same rumble character, you will not get it.
OpenPuck against a plain USB adapter or a Bluetooth pairing
The obvious alternative is using the controller's own Bluetooth mode. The README answers that directly: Bluetooth has over twice the latency of the puck, which is why the project exists at all. If you only play turn-based games, that gap may not matter and you can skip the hardware entirely.
The second alternative is a commercial USB adapter that presents the Steam Controller as an XInput device. That approach keeps the puck and translates on the host. OpenPuck replaces the puck instead, so the controller talks to a radio you own, and the mode switching happens on the board rather than in a driver. The practical difference shows up in the mode list: OpenPuck enumerates as a PS3 DualShock 3 on a real PS3 and as an Original Xbox Controller S on a real Original Xbox, which a host-side XInput translator cannot do because those consoles predate XInput and take the controller directly.
The third alternative is Steam Input itself. If every game you play is on Steam and you are happy with the default mapping, OpenPuck adds a board, a build step and a mode you have to remember. The README treats Steam Input as a requirement, not a feature, which is the whole reason the project exists.
Licence, maintenance and the cost of keeping a board in sync
OpenPuck is AGPL-3.0. If you fork it and distribute a modified firmware, the licence's network and distribution terms apply to your version. That matters more here than for a desktop utility, because people flash firmware onto hardware they hand to other people. This is not legal advice; read the LICENSE file in the repository.
The repository is not archived, and the last push was on 2026-09-14. Releases are frequent and small: 0.9.51 on 2026-08-24, 0.9.31 on 2026-07-10, 0.9.28 on 2026-07-09. The version numbers suggest the project is still short of 1.0, and the release notes are the place to look before flashing, because the README does not document rollback. If a new build breaks a mode, the README does not tell you how to go back to the previous one.
Upgrade cost is low in time and high in attention. Flashing is a build step, not a package update, and the TinyUSB overrides in the Makefile mean a core upgrade can change build behaviour. The repository also carries ReversePuck, ReversePuckFirmware, puck_sniffer and pairtui directories, which suggests reverse-engineering and pairing tools sit alongside the firmware and may need their own attention.
Editorial conclusion
Adopt OpenPuck if you already own a Steam Controller 2, cannot buy a spare puck, and want the controller to work in Xbox, Switch, PS3 or Original Xbox mode without Steam running. Do not adopt it if you need a supported accessory with a warranty, if you depend on rumble in DirectInput mode, or if you cannot read C++ when something breaks. Before ordering a board, verify which Pro Micro NRF52840 variant you have, confirm the WebUSB panel enumerates in your browser, and check that your target console mode is one the README says has been verified on real hardware.
Frequently asked questions
What is OpenPuck?
OpenPuck is open source firmware for an NRF52840 Pro Micro that emulates the Steam Controller 2 Puck. It also adds Xbox, Original Xbox, Switch, PS3/4/5, DirectInput and SInput modes, with an independent lizard mode for when Steam is not running.
What is an open puck Steam Controller?
It is a replacement for the Steam Controller 2's wireless puck, built on a Pro Micro NRF52840 board that the README lists at $8. Once the sketch is uploaded, it emulates the puck over USB to Steam and lets the controller pair normally.
Is the Steam Controller discontinued?
The README does not discuss the original Steam Controller's availability. It describes the Steam Controller 2, released in 2026, and its puck, which the README says is not sold separately and predicts never will be.
Can I still buy a Steam Controller?
The README does not cover buying the controller. It covers buying the puck, stating that it is not available separately from the controller, which is one of the two problems the project was written to solve.
Is the Steam Controller 2 out yet?
Yes. The README states the Steam Controller 2 was released in 2026 and describes it as having trackpads, gyro and four back buttons. OpenPuck exists because the controller's puck is not sold on its own.
Community notes