Hacker News new | past | comments | ask | show | jobs | submit login
Connect to your Raspberry Pi over USB using gadget mode (howchoo.com)
191 points by xg15 on June 3, 2023 | hide | past | favorite | 81 comments



I've done this, it's super useful. The use case for me was that I wanted to simultaneously use two joysticks with the same game, mixing their inputs together instead of just using one or the other for each axis. The behavior only ended up being possible by writing a "joystick mux" program that would accept input from multiple joysticks, combine it, and then retransmit it as a gadget-mode device.

Side note, USB HID descriptors are a disaster and someone should do something about it. Even commercial devices by reputable manufacturers have broken descriptors. A tool with modern ergo and integration would probably get a surprising amount of traction.

https://github.com/saulrh/composite-joystick


This is awesome! A huge boon to digital artists those interested in HCI research. Also in rust! :)

I also noticed how problematic it is to support even major controllers like the PS4 controller under SDL. Games have to be aware of the exact model of controller that they are attached to. I was thinking you could use a RPi0 and it could "clean" all the device specific issues.

In your case, there is no reason that a FUSE like USB interposer couldn't exist purely in userland, but this is what we have.


I actually prototyped the thing in python the first time around, but performance was too poor to pass through even a single joystick, so Rust it was, lol.

As for software translation, that was out early in the design process: I needed Windows and I did not want to write a Windows device driver or fight with code signing. Nor did I want a Windows-only or Linux-only solution. So the only solution was to control the platform the software ran on (-> raspberry pi), then drop down far enough in the stack that everyone agreed on a protocol (-> USB HID). I would have been very very happy if I could have implemented this at a higher level.


Sorry, I re-read my comment and I wasn't trying to argue against you, just how messed up the OSes are and that everything is basically a stack of hacks, even the "good stuff".

I like that you prototyped it in Python first. I wonder why it didn't work? Python function call overhead?

It would be neat if there was a cross platform USB HID muxing and translation layer that used Wasm for all its logic, then the "fixups" would be portable.


I didn't do a ton of debugging before giving up and switching away from python, but I think that at least some of it was issues with the event loop and cost of serialization introducing latency.

Yeah, I think some of my irritation with the situation bled through there, lol, didn't mean to come off as aggressive. I also lament the absence of a common input standard of some sort. WASM or the like would be a neat common layer; I feel like it's a good target for embedded scripting and module systems these days.


When I used to game cooperatively I always wanted a foot pedal, for push to talk or some defensive action.

But I wonder if games that detect bots would trigger on this.


No way to know for every game, but foot pedals for PTT is definitely a thing for controller players in competitive PVP games. They are often sold as accessibility products.


nifty project, thanks.


Feels like the ubiquity of these kinds of how-tos implies that the Raspberry Pi is an abundant, ready-to-hand device, which hasn't been true for a few years now. But maybe we’ll get there again soon? Seems like I’ve read people being optimistic about rpi sourcing but it also hasn’t really materialized yet.


The number of people I know who have been waiting to buy a Pi and actually get one has gone from about 1 a month to about 2 a week in the past couple months.

It's slow but steady, seeing more in stock notifications from authorized resellers on rpilocator.com, and the stock doesn't deplete for 30 minutes to an hour now, instead of like 5-10 minutes earlier this year.


That's.... progress I guess.


Good to hear. Love all your work!


Would be good if more people called this out. I said something regarding how memory inefficient software is these days and how that makes pi clones difficult to use as a sandbox and someone helpfully responded back about how I should be using some model of RPi for that.

First, I already have devices. Second, people are still waiting in like to get Pi’s and based on the last interview I saw the Raspberry people think the system is working. They don’t want to raise their prices.

I am fairly sure if you have more money to offer your suppliers that scarce components are easier to get ahold of. They could keep their margins the same and raise their rates and generate a lot more revenue.


> Would be good if more people called this out.

You mean as if every rpi adjacent thread doesn't already get filled with these supply issue comments?


> Would be good if more people called this out.

"Call it out"? For what? Do you think the Raspberry folks are just choosing to not make enough? I'm pretty sure they don't like the current situation as much as you don't.


They've chosen to prioritize selling to businesses ordering hundreds of Pis for field-deployed devices, over individual hobbyists ordering single-digit quantities for tinkering and hacking (https://www.youtube.com/watch?v=-_aL9V0JsQQ).


It did seem like something of a bait-and-switch and contrary to the educational mission.

Certainly inconvenient for hobbyists, students and instructors.

It would be better if there were more boards that were hardware and software compatible with the Pi.


They’ve chosen not to raise prices in a parts shortage and are calling it a virtue. Meanwhile the common advice is to buy them off of eBay at elevated prices. Essentially scalping.

