Comments
Figures ▾
Tables ▾

Open-Source Light-Gun Firmware · Volume 3

Hardware as OpenFIRE Defines It — Boards, Pin Presets, the Camera, the Emitters and the Hardware Guide's Circuits

Every supported board and its default pin map quoted from the project's own files, the DFRobot camera and the Wii-sensor alternative, the two emitter layouts, and the solenoid, rumble and button wiring exactly as OpenFIRE's Hardware Guide v1.3 draws it

3.1 Whose definition this is

This volume records what the OpenFIRE project itself says about hardware: which boards it supports, which pin does what by default, which camera and emitters it expects, and how its own Hardware Guide wires the solenoid and rumble motor. Four documents define that, and each is quoted with its name:

  • BOARDS.md in the firmware repository — the default pin maps as ASCII board drawings.
  • OpenFIREshared.h in the OpenFIRE-Boards repository — the same maps as the code that both the firmware and the App actually load (boardsPresetsMap), at the commit firmware v6.2 pins.
  • The firmware README.md — the parts list.
  • The OpenFIRE Hardware Guide, version 1.3 — a 15-page illustrated wiring guide published on openfirelightgun.org; the PDF is dated 17 October 2026, the day before this was written. All of its drawings use a Raspberry Pi Pico.

Two siblings own the design work this volume deliberately does not do. Reference Electronics owns the build’s own circuit — the driver stages, the camera interface, the emitter bar and the schematic for Altium — and treats what follows as one input. Solenoid Recoil and Power Supplies own the solenoid and its supply. Where the project’s drawings raise an engineering question, it is flagged here and answered there.

3.2 Supported boards

Figure 1 — The six RP2040 and RP2350 boards with full default layouts in OpenFIRE v6.2, drawn from the board vectors the OpenFIRE App uses in its board previewer: Raspberry Pi Pico, Pico 2, Adafruit ItsyBitsy…
Figure 1 — The six RP2040 and RP2350 boards with full default layouts in OpenFIRE v6.2, drawn from the board vectors the OpenFIRE App uses in its board previewer: Raspberry Pi Pico, Pico 2, Adafruit ItsyBitsy RP2040, Adafruit KB2040, Arduino Nano RP2040 Connect and Waveshare RP2040-Zero. The drawings are not to a common scale. Drawings: TeamOpenFIRE, OpenFIRE-Boards repository (boardPics), assembled for this dive.

Firmware v6.2 ships eleven UF2 images. The board a UF2 is built for decides its default pin map; every pin can then be remapped in the App (Volume 5), so a “generic” image works on any RP2040 or RP2350 board once its pins are set by hand.

Table 1 — 3.2 Supported boards

UF2 (OpenFIREfw.*.uf2)BoardChipDefault layoutNotes from the project
rpipicoRaspberry Pi Pico and clonesRP2040YesREADME: “cheapest, most pins available”
rpipico2Raspberry Pi Pico 2RP2350Yes, pin-identical to Picov6.0 notes: the team had no Pico 2 boards to test on at release
rpipicow-noBTPico W, USB onlyRP2040Yes, as PicoBluetooth build is a known issue: “TinyUSB/Serial fails to initialize properly when connected via USB”
rpipico2w-noBTPico 2 W, USB onlyRP2350Yes, as Pico
adafruitItsyAdafruit ItsyBitsy RP2040RP2040Yes (SAMCO 2.0); SAMCO 1.1 as an App presetFits SAMCO carrier boards
adafruitKB2040Adafruit KB2040 “Kee Boar”RP2040YesPro Micro footprint, for other carrier boards
arduinoNanoArduino Nano RP2040 ConnectRP2040YesPins handled by the NINA Wi-Fi chip “are not yet exposed”
waveshareZeroWaveshare RP2040-ZeroRP2040YesUnderside pads 17–25 “not yet exposed to the OpenFIRE App”
vccgndYDVCC-GND YD RP2040 (“the Chinese Pico clone with embedded NeoPixel”)RP2040No — BOARDS.md: “no default layout yet”Map every pin in the App
genericAny other RP2040RP2040No”may or may not work”
generic_rp2350Any other RP2350RP2350NoAs above

The shared header also carries presets for three ESP32-S3 boards (Espressif DevKitC-1, Waveshare ESP32-S3-Pico and ESP32-S3-Zero). They serve the ESP32 port described in Volume 1; the TeamOpenFIRE firmware has no ESP32 build.

Figure 2 — A Raspberry Pi Pico, top and bottom. The GP numbers that OpenFIRE's documentation uses are printed only on the underside (left); the top (right) carries the BOOTSEL button and only a handful of pin…
Figure 2 — A Raspberry Pi Pico, top and bottom. The GP numbers that OpenFIRE's documentation uses are printed only on the underside (left); the top (right) carries the BOOTSEL button and only a handful of pin numbers. Photo: Ogidya, Wikimedia Commons, CC BY-SA 4.0.

For this build the board is decided: a Raspberry Pi Pico (RP2040) to start, on a carrier board, with any microcontroller acceptable later if it has enough inputs and outputs. The pin budget that proves the Pico has enough is in Reference Electronics. The Pico 2 is pin-identical and OpenFIRE treats it identically, so it stays a drop-in trial: the RP2350’s faster Cortex-M33 cores and floating-point unit give headroom for anything a fork adds (heavier filtering, a second camera, the maths in Aiming Maths and Calibration).

Why this, and why not the others. Criteria: a release UF2 with a full default pin map; enough GPIO for every button, the Hall trigger, two power stages, rumble and status; the board every OpenFIRE gun in the field has run; price and stock.

Table 2 — 3.2 Supported boards

BoardVerdictReason
Raspberry Pi Pico (RP2040)Pickrpipico UF2 with the full default map; the README’s “cheapest, most pins available”; what every OpenFIRE gun in the field runs; $4.00–4.60 (3.11)
Raspberry Pi Pico 2 (RP2350)Drop-in laterSame map and same UF2 family; the team’s v6.0 notes say they had not tested Pico 2 boards at release, and it was out of stock at Adafruit on 2026-10-18
Pico W / Pico 2 WRejectedOnly -noBT builds ship, because Bluetooth is a known issue in the README; the radio adds nothing to a wired gun
Adafruit KB2040, ItsyBitsy RP2040RejectedFewer pins; they matter only for a carrier or shell built around their footprints (SAMCO boards for the ItsyBitsy)
Waveshare RP2040-Zero, Arduino Nano RP2040 ConnectRejectedPins the App cannot yet assign: the Zero’s underside pads and the Nano’s NINA-handled pins
VCC-GND YD RP2040, generic RP2040/RP2350RejectedNo default layout; every pin mapped by hand, “may or may not work”
ESP32-S3 boardsNot for the first gunOnly the separate ESP32 port supports them; its PixArt camera support is the reason to revisit (Volume 1)

The KB2040 and ItsyBitsy matter only if a carrier board or shell is designed around their footprints.

Figure 3 — The Raspberry Pi Pico 2, the RP2350 version of the board. It is pin-for-pin compatible with the original Pico, and OpenFIRE uses the same default layout for both. Photo: Profpcde, Wikimedia Commons…
Figure 3 — The Raspberry Pi Pico 2, the RP2350 version of the board. It is pin-for-pin compatible with the original Pico, and OpenFIRE uses the same default layout for both. Photo: Profpcde, Wikimedia Commons, CC0.

3.3 The Pico’s default pin map

Figure 4 — The Raspberry Pi Pico's pins with OpenFIRE's default function for each, from the rpipico entry of the boardsPresetsMap table in OpenFIREshared.h. Buttons occupy most of the left edge with the trigg…
Figure 4 — The Raspberry Pi Pico's pins with OpenFIRE's default function for each, from the rpipico entry of the boardsPresetsMap table in OpenFIREshared.h. Buttons occupy most of the left edge with the trigger on GP15 at the bottom; the solenoid and rumble signals are GP16 and GP17 on the bottom right; the camera is on GP20 and GP21 (the RP2040's I2C0); a second I2C bus for an OLED is on GP18 and GP19; GP28 reads a TMP36 temperature sensor. The grey suggestions for GP22, GP26 and GP27 are from the Hardware Guide and are not defaults. Own-work diagram.

BOARDS.md draws the Pico’s defaults as ASCII art; quoted exactly, with the legend “(x) = GND/No Connect | (-) = GPIO | (p) = Power”:

                   A Button     0  |-)   *USB*   (-| VBUS (USB voltage)
                   B Button     1  |-)           (-| VSYS (Input from Battery/Output to NeoPixels)
                               GND |x)           (x| GND
                   C Button     2  |-)           (x| 3V3 En
                   Start        3  |-)           (p| 3V3 Out (to Display/Cam/Analog Inputs)
                   Select       4  |-)           (x| ADCVREF
                   Home Button  5  |-)           (-|  A2 Temp Sensor
                               GND |x)           (x| AGND (for ADC VREF)
                   D-Pad Up     6  |-)           (-|  A1 *Unmapped*
                   D-Pad Down   7  |-)           (-|  A0 *Unmapped*
                   D-Pad Left   8  |-)           (x| RUN
                   D-Pad Right  9  |-)           (-|  22 *Unmapped*
                               GND |x)           (x| GND
                   RGB Red     10  |-)           (-|  21 Camera SCL
                   RGB Green   11  |-)           (-|  20 Camera SDA
                   RGB Blue    12  |-)           (-|  19 Peripherals SCL
                   Pump Action 13  |-)           (-|  18 Peripherals SDA
                               GND |x)           (x| GND
                   Pedal       14  |-)           (-|  17 Rumble Signal
                   Trigger     15  |-)   _|_|_   (-|  16 Solenoid Signal

The code agrees. The rpipico row of boardsPresetsMap maps GP0–GP9 to A, B, C, Start, Select, Home and the four D-pad directions; GP10–GP12 to the RGB LED; GP13 pump action, GP14 pedal, GP15 trigger, GP16 solenoid, GP17 rumble, GP18/GP19 peripheral SDA/SCL, GP20/GP21 camera SDA/SCL, GP22 unmapped, GP23–25 “unavailable” (not brought out on the Pico), GP26 and GP27 unmapped, GP28 the temperature sensor, and GP29 unavailable. A header comment notes that “pin 29/A3 is used for builtin chipset temp monitor” — on the Pico that ADC channel actually reads VSYS through a divider, and either way it is not offered to the user. The Pico W, Pico 2 and Pico 2 W rows are identical.

Two practical points from COMPILING.md. The numbers are GPIO numbers, not physical pin numbers: “on many boards, including the Raspberry Pi Pico and the Adafruit Itsybitsy RP2040, these are the silkscreen labels on the underside of the microcontroller (marked GP00-29)”. And A0–A3 are aliases for GP26–GP29. The App’s board previewer (Help → View Compatible Boards) shows the same map interactively, highlighting each pin as the cursor passes over its label.

Figure 5 — The underside of a Raspberry Pi Pico, where the GP numbers are printed beside each pad, along with the three SWD debug pads at one end. Photo: Phiarc, Wikimedia Commons, CC BY-SA 4.0.
Figure 5 — The underside of a Raspberry Pi Pico, where the GP numbers are printed beside each pad, along with the three SWD debug pads at one end. Photo: Phiarc, Wikimedia Commons, CC BY-SA 4.0.

For a gun with a custom PCB, the defaults are a convenience, not a constraint. The things that are fixed by hardware are: the camera’s SDA and SCL must be an even/odd pair on one I²C block (Volume 2); the temperature sensor and an analog stick need ADC pins (GP26–GP28 on a Pico); and a Wii camera clock needs a pin whose PWM slice is free. Everything else is a free choice, which is how Reference Electronics can route the PCB first and set the pin map to match.

3.4 Every assignable function

The functions the App can assign to a pin are fixed by the boardInputs_Strings table in OpenFIREshared.h, with their names exactly as the App shows them:

Table 3 — The functions the App can assign to a pin are fixed by the boardInputsStrings table in OpenFIREshared.h, with their names exactly as the App shows them

GroupFunctions
ButtonsTrigger · Button A · Button B · Button C · Start · Select · D-Pad Up / Down / Left / Right · Pedal · Alt Pedal · Pump Action · Home Button
Force feedback outputsRumble Signal · Solenoid Signal
Hardware togglesRumble Switch · Solenoid Switch · Autofire Switch
LightsExternal NeoPixel · RGB LED Red · RGB LED Green · RGB LED Blue
BusesCamera SDA · Camera SCL · Peripherals SDA · Peripherals SCL
AnalogAnalog Stick X · Analog Stick Y · Temperature Sensor
ClockWii Cam Clock

Buttons are active-low with the RP2040’s internal pull-ups; the Hardware Guide puts it as “Buttons are all assigned internal pull-up resistors so no extra hardware is needed. Any momentary, normally open button will work.” The toggle switches are read the same way (a closed switch means the feature is on). How switches, triggers and debounce should be chosen for this build is Controls and Inputs.

3.5 The camera

Figure 6 — The DFRobot SEN0158 seen from the cable end, showing the printed "TOP" mark and the wire legend on the body. The mark sets the camera's rotation in the barrel; a camera mounted rotated reports a ro…
Figure 6 — The DFRobot SEN0158 seen from the cable end, showing the printed "TOP" mark and the wire legend on the body. The mark sets the camera's rotation in the barrel; a camera mounted rotated reports a rotated scene, which calibration's tilt correction can absorb only up to a point. Photo: DFRobot, dfrobot.com product page.

OpenFIRE’s README names one camera: the DFRobot IR Positioning Camera, SEN0158, linked to Mouser as the US distributor and to DFRobot’s own shop. DFRobot’s page describes it as an I²C module running from 3.3 to 5 V, with a sensor “Resolution is 128x96 pixel” that tracks up to four infrared objects, a detecting distance of 0 to 3 m, and a field of view of 33° horizontal by 23° vertical. The 1024 × 768 coordinates the driver reads are the sensor’s own sub-pixel interpolation of that 128 × 96 array. Inside is the PixArt sensor from the Wii Remote, and the driver’s register values come from the Wii Remote reverse-engineering effort (Volume 2).

Figure 7 — OpenFIRE Hardware Guide v1.3, camera page. The DFRobot camera's four wires go to the Pico's 3V3 OUT (red, VCC), GND (black), GP21 (green, SCL) and GP20 (yellow, SDA). The inset shows the camera end…
Figure 7 — OpenFIRE Hardware Guide v1.3, camera page. The DFRobot camera's four wires go to the Pico's 3V3 OUT (red, VCC), GND (black), GP21 (green, SCL) and GP20 (yellow, SDA). The inset shows the camera end-on with its alignment mark, and the note asks the builder to check alignment in the App after construction. Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

The Hardware Guide wires it as: red to 3V3 OUT, black to GND, green (SCL) to GP21, yellow (SDA) to GP20, with the note “Camera Alignment (test in App after construction for best results)”. Powering it from 3.3 V rather than 5 V keeps the I²C lines at the Pico’s logic level; the module’s own pull-ups and level handling are a question for Reference Electronics, which should also decide whether 1 MHz I²C over the cable a long barrel needs is acceptable.

Figure 8 — The DFRobot SEN0158 with its lead, which ends in a four-way connector. The wire colours on the lead match the Hardware Guide's wiring: red, black, green and yellow. Photo: DFRobot, dfrobot.com prod…
Figure 8 — The DFRobot SEN0158 with its lead, which ends in a four-way connector. The wire colours on the lead match the Hardware Guide's wiring: red, black, green and yellow. Photo: DFRobot, dfrobot.com product page.

Availability. On 18 October 2026 DFRobot’s page lists the SEN0158 at US$23.55 but shows a “Notify Me” button rather than an add-to-cart, and says “A new version of Gravity: IR Positioning Camera is currently in development.” Nothing on the page says when, or whether the new version will be register-compatible. Every open firmware in Volume 1 depends on this module or on the Wii sensor inside it, so its availability is the single largest supply risk in the build. The fallbacks, in order of how much of OpenFIRE they keep:

  1. Distributor stock of the current SEN0158 (Mouser is the README’s link; its page could not be read for this dive).
  2. A Wii Remote sensor wired as the Hardware Guide shows (3.6). Same chip, same driver, but it needs its own clock and careful soldering.
  3. A PixArt PAJ7025R2 or R3, which the ESP32 port supports and the TeamOpenFIRE firmware does not. That route means either the ESP32-S3 or a port of that camera code to the RP2040 in Our Firmware.

The camera for this build. The camera is being researched and chosen against alternatives because of exactly this supply risk. The Reference Electronics dive’s proposal for the first prototype is fallback 2: a harvested genuine Wii Remote camera on a small carrier board, clocked from GP22 — the only buyable part that stock OpenFIRE supports, with the same sensor and field of view as the SEN0158. A SEN0158 from remaining stock is the backup, and a PAJ7025R3 on an ESP32-S3 is the later option for the wider field of view a large television needs. The comparison and its reasons are in that volume. The sensor families themselves are compared in IR Point Tracking.

3.6 The Wii Remote sensor as a camera

Figure 9 — A die photograph labelled as the PixArt PFC089 optical sensor, said to be the chip inside the Wii Remote's IR camera. The large light square is the pixel array; the logic that finds and reports the…
Figure 9 — A die photograph labelled as the PixArt PFC089 optical sensor, said to be the chip inside the Wii Remote's IR camera. The large light square is the pixel array; the logic that finds and reports the four brightest blobs sits beside it. That on-chip blob tracking is why a light gun needs only an I2C read, not image processing. Photo: John McMaster, Wikimedia Commons, CC BY 4.0.

The Hardware Guide gives two ways to use a sensor salvaged from a Wii Remote in place of the DFRobot module. Both use the same I²C pins (SDA GP20, SCL GP21) and 3V3; they differ in where the sensor’s clock comes from.

Figure 10 — OpenFIRE Hardware Guide v1.3, "DIY WiiMote Conversion (using clock pin)". The bare eight-pin sensor is fed its clock from GP22 on the Pico, with a 4.7 kilohm resistor in the drawing; the pin-out is…
Figure 10 — OpenFIRE Hardware Guide v1.3, "DIY WiiMote Conversion (using clock pin)". The bare eight-pin sensor is fed its clock from GP22 on the Pico, with a 4.7 kilohm resistor in the drawing; the pin-out is shown from the rear and from below. The guide notes that the clock pin "will need to be set in the App". Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

Clock from the Pico. The sensor’s clock input is driven from a GPIO — the guide suggests GP22 — mapped in the App to “Wii Cam Clock”. The firmware then generates the clock itself: it drops the system clock to 125 MHz and runs that pin as PWM with a period of five system clocks, giving 25 MHz (Volume 2). The guide labels this a “Suggested pin-out”; any pin with a usable PWM channel will do.

Figure 11 — OpenFIRE Hardware Guide v1.3, "DIY WiiMote Conversion (using crystal)". The sensor gets its clock from a separate 24 MHz crystal oscillator instead of a Pico pin, with 4.7 kilohm and 22 kilohm resi…
Figure 11 — OpenFIRE Hardware Guide v1.3, "DIY WiiMote Conversion (using crystal)". The sensor gets its clock from a separate 24 MHz crystal oscillator instead of a Pico pin, with 4.7 kilohm and 22 kilohm resistors as drawn. Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

Clock from a crystal. The alternative drawing uses a separate 24 MHz oscillator and frees the Pico’s pin and its system clock. The project’s two sources therefore disagree on frequency — 25 MHz generated in code, 24 MHz in the crystal drawing — and both are presented as working. The Wii Remote’s own clock frequency is a fact for IR Point Tracking to establish from a primary source; until it does, the 25 MHz the firmware generates is the configuration the code was written and tested against.

3.7 Emitter layouts and the emitters

Figure 12 — The two emitter layouts OpenFIRE supports, as the App's alignment assistant draws them and as the firmware's screen model assumes them. Square: two emitters above the picture and two below, at 20 a…
Figure 12 — The two emitter layouts OpenFIRE supports, as the App's alignment assistant draws them and as the firmware's screen model assumes them. Square: two emitters above the picture and two below, at 20 and 80 percent of its width. Diamond: one emitter at the middle of each edge. The layout is chosen per calibration profile. Own-work diagram.

OpenFIRE tracks four emitters in one of two arrangements, chosen per profile:

  • Square, which the instruction book calls “dual lightbars, or ‘square’ layout (Samco, preferred)” and the README “double lightbar (recommended!)”: two emitters above the picture and two below. The App’s IR Emitter Alignment Assistant (appcali.cpp) draws the target boxes at 20 % and 80 % of the picture width on the top and bottom edges.
  • Diamond, “four separate points on the display … (Xwiigun and other legacy lightgun systems)”: one emitter at the middle of each edge.

The project’s own home page describes the default as “arranged in a rectangle pattern with two on top and two on bottom”. The layout Michael’s brief describes as common for Samco-style builds — “one IR point at the middle of each screen edge” — is the diamond, not the one OpenFIRE recommends.

The placement rule that follows from the code. The firmware’s screen model puts the square layout’s emitters exactly on the top and bottom edges of the picture, and calibration works out their horizontal spacing from what the camera sees (Volume 2). So the emitters should be as close to the top and bottom edges of the picture as the bezel allows, centred, and roughly at the 20/80 % marks. Exact spacing does not matter — calibration measures it — but the bars should be parallel, level and symmetric, because the model assumes a rectangle. Distance from the picture edge is absorbed by the edge-shot offsets, at some cost in linearity near the corners.

With the exact inverse map (Aiming Maths and Calibration, Volume 4), placement stops affecting accuracy, though it still matters for the camera’s field of view; the rule above is the right one for v6.2’s map.

The emitters. The README: “regular Wii sensor bars might work for small distances, but it’s HIGHLY recommended to use SFH 4547 LEDs w/ 5.6Ω (ohm) resistors”. The instruction book adds that two Wii sensor bars work for “a small PC monitor”, while a TV calls for “a set of high power black IR LEDs … arranged like (larger) sensor bars”. The OSRAM SFH 4547 is a 940 nm, 5 mm emitter rated for 100 mA continuous with a typical forward voltage of 1.5 V at that current (datasheet). A 5.6 Ω resistor cannot be meant for one SFH 4547 on 5 V — that would pass well over half an amp — so the figure implies a series string; three in series from 5 V leave about 0.5 V across 5.6 Ω, or roughly 90 mA. The README does not say so, and that is arithmetic, not the project’s statement. It is also a sensitive design: a ±0.1 V tolerance on each of three forward voltages moves the resistor’s voltage between about 0.2 and 0.8 V and the current between about 35 and 145 mA. The emitter bar is designed properly in Reference Electronics; 850 versus 940 nm and sunlight are in IR Point Tracking.

3.8 The solenoid, as the Hardware Guide draws it

Figure 13 — OpenFIRE Hardware Guide v1.3, "Solenoid — DIY Setup". GP16 drives the gate of a TO-220 MOSFET (IRL540, or the part printed as IRL44Z) through 1 kilohm, with 100 kilohms from gate to ground; the sol…
Figure 13 — OpenFIRE Hardware Guide v1.3, "Solenoid — DIY Setup". GP16 drives the gate of a TO-220 MOSFET (IRL540, or the part printed as IRL44Z) through 1 kilohm, with 100 kilohms from gate to ground; the solenoid runs from a separate 12 or 24 V adaptor rated 4 to 5 A, with a diode across it; a TMP36 temperature sensor sits on the solenoid body, powered from 3V3 OUT and read on GP28, with 100 nF across its supply. Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

The Hardware Guide draws two solenoid circuits on the Pico, both with the solenoid signal on GP16:

DIY: a logic-level N-channel MOSFET — the guide lists IRL540 and a part printed as “IRL44Z” — with 1 kΩ in series from GP16 to the gate and 100 kΩ from gate to ground; the solenoid between the supply’s positive and the drain, with a diode (1N4007; “1N4001 (Obsolete)”) across it; a 12 V or 24 V, 4–5 A adaptor whose ground is common with the Pico’s. Solenoids named: JB-0530 and JF-1039, each in 12 V and 24 V versions.

MOSFET module: the same, with a ready-made module built around an AOD4184 or LR7843 taking GP16 on its PWM input.

Both drawings put a TMP36 on the solenoid body, powered from 3V3 OUT with its output on GP28, and note: “Temp sensor pin will need to be allocated in the App (analog pins only).” The 100 nF in these drawings is the TMP36’s decoupling capacitor between 3V3 and ground; there is no capacitor across the solenoid or its supply in either drawing.

Figure 14 — OpenFIRE Hardware Guide v1.3, "Solenoid — MOSFET Module Setup". The same arrangement with a ready-made MOSFET module (AOD4184 or LR7843) switching the solenoid from GP16; the TMP36 on the solenoid …
Figure 14 — OpenFIRE Hardware Guide v1.3, "Solenoid — MOSFET Module Setup". The same arrangement with a ready-made MOSFET module (AOD4184 or LR7843) switching the solenoid from GP16; the TMP36 on the solenoid body still reports to GP28. Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

Things to carry into the sibling dives rather than act on here:

  • “IRL44Z” is not a part number that could be found. It is probably the IRLZ44N, a common logic-level MOSFET; the guide should be read as “an IRL540 or an IRLZ44N-class logic-level part” until the authors say otherwise.
  • Gate resistors. Michael’s brief uses about 100 Ω series and 10 kΩ pull-down; the project uses 1 kΩ and 100 kΩ. Both hold the gate low at boot. The trade between switching speed and ringing belongs to Solenoid Recoil.
  • The firmware drives GP16 with plain digitalWrite, not PWM: the module’s “PWM” input simply sees a logic-level on/off. Pulse timing (45 ms on by default) is set in the App (Volume 5).
  • Wiring gauge. The README: “Solenoid may cause EMI disconnects with too thin of wiring. Cables for this run specifically should be 24AWG at its thinnest - or else the cables will become antennas under extended use, which will trip USB safety thresholds in your PC to protect the ports.” The symptom (USB drop-outs when the solenoid fires) is widely reported; the explanation is the project’s. Supply droop and ground bounce on a shared return are the more conventional suspects, and Power Supplies measures them.
  • The README also links two OSH Park driver boards (solenoid and rumble). Their designs were not inspected for this dive.

3.9 Rumble

Figure 15 — OpenFIRE Hardware Guide v1.3, "Rumble — DIY Setup". An N20 gear motor runs from the Pico's VBUS (USB 5 V) through a 2N2222 transistor whose base is driven from GP17 through 500 ohms to 1 kilohm; a …
Figure 15 — OpenFIRE Hardware Guide v1.3, "Rumble — DIY Setup". An N20 gear motor runs from the Pico's VBUS (USB 5 V) through a 2N2222 transistor whose base is driven from GP17 through 500 ohms to 1 kilohm; a diode and a 100 nF capacitor sit across the motor. Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

The rumble motor’s signal is GP17. The Hardware Guide’s DIY circuit runs an N20 motor from VBUS — the USB 5 V — through a 2N2222 NPN transistor with 500 Ω–1 kΩ in the base, and puts a diode and 100 nF across the motor. A MOSFET-module version uses the same AOD4184 or LR7843 modules as the solenoid. Unlike the solenoid, the rumble output is PWM: the firmware writes analogWrite(rumblePin, rumbleStrength), 255 by default, so the App’s strength setting sets the duty cycle. The README asks for “Any 5V gamepad rumble motor”. The motor’s current comes out of the host’s USB port, which is a budget to check against the Pico’s own draw, the camera and any NeoPixels; Motors and Rumble covers the motor.

3.10 Buttons, status LED, NeoPixels, OLED and stick

Figure 16 — OpenFIRE Hardware Guide v1.3, "Buttons — Default Layout". Each button is a normally open switch from its GPIO to ground: A on GP0, B GP1, C GP2, Start GP3, Select GP4, Home GP5, the D-pad on GP6 to…
Figure 16 — OpenFIRE Hardware Guide v1.3, "Buttons — Default Layout". Each button is a normally open switch from its GPIO to ground: A on GP0, B GP1, C GP2, Start GP3, Select GP4, Home GP5, the D-pad on GP6 to GP9, pump action GP13, pedal GP14 and trigger GP15. Image: OpenFIRE Hardware Guide v1.3, openfirelightgun.org.

The rest of the Hardware Guide, briefly, all on the Pico:

Table 4 — The rest of the Hardware Guide, briefly, all on the Pico

ItemAs drawnNotes in the guide
ButtonsSwitch from each GPIO to GND (defaults as 3.3)Internal pull-ups; “Any momentary, normally open button will work”
Status LED, common cathodeGP10/GP11/GP12 through 220 Ω, cathode to GNDPins reassignable
Status LED, common anodeSame, anode to 3V3 OUTThe firmware’s default toggle is common anode (LEDAnode true); a common-cathode LED needs the toggle changed in the App
NeoPixel (WS2812B)Data from GP10, power from VBUS”Up to three/four NeoPixels can be run directly off VBUS - any additional pixels should be driven by external voltage due to USB amp draw limitations”; pin and count set in the App
SSD1306 OLED, 1.3 in, 128 × 64, I²CSDA GP18, SCL GP19, 3V3”Your pin-outs may differ”
Analog stickGP26, GP27, 3V3”There are many versions of these so check your pin-outs carefully”; must be ADC pins

The defaults leave the second I²C bus (GP18/GP19) free for the OLED so the camera’s bus carries only the camera, which matches the two-core design in Volume 2.

3.11 Where to buy, with dated prices

Prices are from each seller’s own page on 18 October 2026, in US dollars, single quantity. The full bill of materials for this build, with alternates, belongs to Reference Electronics.

Table 5 — 3.11 Where to buy, with dated prices

PartMaker’s pagePrice and stock (seller, 2026-10-18)
Raspberry Pi Pico (RP2040)raspberrypi.com/products/raspberry-pi-picoAdafruit #4864 $4.00, out of stock; SparkFun DEV-17829 $4.60, in stock
Raspberry Pi Pico 2 (RP2350)raspberrypi.com/products/raspberry-pi-pico-2Adafruit #6006 $6.25, out of stock
Adafruit KB2040adafruit.com/product/5302Adafruit $8.95, in stock
Adafruit ItsyBitsy RP2040adafruit.com/product/4888Adafruit $9.95, “64 in stock”
DFRobot SEN0158 IR Positioning Cameradfrobot.com/product-1088.htmlDFRobot $23.55, “Notify Me” (not orderable)
OSRAM SFH 4547 emitter(README links Mouser 720-SFH4547)Mouser’s page did not load for this dive; not quoted
Figure 17 — The Adafruit KB2040, a Pro Micro-footprint RP2040 board with a USB-C connector and a STEMMA QT I2C socket, one of the README's three recommended boards. Photo: Adafruit Industries, adafruit.com.
Figure 17 — The Adafruit KB2040, a Pro Micro-footprint RP2040 board with a USB-C connector and a STEMMA QT I2C socket, one of the README's three recommended boards. Photo: Adafruit Industries, adafruit.com.
Figure 18 — The Adafruit ItsyBitsy RP2040, the board that fits SAMCO carrier PCBs and the one the README recommends for builders using them. Photo: Adafruit Industries, adafruit.com.
Figure 18 — The Adafruit ItsyBitsy RP2040, the board that fits SAMCO carrier PCBs and the one the README recommends for builders using them. Photo: Adafruit Industries, adafruit.com.

Michael’s brief put the whole electronics at “about US$50 to $60 … (from a late-2024 forum report in probably AUD)”. At October 2026 prices the two core parts alone are $4.00 to $6.25 for the board and $23.55 for the camera, when it can be bought.

3.12 What could not be verified

  • The identity of the “IRL44Z” in the Hardware Guide (probably IRLZ44N).
  • Whether the Wii sensor should be clocked at 25 MHz (firmware) or 24 MHz (Hardware Guide crystal drawing); both are the project’s.
  • The OSH Park solenoid and rumble driver boards linked from the README; designs not inspected.
  • Mouser and DigiKey stock and prices for the SEN0158 and SFH 4547 (the pages could not be read).
  • When DFRobot’s “new version” of the camera will ship and whether OpenFIRE’s driver will work with it.

Sources

  1. TeamOpenFIRE, OpenFIRE-Firmware v6.2: README.md, BOARDS.md, COMPILING.md, OpenFIREmain/README.md, OpenFIREmain/OpenFIREprefs.h, OpenFIREFeedback.cpp, OpenFIREcommon.cpp, https://github.com/TeamOpenFIRE/OpenFIRE-Firmware — read 2026-10-18. Release notes for v6.0 and v6.2.
  2. TeamOpenFIRE, OpenFIRE-Boards, OpenFIREshared.h and boardPics/*.svg, https://github.com/TeamOpenFIRE/OpenFIRE-Boards — read 2026-10-18.
  3. TeamOpenFIRE, OpenFIRE-App src/appcali.cpp (alignment assistant geometry), https://github.com/TeamOpenFIRE/OpenFIRE-App — read 2026-10-18.
  4. OpenFIRE Hardware Guide, version 1.3, https://openfirelightgun.org/wp-content/uploads/2026/10/OpenFIRE-Hardware-Guide_1.3.pdf (PDF created 2026-10-17) — read 2026-10-18.
  5. OpenFIRE project home page, https://openfirelightgun.org/ — read 2026-10-18.
  6. DFRobot, “Gravity: IR Positioning Camera For Arduino” (SEN0158), https://www.dfrobot.com/product-1088.html — read 2026-10-18.
  7. ams OSRAM, SFH 4547 datasheet (940 nm, 5 mm IRED).
  8. Seller pages, 2026-10-18: https://www.adafruit.com/product/4864, /6006, /5302, /4888; https://www.sparkfun.com/raspberry-pi-pico.html.

Comments (0)

  1. Loading…

Comments are held for moderation — nothing appears until approved.