USB HID Keyboard
Turn your Raspberry Pi into a USB keyboard — decoded Morse code is typed as real keystrokes on any computer.
HID Setup
Morse-Pi can turn your Raspberry Pi into a USB keyboard. When connected to any computer via USB, the Pi appears as a standard HID keyboard device and sends real keystrokes. This works with both the Python and Rust backends.
Requirements
- Pi Zero, Zero W, Zero 2 W, or Pi 4 (must have USB OTG support)
- Connect via the USB data port:
- Pi Zero: the port labeled "USB" (not "PWR")
- Pi 4: USB-C port
- A USB data cable — some cheap cables are power-only and won't work
What the installer configures
- Adds
dtoverlay=dwc2to/boot/config.txt(or/boot/firmware/config.txt) - Loads
dwc2andlibcompositekernel modules via/etc/modules - Creates a gadget setup script at
/usr/local/bin/morse-pi-hid-setup.sh - Creates
morse-pi-hid.serviceto run the gadget setup on boot - Creates a udev rule (
/etc/udev/rules.d/99-morse-pi-hid.rules) so/dev/hidg0is writable by all users
⚠ Reboot required
USB HID keyboard mode requires a reboot after first installation to activate the kernel modules. Run sudo reboot after the installer finishes.
Using HID Mode
- Connect the Pi to a computer via USB (data port)
- The computer recognizes it as "Morse Code Keyboard"
- Open the Morse-Pi web UI → KB tab
- Click Enable
- Open a text editor on the computer
- Key Morse code — decoded characters appear in the text editor
Two modes
| Mode | Behavior |
|---|---|
| Letters | Each decoded Morse character (A–Z, 0–9, punctuation, space) is sent as the corresponding keystroke. |
| Custom | Each dot/dash paddle press immediately sends a configured key (default Z/X). No decoding — raw key mapping for use with Morse practice websites. |
ℹ Custom mode keys
You can change which keys are sent for dot and dash in CONFIG → KB Dot Key / KB Dash Key. Defaults are Z for dot and X for dash.
HID Troubleshooting
/dev/hidg0 doesn't exist
- Reboot after installation:
sudo reboot - Check if modules are loaded:
lsmod | grep dwc2 - Check kernel messages:
dmesg | grep -i usb - Verify the HID service:
sudo systemctl status morse-pi-hid
g_ether conflict (most common cause)
The Pi Zero has only one USB controller (UDC). If g_ether (USB Ethernet for SSH-over-USB) loads first, it monopolises the UDC and blocks the HID gadget. Check with:
lsmod | grep g_ether
dmesg | grep -i "UDC.*busy"
To fix immediately (note: this will disconnect USB SSH):
# Unload g_ether
sudo rmmod g_ether usb_f_ecm usb_f_rndis u_ether 2>/dev/null
# Re-bind the HID gadget
echo "20980000.usb" | sudo tee /sys/kernel/config/usb_gadget/morse-pi-keyboard/UDC
# Verify
ls /dev/hidg0
To fix permanently (recommended — the installer does this automatically):
# Blacklist g_ether so it never loads
echo "blacklist g_ether" | sudo tee /etc/modprobe.d/morse-pi-no-gadget-conflict.conf
# Remove from cmdline.txt if present
sudo sed -i 's/,g_ether//g; s/g_ether,//g' /boot/firmware/cmdline.txt
# Remove from /etc/modules if present
sudo sed -i '/^g_ether/d' /etc/modules
# Reboot
sudo reboot
⚠ WiFi required
Disabling g_ether removes USB-over-Ethernet networking. Make sure you have WiFi SSH configured before blacklisting, or you'll lose remote access to the Pi.
Computer doesn't recognize the keyboard
- Use the data port, not the power-only port
- Try a different USB cable (some are power-only)
- Check Pi USB messages:
dmesg | grep -i gadget
Wrong characters being typed
- HID scan codes assume a US keyboard layout
- If your computer has a different keyboard layout, some characters may map differently
"Permission denied" writing to /dev/hidg0
- Fix permissions:
sudo chmod 666 /dev/hidg0 - The udev rule should handle this automatically — run
sudo udevadm trigger - Verify rule exists:
cat /etc/udev/rules.d/99-morse-pi-hid.rules
Manual HID setup
If the installer didn't configure HID, or you need to redo it manually:
# Enable dwc2 overlay
echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
# Add kernel modules
echo "dwc2" | sudo tee -a /etc/modules
echo "libcomposite" | sudo tee -a /etc/modules
# Reboot
sudo reboot