You can pay suppliers preferential prices for preferential treatment. That has been Apple’s MO for a decade and a half.

Raise your prices until demand just starts to taper. Use the money to butter up suppliers (place bigger orders, pay cash on delivery, in advance, whatever). Get it done, stop patting yourself on the back for five years running for not being able to keep up with demand.


> They’ve chosen not to raise prices

They did raise prices.

https://www.raspberrypi.com/news/supply-chain-shortages-and-...


> Raspberry people think the system is working

it is for them


Given the continued prevalence of this kind of comment, I think people have missed the recent updates regarding supply chain slowly normalizing until the end of the year (you can now buy Zeros in packs of 10 at some UK a and EU retailers, at non-scalping prices).

Worse, I suspect this will become an urban legend of sorts even when there are no more shortages.


The prices aren’t that bad on eBay etc right now. The pi 4 8gb is around $100. I bought one last week for $98.

Circa $30 over old retail but then they and so much else will never get back there.

Why would it when people will pay the new normal?


I’ve watched this for the past few months and picked up a Zero W and rpi 3 at msrp.

https://rpilocator.com/?


> watched this for the past few months

yeah I got tired of doing that


I saw this article a few days ago, hopefully it is true: https://www.pcworld.com/article/1939160/at-last-the-raspberr...


OKAY. This is a step closer to my dream idea which I feel like should be possible but haven't figured out, and am curious if anyone has done anything like this:

I want to be able to wirelessly change the music on the "USB drive" in my car; i.e. the "drive" is actually an always-on computer, e.g. a Pi.

Change the music from the computer at home and be on my way?


Yup, you can use the usb-gadget mass-storage framework to "plug in" a "block device" which is backed by a file on the computer. You can then "unplug" the device from the usb, and loop-mount it locally to manipulate its contents.

Nota bene, do not mount it two places at the same time!


Here’s the solution I built for that, with a combination of on-device voice control, and a Bluetooth remote: https://github.com/lukifer/voicetunes

Something I’d still like to add is a USB OTG emulation of iOS/Android/iPod/etc, so that the currently playing track shows on the dash, steering wheel controls can be used, etc, but my last experimentation a couple years ago didn’t go anywhere. (All the open source stuff for emulating CarPlay and Android Auto seem to be for the other direction: the dash, not the device.)


This is very cool - but also waaay more complicated than what I'm talking about here.

As in, I'm fine with the SYSTEM that plays music now (I have Toyota Entune) and I don't much want to mess with it.

I literally just want to be able to remotely change the files on the USB drive in the car -- without ever having to take it out of the car; that's it.


If you have a spare Android phone with enough storage, and can configure it to mount as a USB mass storage device, maybe you can install an FTP server/Syncthing client/etc. on it, use that to manage the music remotely, and plug it in to your car so that it can see the library.


I've worked on DriveDroid. There were indeed people who have done this.

Best example of such a use-case was someone who wanted to make an old printing press fetch files its files from the internet. The press only had an interface for floppy disks. He replaced the floppy disk controller with a floppy emulator that exposed an USB port. Connected a phone with DriveDroid. Synced usb image files from the internet to be exposed over usb mass storage. The image files were fat images that hold the printing job files. They were generated by the server automatically. It worked pretty well from what I heard.


Android phones usually don’t mount as actual storage devices. The interface is worded that way but it’s different protocol called MTP.


For many phones it is possible to change the exposed protocol from mtp to mass storage. Mass storage does need an image file with fat filesystem to work on most devices. It nowadays is not possible to expose the phones internal storage.


I don't have much idea about these things but is it possible to make a pi act as a usb drive? Then you can plug-in a wifi-enabled pi in the usb slot of your car which can store your music files and grant you tons of control.


There are some SD-cards with Wifi Modules in them around (Toshiba FlashAir for example). Pop one of those in a USB adapter and you're done.

Similar solutions are also popular in the 3D printing space, look up Fysetc or BTT wifi sd cards.


I use this for my Teslas Dashcam (it was built for it), but it also has a feature to rsync music files from a network share every time it connects to the network and expose it as files on a USB drive to the host. Sounds like it would cover what you want, and it supports RPI Zero Ws natively.

https://github.com/marcone/teslausb


Check this out: https://github.com/oandrew/ipod-gadget

It's a USB gadget kernel module that pretends to be an iPod to stream music to car/etc.


You could get a Toshiba FlashAir sd card, which can be read/write to from wifi. Plug that into a USB sd card adapter & away you go. Discontinued but there are some available about.


These seem to be around $70 used for 16Gb at the moment. Are there any alternative options?


Ebay seems to have better prices. $120 for 64GB. Big investment, not a ton of space, but if this is an mp3 collection that's a huge amount of music.

Pity the market keeps evaporating. Very cool product.


Search for "wifi sd card". There are a million of them


This isn't so much to build on your idea directly, but maybe some additional fodder will help further inspire ideas and yet more food for thought (for myself as well, and better yet, anyone else)..

I recently realized I can use a $15 USB capture card with an HDMI input on the other end to snag the video feed of a Pi or anything else that can output HDMI. As I use Linux, you can tap into the /dev/video<number> device as if it was a camera, using VLC/OBS. (There's also a paid app on Play store that allows me to also do this on my phone as the display side, using OTG. Would love to be able to use my tablet running a de-Googled LineageOS as well, but that'd entail figuring out how to crack/patch out Google's license checking library, and I haven't found any FOSS alternatives, ugh.)

From there, making the (my) dream happen would be if there was some convenient way to use the same device that's tapping into the video out as the keyboard/mouse input, much in the modal way of VMWare/VirtualBox, where it overtakes your input, and using the hotkeys to release when you want to switch back to your tasks on the host.

In particular, I have a Flipper Zero that doesn't get real use beyond novelty functions and have been wondering if that (or something like a ESP32/ESP8266 computer) could help facilitate that. My skillset is nowhere near that close to the metal.

At least, re: your post I'm piggybacking, and coming from knowing the capabilities of the Flipper Zero, I wonder if RubberDucky/BadUSB payloads could bring you any closer to meeting the spirit of your goal. Or, some sort of rsync like mechanism baked into the Pi when it (automatically) connects to a detected, saved network. Or, a RubberDucky/BadUSB payload on-demand to fire off an rsync.


I would also take a look at esp32 and possibly raspberry pi pico W as well.

For the esp32 there is this official example of what I think is faking a usb drive: https://github.com/espressif/arduino-esp32/blob/master/libra...

Not all ESP32s support USB OTG and I don’t have the correct one here atm to test with. Not sure how much more work would be needed to serve files from sd card.

You could then use a web server on the esp32 to transfer your files


There is a mass storage gadget: https://linux-sunxi.org/USB_Gadget/Mass_storage


Perhaps a USB Armory (thumb drive computer) configured to expose a mass storage device with your music. Then push new music files to it over Bluetooth from your phone.


They are crazy expensive now, but this could have been easily done in the past with a Flash Air sd card and a USB adapter.


This works on the Raspberry Pi Zero, and the Raspberry Pi 4. I'm not sure about the Zero 2, but I know the other models lack hardware support for the feature.

You can buy a cool little PCB that attaches to the Zero and gives it a male USB-A port, turning it into a chunky flash drive or whatever. (They're sometimes referred to as a "BadUSB".)


It works on any Pi which has only 1 USB port - except for the power port. So on the various "Model A's" and on the zeros. The reason is, the Pi's SOC actually is natively capable of USB Gadget mode, but only offers 1 USB port, and on the various B models they interpose a hub to offer more ports - but gadget mode stops working due to the hub being in between.

The Pi 4 is an exception - its USB-C power port works in gadget mode too, unlike its normal USB-A ports, which do not, like all other Pis, because of said hub.


So on a raspberry 3A this works over USB-A… but how? Get a female-to-male adapter/cable somehow?


Definitely works on the zero 2. I've built hardware that uses it.


I see keyboard kits built around the Pico. Are they using this technique or something else?


You can also get console access this way, if you use a different "gadget" (g_serial) and set tty to it on kernel command line.

You can also make your own combinations of USB configurations over configfs which is more flexible.


The beagleboard SBC was amazing for how setup it was. I think the stock image had serial. It also presented a network adapter & host a small network. If you connected, it would advertise a webserver, which was a web IDE for programming the device. Incredible out of box experience.


As you seem to know well this thing, I'll ask you: they write type "ssh pi@raspberrypi.local" and voilà !", but I know that just enabling an IP stack over a USB link is not enough per se* normally, the device has to have a network configuration (IP address, netmask, gateway) which usually means DHCP. Moreover, how does the ssh client computer know that "raspberrypi.local" is this device?


Domain names: https://en.wikipedia.org/wiki/Multicast_DNS

Yes, you have to have either some kind of network configuration, and enable the network interface that appears after you pluging in the USB device. It's no different from using USB-ethernet adapters.

The easiest is probably to rely on link local addresses and mDNS if all you need is local access from the computer you connected the device to. On a systemd based Linux distros, mDNS is enabled by default in systemd-resolved daemon. On my distro, there's no default configuration for usb network adapters, so I have to do that part by myself. Other systems may work differently and auto-enable USB interfaces and at least setup link local addresses on them. The device implementig the gadget has to do the same.


Going to toot my own horn a little bit here. I used this capability on this work project: https://github.com/nhsx/il-magic-scanner (long story short: use a pi camera to OCR ID info off a phone screen, then pretend to be a keyboard and "type" it into an attached computer). There's a spun-off standalone daemon at https://github.com/nhsx/il-keebd which handles the "pretend to be a keyboard" bit. It listens on a local socket for text, converts it to scancodes, and squirts them up to the usb host.

The keymap isn't complete by any means, but it's got enough there to be interesting.


One cool and lesser-known fact is that you can enable adb on Raspberry Pi with adbd.

It’s a fairly seamless way to get console/push/pull over USB. Only downside is that it requires the adb tool on the host as well, vs gadget serial/ssh.


I prefer to connect with SSH over bluetooth. https://blog.habets.se/2022/02/SSH-over-Bluetooth-cleanly.ht...


I'm currently trying to do this on my little stack of Pi Zero and Zero 2 boards. I remember at some point this worked great, and then I couldn't get it to work again. So far I'm not having any success. The Pi doesn't show up as a USB device using lsusb on the host. Working my way through a stack of micro-usb cables. Maybe they all are charge only. Anyone have recent success with 64-bit Raspberry Pi OS and Ubuntu on the host end?


I used this mode to defeat some arcade dongle protection. It's very handy.


None of this seems to address power.

maybe the pi zero is ok.

For a pi4 you have to provide power though the usb-c connector and it needs up to 3A.

This is also why implementing pi-kvm is so complicated.


With the zero 2 you can put the power through one port and the USB-OTG connection into the other. It's fine.

I don't actually know if you could power the zero fully through the OTG port, although I wouldn't be that surprised.


You can, I recently did it.

Power on the Zero is connected to the pins, the power USB connector and the OTG USB connector. Afaik, there are no components in-between.


Does a splitter cable exist?


You can buy cables or small splitter pcb's;

https://shop.pimoroni.com/products/usb-c-pwr-splitter?varian...


I don't think it's possible for the pi to also act as a host on its other USB port if you do this, is it?


One of the unfortunate things about the Raspberry Pi Zero is that the second micro usb is power only. For this type of configuration I encourage all to check out the Allwinner ARM-based SoCs and boards built from friendlyelec. With the NanoPi Neo I was able to enable USB ethernet gadget mode on its micro-usb and then have it host and power another device on its USB-A (for me a mobile phone). In my use case the laptop powered both the NanoPi and charging the mobile device all from USB power while also acting a an ethernet packet router from the mobile device back to the laptop all over USB on its own subnet.

https://www.friendlyelec.com/index.php?route=product/product...


I ran out of ports on the usb charger I was using to run my little cluster so I have a couple of the lower power devices daisy chained off of the higher power ones.

It does mean that some devices will power off unexpectedly when others restart but unexpected restarts are something you have to plan for anyway.


Many clones have two usb ports, with one being OTG capable. For example the mango pi mq.


Yeah, anything based on H3/H5 SoCs will work fine for this use case due to the SoCs having 4 separate USB host controllers, one of them muxed with OTG controller. That's a lot of I/O flexibility.


You should be able to do this with a pi 4, since the usb-c power port is also the gadget port. The usb 3.0 ones off the pcie bus on the pi should be completely independent from that and still work (not sure about the 2.0 ports or anything).


Oh, now that's interesting. Not quite the form factor I had in mind, but worth proving an idea or two out on.

Thanks.


Yep, and if that does work for you, then you might be able to get closer to the form factor you want using a CM4. That said you'd have to learn how to design your own board for it and potentially handle the pcie lane. But that would be a much smaller starting footprint with it at least.


FWIW - I was able to do this using a pocketbeagle. We even did this for a small run product where Octavo SIP exposed USB Serial and Ethernet via gadget, and then was a host on the USB1 side.


Seems true unfortunately, though you can at least switching between the modes somewhat convenient: https://forums.raspberrypi.com/viewtopic.php?t=282649


Yeah, not quite what I'm after. I want usb microphone into usb gadget. Bit of a pain that getting audio in takes an extra hat otherwise.


Did this with a uugear mega4 ppps usb switch between two pi zero ws. One can be permanently on, drawing just 0.6watt. It can turn on the second pi zero and connect to it.


Unfortunately there seems to be a bug on Ubuntu 22.04 for Arm that, when you configure the Pi for gadget mode and log in via VNC, X locks after a few minutes. Didn’t do this on 20.04.


Didn't realize that the Pi4 supported gadget mode (Pi3 doesn't.)

Part of it might be that I got tired of dealing with rpilocator just to find a Pi4 at msrp...


If this let's me format USB drives to whatever filesystem & flash ISOs on them then I'm golden with an iPad/Type-c with a decent middleware iOS app


I fried one of my Pis by plugging it into my desktop's front USB port.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: