Ask HN: Advice for creating a USB device linking 2 computers

20 points by WorldDev ↗ HN
I want to build a little device that connects two computers together via usb, and send keystrokes from one to the other.

(I would use it to use a laptop keyboard on a headless computers).

I am looking for an easy solution, it does not have to be the cheapest.

ChatGPT points me to Arduino, but as far as I can see, there's no arduino with 2 usb ports. It also points me to Raspery pi zero, but that's a computer, not a microcontroller, so not sure if it's suitable.

If anyone with experience can give me some pointers, it would be greatly appreciated!

25 comments

[ 3.3 ms ] story [ 46.8 ms ] thread
Get two microcontrollers with USBD peripheral and connect them using SPI or UART. Write two firmwares for these microcontrollers. Probably two Raspberry Pi Picos would be the easiest way to implement that project.

You also might want to use optical isolators between these microcontrollers, instead of wiring them directly. Just connecting grounds might be wrong, because different computers might have different grounds.

There are ST Micro parts with two USB ports that can can both be devices. I'm not sure the implications of powering them both at once. Look at STM32F407/417.

It might be simpler to get 2 microcontrollers and establish a communication link between them. Something like Arduino (Nano or even smaller third party boards), or Teensy would be suitable for this kind of setup.

Raspberry Pi definitely works! I have a project you can take a look at; you'll have to modify it slightly since you want a keyboard rather than a joystick, but they're both HID so the majority of it should work pretty much out of the box: https://github.com/saulrh/composite-joystick.
Most keyboards run on standard ARM chips and firmware is a mini OS. Check out one of open source keyboard firmwares and you can adapt related code to run on your laptop and pretend to be keyboard over USB port. If you run Linux on laptop you maybe don't even need separate device.
I believe the search keyword for what you're looking for is probably "IP KVM".
It sounds like you might want a device like a Bash Bunny or Rubber Ducky?
Intuitively, connecting two computers over USB seems like it should be easy.

The reason it is not simple is USB is asymmetric. There’s one host and multiple clients. And computers are approximately always built as hosts.

But if you are going to add hardware, a pair of usb network adapters (wired (or wireless)) has the same architecture.

And you won’t have custom software below the application layer. Good luck.

Would a KVM switch do what you need? Or virtualizing the second machine's usb port in some way? Is there any kind of existing IPMI/ILO/etc functionality in the target machine that you could use?

If not: You need something that can act as a usb "device" (the "host" and "device" sides of a usb connection are very different). A search for "usb keyboard emulator" turns up a lot of projects in that area. I'm not sure you're going to get much simpler than a pi-zero or teensy, unless you can find someone selling a pre built device that meets your needs.

If you're lucky, your laptop has a usb port that can be configured to take the "device" role instead of the usual "host" role. In that case you could probably build a software-only solution using the Linux usb "gadget" framework to make that port act like a keyboard when attached to the target's usb port.

Two USB to serial converters and a null modem. Why make it hard?
I don't think you can tackle this purely from a hardware side. If you want to send input from the laptop to another system, there's no kind of USB profile available to collect input from a system.

You're going to need software on the laptop to gather the input. That seems necessary. You're not going to invent a purely hardware based solution here.

Given that, I'd abandon your starting requirement of needing two usb device ports. That doesn't seem to help you out here, doesn't actually buy you much.

I'd look at the field of existing software out there that can ship input between systems. Use ethernet, wifi, or BT for connectivity if possible (perhaps via usb-ethernet adapters which are very cheap!), and if absolutely required you can build a little rpi-zero with a usb-gadget to act like a virtual keyboard. https://github.com/input-leap/input-leap https://github.com/feschber/lan-mouse https://github.com/lkundrak/btkbdd

The destination computer reads a file (of keystrokes) on a USB at a mount point, like every few seconds. The source computer writes to the same file.

After each newline, you are the "device" in the middle that unplugs the USB from the source computer and plugs it in to the destination computer.

Now we want to automate the middle, but without networking. How to do that?

See also Logitech Flow keyboard (and mouse). After each batch of commands, communicate via the shared clipboard.

> but as far as I can see, there's no arduino with 2 usb ports.

2 arduinos with a serial link between them.

You could do this with a couple of TI MSP-EXP430F5529LP boards (<$16 each from Digikey). They include demo code with HID features. I've used this platform extensively, but I never used the USB features for anything other than a JTAG interface for development. I once recommended it to a friend with no embedded development experience, and he had his own custom "mouse jiggler" up and working in one day.

https://www.digikey.com/en/products/detail/texas-instruments...

Alternatively, the newer ESP32-S3 boards (<$6 each) have dual USB-C interfaces, so you could do it with only one (smaller) card instead of two. Development might take longer though.

https://www.amazon.com/dp/B0CN4789XC

If you want to allow a network connection between the two computers, you could load soft-KVM software on each, and go from there.

https://goinglinux.com/open-source-cross-platform-kvm-softwa...

You can use two arduinos and connect them in such a way they are talking through the GPIO ports to each other.

You could do something similar with a couple of Raspberry Pi's or RPI nanos. It doesn't really matter as both can be configured as USB devices and to access their GPIO ports.

The trick is getting them to act as a USB device and then to have them send data over the GPIO ports.

Fortunately I don't think either of those should be super hard.

Get two FTDI FT232RL chips, connect them together on serial side (RXD->TXD, TXD->RXD, GND<->GND). Plug into USB ports of your computers, run terminals (or any other software that supports serial I/O), send/receive data. Can use XYZModem to send files, PPP for TCP/IP networking, etc. No programming involved. Cheap as hell.
Are there any options to connect more than 2 computers via USB using hub topology?
Thanks for the idea. I think it's a great one, but I have a few concerns:

1) The two computers are on 2 different grounds, so I believe it could damage the computers. So I would like to isolate the ground somehow, I am not sure what the options are. I tried to look for opto-isolated options, but didn't really find something clear. Do you have any suggestion?

2) This specific chip is marked NRND (not recommended for new designs) on ftdi's website, So it feels slightly wrong to use it?

> I want to build a little device that connects two computers together via usb, and send keystrokes from one to the other.

> (I would use it to use a laptop keyboard on a headless computers).

Are you sure you need such a device? If this is to occasionally manage that headless system, wouldn’t a Remote Desktop connection work fine?

You’re mentioning a Mac Mini and a MacBook elsewhere, so https://support.apple.com/en-gb/guide/remote-desktop/apdf49e... might be sufficient for your needs.

Neat project, regardless of some of the opinions of practicality.

What you want to do is make sure your client device is an HID device, so that it's recognized as a keyboard. I think something like this will do: https://makerspot.com/cp2110-usb-hid-to-uart-serial-adapter/

For the server side, you'll either want a USB to serial adapter with a microcontroller in between, or one of the RP2040 Raspberry pis as it can be both those at once. https://www.waveshare.com/rp2040-zero.htm

Actually you can probably do it with two RP2040s (or maybe just one) as their USB ports I believe can be configured for different roles.

Good luck, and share your results!