Arduino Leonardo and a USB Host Shield
The cheapest input device in the stack: how the shield sits on the board, why its SPI lines must be jumpered to the ICSP header, uploading the sketch, and the limits you accept.
Short answer
An Arduino Leonardo with a USB Host Shield is the cheapest working mouse passthrough: the shield's MAX3421E reads your mouse and the ATmega32u4 presents it. It is also the fiddliest: most shields expect Uno pin mapping and need SPI jumpered to the ICSP header.
On this page9
Why you need a Leonardo, not an Uno
The reason is the microcontroller. The Leonardo uses an ATmega32u4, which has USB built into the chip, so the board can present itself to a PC directly as a keyboard, a mouse or a serial port. An Uno cannot do this, because its USB socket is wired to a separate bridge chip whose only job is serial, so it can never claim to be a mouse. That one difference is the entire reason this build specifies a Leonardo. It is also why the Uno you already own will not work, however the code is written. Boards with the same 32u4 chip, such as a Pro Micro, work on the same principle.
What parts you need
The build needs two boards and two cables. That simplicity is the appeal, and it really is the cheapest way to a working cursor.
- Arduino Leonardo
- ATmega32u4 with native USB. Presents the mouse interface to the game PC and also carries the serial link
- USB Host Shield 2.0
- Carries a MAX3421E USB host controller, talked to over SPI. This is the half your real mouse plugs into
- Library
- The USB Host Shield Library 2.0, which provides the HID mouse handling on the host side
- Cable to the game PC
- The Leonardo's own micro-USB socket. This is the HID side
- Cable to the second PC
- Also the Leonardo's USB socket on a single-cable build, or a separate USB-to-serial adapter on a UART if you want the links physically separate
- Soldering iron
- Not optional in practice. See the next block
Warning
How to connect the shield's SPI lines
This is the step that gives the build its reputation. Most USB Host Shields were designed for the Uno, where SPI is exposed on digital pins 11, 12 and 13. On the Leonardo those pins are not SPI at all, because SPI is available only on the 6-pin ICSP header. If you stack an Uno-mapped shield onto a Leonardo, it will look correct while the board never communicates with the MAX3421E.
- Check whether your shield has a female ICSP connector on its underside. Shields that have one stack onto a Leonardo and simply work
- If it does not, you will need to add jumpers. Find where the shield's SPI pins (clock, data in and data out) land on the Uno header
- Cut, bend out or otherwise isolate those three pins so they no longer connect to the Leonardo's digital pins 11, 12 and 13
- Run three wires from the isolated shield pins to the matching pins on the Leonardo's ICSP header
- Leave the chip-select line, usually pin 10, connected as it was, because chip select is an ordinary digital pin and its mapping is already correct
- Before you power the stack, confirm that the shield is getting 5V and ground from the header
- Power up and run the library's board-diagnostic example. It reports whether the MAX3421E responds at all, which is the only thing this step needs to establish
How to upload the sketch
Uploading is straightforward once the wiring is right, but prove that the host side works before you write or flash anything more complex.
- Install the Arduino IDE and add the USB Host Shield Library 2.0 through the library manager
- Select Tools, then Board, then Arduino Leonardo, and pick the port the board appears on
- Upload the library's USB host board diagnostic example and open the serial monitor, which should report the controller as present and initialised
- Upload the library's HID mouse example, plug a wired mouse into the shield, and confirm that movement and clicks print to the serial monitor
- Only then upload the passthrough firmware your cheat expects, keeping the same board and port
- Note the baud rate at which the sketch opens the serial link, because you will need to enter the same value in the cheat
- Power-cycle the stack after the final upload instead of relying on a soft reset
Why the COM port number keeps changing
On a Leonardo, the serial port is part of the board's USB gadget rather than a separate bridge chip. As a result, the COM number can change when the board resets, and it changes again when the board enters its bootloader during an upload. This is normal on a stack you are reflashing repeatedly. Once you settle on final firmware, find the port in Device Manager and force it to a low single-digit number under Port Settings and Advanced. Then enter that number in the cheat. If you want the control link fully separate from the game PC, take it from a hardware UART with a USB-to-serial adapter instead. The game PC then sees a device that is only a mouse.
What you give up for the lower price
None of these trade-offs is fatal, but each one is something a more expensive device does not ask of you.
| Area | Leonardo + shield | Why it matters |
|---|---|---|
| Assembly | Soldering or jumpering is usually required | The single biggest source of a build that never works, and the hardest to diagnose without a meter |
| Host bandwidth | The MAX3421E is a full-speed host controller | Fine for mice. It is not the board to pick if you want to pass a high-speed device through |
| Processing headroom | An 8-bit microcontroller at 16 MHz | Enough to relay reports. Very little left for smoothing or shaping movement on the device itself |
| Report rate | Constrained by a full-speed device interface | The 1 ms interval floor of full-speed USB applies. A Teensy 4.1's high-speed device port is not limited the same way |
| Descriptor control | Available, but the tooling is rougher | You can change what the game PC sees. It is more work here than on a Teensy and much more than on firmware that clones descriptors for you |
| Support | Community only | When it breaks there is no vendor. The upside is that every part of it is documented by somebody |
Tip
Who should build one
This build suits people who already own a soldering iron, enjoy the process, and treat the device as a project rather than a purchase. If that describes you, it makes a good weekend project, and you will understand the input layer better than anyone who bought a box. If it does not, buy a MAKCU, because spending three evenings on a shield to save the price difference is a bad trade. A half-working input device is also worse than none, because it produces faults that look like cheat bugs.
What to check before you assume it is broken
- The board is a Leonardo or another ATmega32u4 board, not an Uno
- The shield's SPI lines reach the ICSP header, through a connector or through wires
- The library's board diagnostic reports the MAX3421E as present
- A plain wired mouse prints movement in the HID mouse example
- The game PC lists a mouse device when the Leonardo is plugged into it
- The COM number in the cheat matches Device Manager and is a single digit
- The baud rate in the cheat matches the value in the sketch
Common Arduino questions
Can I use an Uno with a host shield instead?
No, because an Uno cannot present itself as a USB mouse: its USB socket is wired to a serial bridge rather than to the main microcontroller. You need a board whose own chip has USB, such as one of the 32u4 boards.
Do I definitely have to solder?
Not if your shield has an ICSP connector on its underside, because then it stacks and works. Most cheap shields do not have one, and in that case you have to isolate three pins and run three wires.
Is this device more detectable than a KMBox?
Nothing here is undetectable, and the real comparison is narrower than people expect. In both cases the movement arrives as real USB HID traffic. A cheap DIY build tends to be weaker in the USB identity it presents if you leave it stock, but that is a configuration choice rather than a result of the price.
Will my wireless mouse dongle work in the shield?
Often yes, because the host controller sees it as a USB HID device. Dongles that present extra vendor interfaces are the usual exception, and onboard configuration software generally stops working through any passthrough.
Why does the COM port keep changing?
Because the serial interface is part of the board's USB gadget, and the board resets during uploads. Once your firmware is final, force a low fixed number in Device Manager.
Sources
Nothing in our checked source list covers the Leonardo, the host shield or the MAX3421E, so the jumpering and upload steps come from building one.
Read next
Still stuck? Open a ticket on Discord
All guides