littleBits MAKEY MAKEYモジュールをNode-REDで読み取る

littleBits MAKEY MAKEYモジュールをNode-REDで読み取ることをやってみたくて試してみます。

# 背景

以前、このような<a href="https://liginc.co.jp/203593" target="_blank">気軽にIoTのプロトタイプを作れるlittleBitsのMAKEY MAKEYモジュールを使ってみた</a>ネタを作ったときに思ったのは接続した時点で右キー・左キー・クリック or  スペースをキーボードマウスデバイスとして割り当ててくれるため、むしろ割り込みにくく捉えにくい。

たとえば、ブラウザにマウスを載せて、JavaScriptでキーイベントとクリックを取る方法も、その時考えましたが、プレゼン時のちょっとした衝撃でマウスがズレる可能性があって断念した経緯もあります。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/b0bf51b6-e4ec-f2d5-84a8-887547d2b6c0.png)

ということで、さらに何を押されたかを丁寧に伝えるとなると、Arduinoモジュールを噛ませてPCに伝達しないといけないため、ちょっと冗長になるのが、そろそろどうにかしたいと思っておりました。

# 今回の実験ができると

littleBits MAKEY MAKEYモジュールをNode-REDで読み取る今回の実験ができると、そのあたりの割り込みがしやすくなり、かつ他のネットワークな通信にすぐつなげることができるので、MakeyMakeyのたのしいフィジカルな情報をすぐにコンテンツに反映することができます。

# 今回の構成

Raspberry Pi3にMAKEY MAKEYモジュールをくっつけた状態で行います。

![image_20161201_161545_7.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/b1b03adc-7d3e-1a9a-fc3b-0605b6fb2893.jpeg)

# ライブラリ候補

* <a href="http://flows.nodered.org/node/node-red-node-makeymakey" target="_blank">node-red-node-makeymakey</a>
    * 名前のとおりMAKEY MAKEYを扱うとうたっているライブラリ
* <a href="http://flows.nodered.org/node/node-red-contrib-usbhid" target="_blank">node-red-contrib-usbhid</a>
    * USB HIDというキーボードやマウスを扱うデバイスと直接会話してやりとりするライブラリ
    * <a href="http://www.itf.co.jp/tech/road-to-usb-master/hid_class" target="_blank">HID (Human Interface Device) クラスについて | インターフェイス株式会社</a>

# やってみる

## node-red-node-makeymakey

早速インストールしてみました。入力系をいじる場合はrootで動かす必要があるので、suでroot権限で活動します。

```bash
sudo su -
```

フォルダ移動します。

```
cd ~/.node-red
```

rootの場合、```/root/.node-red``` ということですね。インストールします。

```
npm i node-red-node-makeymakey
```

起動。root権限で行っているのでsudoはいらないかもしれませんが、suしてないときにハマるといけないので、ひとまず。

```
sudo node-red
```

無事入りまして、advancedに入りました。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/c55adfae-8c45-0da4-0d19-84841349a6b5.png)

実際に置いてみます。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/712513c6-7d0d-4005-1f3a-514fc6e4ce0d.png)

設定も特になく書き出してみたところ、そもそも基礎のライブラリである、node-hidまわりで呼べないメソッドでエラーを起こしているので、メンテされていなさがうかがえます :cry: 

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/b18e8016-229c-82db-3186-54da8dcf002a.png)

中身をこまごま直してみて解決できそうだったのですが、このままだと「littleBits MAKEYMAKEYモジュールをNode-REDで読み取るためにノードを作り直した話」になるので断念。またの機会に。

## node-red-contrib-usbhid

こちらはすんなり入りました。最初方こちらにすればよかった・・・。

node-red-node-makeymakeyと同様にroot作業。

```bash
sudo su -
```

フォルダ移動します。

```
cd ~/.node-red
```

インストール。

```
npm i node-red-contrib-usbhid
```

起動。

```
sudo node-red
```

