Help us understand the problem. What is going on with this article?

RaspberryPiをUSBHIDデバイスとして使う

More than 1 year has passed since last update.

概要

RaspberryPiをPCやタブレットにつないでUSBマウスやUSBキーボードとして振る舞うようにします。
日本語の情報が少なくて苦労したので、備忘録もかねてこちらに手順をまとめます。

使うもの

RapberryPi Zero/ Zero W/ A/ A+
※ 3/2/B/B+のようにUSBの口が複数あるものは使用できません。ほかの用途で有効に活用しましょう。

準備

まずはファームウェアのアップデート。

sudo rpi-update

※2017-07-05-raspbian-jessieを使ったところ、ファームウェアのアップデートをしないと動作しなかった。
終わったらrebootします。
続いてカーネルその他のアップデート。

sudo apt-get update
sudo apt-get upgrade

終わったらまたrebootしておきましょう。

まずキーボードとして認識させる

HID化のコードを以下のgithubリポジトリから持ってきます。
https://github.com/aidantwoods/RPi0w-keyboard

setupOTGを実行(最初の一回だけ)

setupOTG.sh
#!/bin/bash

# See https://gist.github.com/gbaman/50b6cca61dd1c3f88f41 for more info

echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
echo "dwc2" | sudo tee -a /etc/modules

hid.shを実行

hid.sh
#!/bin/bash
modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "deadbeef01234567890" > strings/0x409/serialnumber
echo "example.com" > strings/0x409/manufacturer
echo "Generic USB Keyboard" > strings/0x409/product
N="usb0"
mkdir -p functions/hid.$N
echo 1 > functions/hid.$N/protocol
echo 1 > functions/hid.$N/subclass
echo 8 > functions/hid.$N/report_length
echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.$N/report_desc
C=1
mkdir -p configs/c.$C/strings/0x409
echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
echo 250 > configs/c.$C/MaxPower
ln -s functions/hid.$N configs/c.$C/
# End functions
ls /sys/class/udc > UDC

このスクリプトを実行したときに
/dev/hidg0
が存在すればok

起動時に実行したければ/etc/rc.localに追記します。

PCと接続

PCと接続します。給電用でないほうのUSBコネクタをPCと接続します。
Wi-FiドングルなどのUSB機器が使えなくなってしまうので、ほかにSSHなどができる手段を用意しましょう。
RaspberryPi Zero WならばWi-Fi経由でSSH接続ができるので簡単です。

キーボード入力

キーボード入力を試します。
実際のキーボードと同じで、キーを押す動作をした場合は離すまで押されっぱなしなので、受け側のPCには注意が必要です。
テキストエディタとかを開いておくとよいと思います。

sudo echo -ne "\0\0\x4\0\0\0\0\0" > /dev/hidg0 #aのキーを押す
sudo echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0 #すべてのキーを離す

文章を打つ時などいちいち打つのは面倒です。
こちらを利用します。
https://github.com/girst/hardpass-sendHID

git clone https://github.com/girst/hardpass-sendHID
cd hardpass-sendHID
make
echo -n "hello world!" | sudo ./scan /dev/hidg0 1 2

こうすると簡単に文字列を打ち込むことができます。

マウスにする

先ほどのhid.shの中のレポートディスクリプタを変更すればマウスやジョイスティックとして認識させることができます。

hid.sh
#!/bin/bash
modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "deadbeef01234567890" > strings/0x409/serialnumber
echo "example.com" > strings/0x409/manufacturer
echo "Generic USB Keyboard" > strings/0x409/product
N="usb0"
mkdir -p functions/hid.$N
echo 1 > functions/hid.$N/protocol
echo 1 > functions/hid.$N/subclass
echo 8 > functions/hid.$N/report_length
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0 > functions/hid.usb0/report_desc
C=1
mkdir -p configs/c.$C/strings/0x409
echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
echo 250 > configs/c.$C/MaxPower
ln -s functions/hid.$N configs/c.$C/
# End functions
ls /sys/class/udc > UDC
sudo echo -ne "\0\x10\0" > /dev/hidg0 #x軸方向に移動
sudo echo -ne "\0\0\x10" > /dev/hidg0 #y軸方向に移動
sudo echo -ne "\x1\0\0" > /dev/hidg0 #左クリック
sudo echo -ne "\0\0\0" > /dev/hidg0 #はなす

クリックはキーボードと同じように一回書くと明示的に離すまでそのままですが、
カーソルの移動は変化があったときのみ送信されます。

レポートディスクリプタについて詳しく知りたければこちらのHIDの仕様書を読むといろいろなものが作れます。
マウスホイールとかを追加するのもいいですね。
時間があればレポートディスクリプタの書き方について書こうと思います。

応用例

こちらを使ってROHM OPEN HACK CHALLENGE 2017に作品を提出しました。
team I.N.U.P.Y名義でROHMのセンサメダルの加速度情報を使って足で自在にPCやタブレットを操作できる靴を開発しました。
優秀賞をいただきました。(^^)/
Raspberry Pi Zero Wの場合、USBが使えなくてもBluetoothやWi-Fiで他の機器と接続ができるので、
このように他の機器から無線で受け取った情報をもとにマウス操作やキー入力をすることが可能です。

参考にしたもの

http://isticktoit.net/?p=1383
https://www.aidanwoods.com/blog/building-a-wifi-enabled-usb-rubber-ducky/
http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
http://esyokunin.dee.cc/30xSub_USB_Siyou/331_Siyou1_HidKb/331_Siyou1_HidKb.html

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした