关于将Raspberry PI Zero模拟为带X/Y轴的HID游戏手柄的可行性咨询
Absolutely feasible! Since you’ve already got your Pi Zero working as an HID keyboard, you’re already familiar with the core USB gadget framework that powers this—gamepad emulation uses the exact same system, you just need to swap out the HID report descriptor to match a game controller’s input structure.
Here’s a breakdown of how to pull this off:
Set up the USB gadget structure
You can either modify your existing keyboard gadget or create a new one (recommended to avoid conflicts). Start by creating a new gadget directory in/sys/kernel/config/usb_gadget/:mkdir -p /sys/kernel/config/usb_gadget/gamepad cd /sys/kernel/config/usb_gadget/gamepadConfigure basic USB device info
Set vendor/product IDs (use generic gamepad values if you don’t have specific ones in mind):echo 0x1234 > idVendor # Example vendor ID echo 0x5678 > idProduct # Example product ID mkdir -p strings/0x409 echo "PiZeroGamepad" > strings/0x409/product echo "YourName" > strings/0x409/manufacturerDefine the HID report descriptor for a gamepad
This is the critical part—it tells the host PC what kind of inputs your device supports. Create afunctions/hid.usb0/report_descfile with a descriptor that includes X/Y axes. Here’s a minimal working example:mkdir -p functions/hid.usb0 echo -ne \\x05\\x01\\x09\\x05\\xa1\\x01\\x09\\x30\\x09\\x31\\x15\\x00\\x26\\xff\\x00\\x75\\x08\\x95\\x02\\x81\\x02\\xc0 > functions/hid.usb0/report_descLet me break this down: it defines a gamepad with two 8-bit axes (X and Y), each ranging from 0 (min) to 255 (max), with 127 being the neutral position.
Bind the gadget and activate it
Link the HID function to a configuration and bind to the USB controller:mkdir -p configs/c.1 ln -s functions/hid.usb0 configs/c.1/ echo "" > UDC # Replace with your USB controller ID if this doesn't work; run `ls /sys/class/udc` to find itTest and control the axes
Once the gadget is active, your PC should detect it as a gamepad. To send axis input, write 2-byte reports to/dev/hidg0:- For example, to set X to neutral (127) and Y to max (255):
echo -ne \\x7f\\xff > /dev/hidg0
You can wrap this logic in a Python or shell script to read input (like from a joystick sensor on the Pi) and map it to the axis values.
- For example, to set X to neutral (127) and Y to max (255):
Make it persistent across reboots
Save your setup commands into a shell script (e.g.,/usr/local/bin/setup_gamepad.sh), make it executable withchmod +x, and add it torc.localor create a systemd service to run it on boot.
A few quick notes:
- Ensure your Pi Zero is in USB OTG mode (you probably already have this set up since you got the keyboard working—double-check that
dtoverlay=dwc2is in/boot/config.txtandmodules-load=dwc2,g_hidisn’t overriding your custom gadget). - If the PC doesn’t recognize the gamepad, double-check your report descriptor—HID syntax is strict, so even a single wrong byte can break detection. You can use offline or local HID descriptor parsers to validate it if needed.
Once everything’s set up, you can test the axis input in Windows’ Game Controller Settings or Linux’s jstest /dev/input/js0 command to confirm it’s working.
内容的提问来源于stack exchange,提问作者Erwin Vorenhout

