Learn

Design your sim racing button box in the browser

Advanced

Or see every lesson.

  • 261parts on the bench
  • 31boards running now
  • 1.00xreal time, on every board
Pro Micro: a complete button boxlive0.000 s 0.00x
Press Run, then turn the knobs and flip the switches
Turn the knobs, flip the slide switches and hold the arcade buttons. The Serial Monitor shows each event and the [Joystick] report.

A button box puts the controls you reach for in a race under your hand: an ignition key and a start button, knobs for traction control and ABS, toggles for wipers and lights, a guarded switch for the pit limiter, and a row of buttons for the radio and the pit request. Inside, it is a small board and a lot of switches, and the board most DIY boxes use is a Pro Micro or a Leonardo, because their ATmega32U4 is its own USB device and can show up on the PC as a game controller.

The box above is a complete template. Turn the knobs, flip the switches and hold the buttons while it runs, and the Serial Monitor shows every event and the controller report the box would send. The sketch keeps the whole panel in two tables at the top, so changing the box is changing a row: which pin, what kind of switch, which button it drives.

One thing up front: Mokxi does not simulate the USB connection to a PC. The Joystick library prints the report it would send as a [Joystick] line instead. Everything up to that point is real and running: the wiring, the pull-ups, the debounce, the encoder decoding, the pulse timing and the button map. Flash the same sketch to a real Pro Micro and the reports go over USB.

Want the step-by-step version? The lesson "Buttons and toggles a game understands" walks through this with checkpoints.

Open the lesson

Plan the panel, then count the pins

Start with what you actually press in your games, then count inputs. This template has two encoders with push (three pins each), an ignition key and a START button, three toggles, four momentary buttons and three status LEDs: eighteen pins, which is every one a Pro Micro brings out. A Leonardo adds a few more.

Past that, builders wire their buttons as a matrix with a diode on each switch, exactly as a keyboard does, so 25 buttons fit on ten pins. The keyboard matrix page explains the matrix and the diode, and it is the same circuit whether the switches are keys or arcade buttons.

Every switch here is wired the same way: one leg to GND, one to a pin with the internal pull-up on. A closed switch reads LOW and no resistors are needed anywhere except in series with the LEDs.

Why toggles should send pulses

A game binds a control to a button press. A latching toggle that holds its button down while it is on looks to the game like one very long press, and flipping it off, which releases the button, does nothing. So the sketch has three kinds of toggle. PULSE sends one short press on every flip, for controls that toggle in the game, like wipers. PULSE_BOTH sends a press on one button going on and on another going off, for games with separate on and off commands, so the switch can never get out of step. HOLD keeps the button down while the switch is on, for tools that read a held button as a state.

The ignition key gets its own kind. START is a STARTER switch: it is held only while the key is on, so a knock on the button with the key off sends nothing, as in a real car.

The panel, as the sketch describes it
const Switch SWITCHES[] = {
  {6, IGNITION, 0, 1, "ignition"},
  {A3, STARTER, 2, NONE, "start"},
  {8, PULSE, 3, NONE, "wipers"},
  {9, PULSE_BOTH, 4, 5, "lights"},
  {7, HOLD, 6, NONE, "pit limiter"},
  {A2, MOMENTARY, 7, NONE, "pit request"},
};

Encoders that never miss a click

Traction control, ABS and brake bias are usually bound to a pair of buttons, one for up and one for down, so each click of a knob should be one press. Two things go wrong with naive encoder code. Cheap encoders bounce, so one click counts as three; and a game reads the controller once a frame, so a press that is too short, or two presses with no gap, can be missed.

The template reads each encoder with a state table: every valid change of the two contacts adds or subtracts one, a bounce adds one and takes it straight back, and only a net count at rest on a detent becomes a click. Each click is then queued and played out as a press of PULSE_MS followed by GAP_MS released, so a fast spin arrives as every one of its clicks. The encoders in Mokxi bounce the way real ones do, so you can see the table cope.

Lights, and what they can know

The three LEDs each follow a switch: the ignition, the pit limiter and the lights. That is honest about what a box on its own can know. An LED that shows what the car is doing, such as a pit limiter the game turned off, needs the game’s telemetry, and on a real rig that is the job of a tool such as SimHub, talking to the board over USB. The wiring and the pins you settle here are the same either way.

A shifter, a handbrake and a flight panel

The same course goes on past the box. The shifter template reads an H pattern from two pots with trigger and release lines so a gear never chatters, uses a push-down button for reverse, adds sequential paddles, and turns a hall sensor into a handbrake axis with dead zones. The flight panel template is an autopilot knob for heading, altitude and vertical speed on a four-digit display, an AP button, and a gear lever with three green lights and a red one in transit.

For flight sims, be clear about the display: on a real panel the numbers come back from the sim through a bridge such as MobiFlight, SimConnect or DCS-BIOS. The template keeps its own count instead, which is fine for testing the wiring and the knob, and says so.

Questions

Which board should a button box use?

One whose chip is its own USB device: a Pro Micro, Leonardo or Micro (ATmega32U4), or an RP2040 board with suitable firmware. An Uno cannot be a game controller with the Joystick library, because its USB is a separate serial chip.

Does Mokxi simulate the USB game controller?

No. The Joystick library prints each report it would send to the Serial Monitor. You test the wiring, the switch logic and the button map here, then flash the same sketch to a real board.

How many buttons can a Pro Micro handle?

Eighteen inputs wired directly, one per pin. With a diode matrix, rows times columns: five rows and five columns is 25 buttons on ten pins. The Joystick library reports up to 32 buttons.

Should toggles hold their button or pulse it?

Pulse, for most game bindings, because games act on a press. Use separate on and off pulses when the game has both commands, and hold only for tools that read a held button as a state.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.