無事、リストに登場しました。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/61773802-b5ab-7837-9888-5aa4b780eb5d.png)

以下のようにフローを設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/359f5d9a-6103-0596-24c3-493887967879.png)

### :pencil2: HIDdeviceノードの設定

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/22633ef2-a39c-1d8f-14b3-17a666cde883.png)

HIDノードはMakeyMakeyIDを指定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/a8a45bb3-4d63-b3d6-a60d-6268f8d833e5.png)

編集ボタンで生成。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/c82a113e-de61-06e6-8ba4-8d4d2ac42c0d.png)

VIDに0x1b4f、PIDに0x2b75を指定します。

なぜ、この固有IDがわかったのかというとnode-red-node-makeymakeyのソースコードを読んでいたら分かったことなので、バグ取りは決して無駄にならなかったということでしょう。

### :pencil2: makeymakey convert functionの設定

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/8963defb-f2f5-488f-878f-4a1823155ef9.png)

HIDdeviceノードから来た値に応じてLEFT、RIGHT、CLICK、SPACEを割り当てます。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/269fb773-c7ca-0870-f19f-ba9c153e41ec.png)


```js
// Bufferを文字列化
var buffer = msg.payload.toString('hex', 0, msg.payload.length);
// 判定
if( buffer == "020000500000000000"){
    msg.payload = "LEFT"
} else if( buffer == "0200002c0000000000"){
    msg.payload = "SPACE"
} else if( buffer == "0200004f0000000000"){
    msg.payload = "RIGHT"
} else if( buffer == "0101000000"){
    msg.payload = "CLICK"
} else {
    // それ以外は後発フローを発生させない
    msg = null;
}
return msg;
```

# 実験

debugフローも設置したので実験をしてみます。

![image_20161201_165655_30.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/9fa29bbf-6a32-ba37-7774-ebb2d0b5f96e.jpeg)

MAKEY MAKEYモジュールにワニクリップをつけて操作してみます。いまはレバーをclickにしているますが、実際に操作してみると、

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/e4a4f8aa-d3f2-62e4-9ede-6e8ec1a7f617.png)

うまく取得することができました。spaceにツマミを倒してみても

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/6aea0b69-f565-1fa8-1464-772fdd4c8bfb.png)

ちゃんと取得することができます！

# 今回のフロー

今回のフローも置いておきます。

```
[{"id":"1118ad97.f48bc2","type":"HIDConfig","z":"f8e06b65.260988","vid":"0x1b4f","pid":"0x2b75","name":""},{"id":"c6aec4e6.b7eb28","type":"debug","z":"f8e06b65.260988","name":"","active":true,"console":"false","complete":"false","x":930,"y":444,"wires":[]},{"id":"d31fba38.fe0848","type":"function","z":"f8e06b65.260988","name":"makeymakey convert","func":"// Bufferを文字列化\nvar buffer = msg.payload.toString('hex', 0, msg.payload.length);\n// 判定\nif( buffer == \"020000500000000000\"){\n    msg.payload = \"LEFT\"\n} else if( buffer == \"0200002c0000000000\"){\n    msg.payload = \"SPACE\"\n} else if( buffer == \"0200004f0000000000\"){\n    msg.payload = \"RIGHT\"\n} else if( buffer == \"0101000000\"){\n    msg.payload = \"CLICK\"\n} else {\n    // それ以外は後発フローを発生させない\n    msg = null;\n}\nreturn msg;","outputs":1,"noerr":0,"x":664,"y":503,"wires":[["c6aec4e6.b7eb28"]]},{"id":"2b60d701.d33e58","type":"HIDdevice","z":"f8e06b65.260988","connection":"1118ad97.f48bc2","name":"","x":407,"y":436,"wires":[["d31fba38.fe0848"],[]]}]
```

# 参考文献

* <a href="http://shmztkyk.hatenablog.com/entry/2013/11/12/165457" target="_blank">Bufferクラスから16進数の文字列を取り出す - dev.log</a>