Have you ever wanted to build your own custom keyboard — not necessarily a full 101+ keyboard, but a small, purpose-built device, or even an interface with no physical keys at all? Imagine a virtual input that accepts commands over Wi-Fi, like simple HTTP REST requests, and turns them into keyboard events on your computer.
It’s easier than you think.
Here’s what got me into this project. I often play RPGs in co-op with a friend, and my computer acts as the server. That gives me a few extra abilities he doesn’t have — like Quick Save (F5) and Quick Load (F8). The problem? Whenever I step away, he’s stuck. He can’t save or reload the game on his own.
So I wanted a simple way for him to trigger just those two keys — F5 and F8 — on my machine, without giving him full remote control. That’s all. Two keys, nothing else.
But once you start thinking about it, the possible use cases expand quickly. You could build a tiny physical keypad where each button types a whole sentence instead of a single character.
\n Or a remote keyboard that works a bit like a simplified KVM-over-IP — just without the video component.
\n Or even a DIY solution for waking a computer over USB keyboard input when the network card doesn’t support Wake-on-LAN.
And of course, HID isn’t just keyboards. It covers mice, gamepads, joysticks — basically anything that counts as a “Human Interface Device”. With the same approach described in this article, you could build any of those.
At first, I tried the software route — wrote a program that listened on a TCP port and injected keystrokes into an active application. It worked… with Notepad, but it didn’t work where it mattered: the game. I tried running as Administrator, fiddled with security profiles, and tested different things, but the simulated keystrokes never reached the game window.
That experience taught me two things. First, sending keystrokes from userland is fragile. Second, it's OS-dependent: different operating systems use different input APIs, and there can be multiple APIs in the same OS, so what works for a simple text editor will not necessarily work for full-screen applications. Finally, a pure software solution can’t handle machines that aren’t booted or are asleep.
So I switched strategies: if software injection is unreliable, let’s speak the computer’s native language. Time to move to a hardware approach.
To make this work, I needed a device that could speak two languages at once: network on one side (Wi-Fi or Ethernet) and USB HID on the other. In other words, something that could receive commands over the network and then act as a USB keyboard when plugged into a computer — essentially a tiny Ethernet/Wi-Fi-to-USB bridge.
My first thought was to use an old Raspberry Pi 1B I had lying around. It had USB, it had Ethernet — seemed perfect. After digging through the docs, I found how to switch its USB controller into device (peripheral) mode. Rebooted… and lost the network entirely.
Which makes total sense in hindsight: on the older Pis, the Ethernet chip is actually connected through USB. Once the USB controller switches from host mode to device mode, it stops handling the Ethernet interface. Newer Raspberry Pi models have multiple USB controllers and can make this work, but it's still a bit fiddly and not guaranteed to behave nicely.
A bit more research pointed me to a much better option: certain ESP32 microcontrollers — specifically the ESP32-S2 and ESP32-S3 — can act as a USB device and use Wi-Fi at the same time. Perfect. The S3 is more powerful and has extra features, but for this project, I didn’t need that horsepower, so I went with the ESP32-S2. The Raspberry Pi RP2040 might also work, but I didn’t test it.
And the cost? Very reasonable. An Adafruit QT Py ESP32-S2 cost me £15.90, including shipping. If you prefer the budget route, you can get a pair of no-name ESP32-S2 boards on Amazon for about £9.99.
The ESP32-S2 chip itself is made by Espressif, but different companies build their own boards around it — adding voltage regulators, USB connectors, buttons, LEDs, etc. And this is where choosing a reputable manufacturer seriously matters.
For your own sanity, consider buying from Adafruit, Seeed Studio, or any other well-known maker.
Two reasons:
Their boards just work. I tried a no-name Amazon board first. Arduino IDE could detect it, but flashing failed every single time — different computers, different operating systems, different cables… nothing helped. I sent it back. The Adafruit board, on the other hand, flashed successfully on the first try.
\
They contribute massively to the community. Great documentation, clear tutorials, tons of libraries, and examples for all kinds of sensors and modules. All open, all high quality. Those extra few quid directly support the ecosystem you’re relying on.
And as a bonus, the Adafruit board comes with a tiny programmable RGB LED — super handy for showing status while the firmware runs.
Programming these boards is pleasantly straightforward. There’s no operating system, no filesystem, no threads, no asyncio — just your code running directly on the microcontroller.
The program is essentially split into two parts:
Thanks to the community — especially contributors like Adafruit — you don’t have to implement low-level networking, Wi-Fi drivers, USB HID descriptors, or USB protocol handling yourself. Libraries take care of all of that. You only need to focus on the logic: how the HTTP command is encoded (I used part of the URL) and which keystrokes the board should send over USB.
The full source code is available on GitHub. Just install the Arduino IDE, clone the repository, drop your Wi-Fi credentials into the `wifi_defs.h`` file, plug in your board, and click “Upload.” A minute later, you’ll have your custom keyboard ready to go.
At the top of the code file, you’ll find a few configuration options — you can disable the Adafruit NeoPixel LED if your board doesn’t have one, change the HTTP port, or temporarily turn off the USB HID functionality (useful when debugging the HTTP handling).
As you can see, building your own remotely controlled USB keyboard is not only possible — it’s surprisingly easy and inexpensive. With just a small microcontroller and a bit of code, you can create a custom HID device tailored exactly to your needs, whether that’s a two-button remote for gaming, a macro pad that types full sentences, or something completely different.
The project in this article is just a starting point. You’re welcome to use the code as a foundation, modify it, break it, rebuild it, and push it in whatever direction your imagination takes you. If you end up making your own version — or come up with a fun or unusual use case — I’d love to hear about it. Feel free to share your ideas and projects in the comments.
:::info Disclaimer: I’m not affiliated with any of the companies or organizations mentioned. All hardware was purchased with my own money, and this project was not sponsored in any way.
:::
\


