AndroidとRubyを使ってURLを叩くと光る置物を作る

[Wantedly Advent Calendar 2015](http://qiita.com/advent-calendar/2015/wantedly) 5日目です

# こんなもの作ります
まず今回作るものについて説明します。私が自分で欲しいと思っていたもので、技術的にも実装できるのがわかっているので作ります。DIYです。

## 何を作るのか
Webサービスで特定のURLを叩くと光る置物を作ります。

## 何故作るのか
CIが終わると、終わったことを教えてくれるものがあると嬉しいと考えていました。Slackやメールで通知はできるけどイマイチ面白みに欠けるので、何か物理的に知らせるものが欲しいと思っていたからです。

## どのようにして作るのか
難しいことはやりません。使える出来合いのものを組み合わせて作ります。

光らせる部分にはフルカラーLEDを使います。LEDの制御はArduinoを使います。ArduinoとAndroidの接続はADK(Accessory Development Kit)を使います。CIが直接叩くWeb側のサービスはRuby on RailsをHeroku上で動かします。Web側のサービスからAndroidへの通知はGCM(Google Cloud Messaging)を使います。

![WantedlyAdventCalender2015.png](https://qiita-image-store.s3.amazonaws.com/0/55138/d69fb127-d2fd-8b0f-625c-89ff9100a0a0.png)


# Android-Arduino-LEDで光る部分の部品を作る
この部分では次の要素を取り扱います。LEDをArduinoに取り付けるシールドを作る。AndroidとUSB Host ShieldとLEDのシールドを組み立てる。Arduinoのコードを書く。Android側のコードを書く。

## LEDをArduinoに取り付けるシールドを作る
Androidにはハードウェアと接続する仕組みとして、Bluetooth、USB-Host-API、ADKがあります。今回は直接ケーブルで繋ぎたいのでBluetoothは除外します。問題はUSB-Host-APIとADKのどちらを使うかです。どちらもUSBケーブルを使いますがどちらがUSBのホストになるかが異なります。USB-Host-APIを使う場合はAndroidがホストに、ADKを使う場合はArduino側がホストになります。
今回は「置物」にしたいので、Androidが電源を供給される側にならなければなりません。そのためにはArduino側がUSBのホストになる必要があります。このため、今回はADKを選択しました。

ArduinoとAndroidをADKで接続するためのハードウェアはArduino ADKを使うか、Arduino Uno等とUSB Host Shieldを使います。今回は手元にあったのもあって、Arduino UnoとUSB Host Shieldにしました。
LEDのシールドを作るのにLEDをシールド用の基盤に取り付けます。フルカラーLEDはカソードコモンのものを使います。カソードをArduinoのGNDに、RGBのRをD3ピンに、GをD5ピンに、BをD6ピンに繋ぎます。D3,D5,D6ピンはいずれもPWM（擬似的にアナログの様に出力できる）対応のピンです。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/52452daf-b6d7-9b92-2077-3a7b47fcc848.png)

## AndroidとUSB Host ShieldとLEDのシールドを組み立てる
ここではArduinoとUSB Host ShieldとLEDのシールドを組み立て、制御できるようにします。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/85959cc2-d155-a813-a71d-9e7d84071017.png)

左から順に、LEDのシールド、USB Host Shield、Arduino UNOです。重ねてAndroidと接続すると次の画像のようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/d8428763-3695-88cb-f12b-7ff5df873f1b.png)

見えているケーブルの片方がAndroidに、もう片方が電源に繋がっています。


## Arduinoのコードを書く
Arduinoのコードは特に難しいことはしません。Android側から受け取った命令に合わせてRGBの値を変化させるだけです。
なお以下のソースコードを動かすには別途ADKのライブラリが必要です。ADKのライブラリはオフィシャルのものもあるのですが、今回は細かくメンテされているYaoadkというライブラリを使用します。

ソースコード
- https://github.com/cattaka/GcmAdkAlertAndroid/tree/master/arduino/GcmAdkAlert
外部ライブラリ
- https://github.com/ADKstudyGroupTokyo/Yaoadk


## Android側のコードを書く
Android側のコードで必要なものは主に２つあります。ADK経由でArduinoに接続するというところと、GCMのトークンを取得するというところです。

- ソースコード
 - https://github.com/cattaka/GcmAdkAlertAndroid

- 参考サイト
 - http://developer.android.com/intl/ja/tools/adk/adk.html
 - https://developers.google.com/cloud-messaging/android/start

いきなり全部書いても良いのですが、全部作ってから全部を動作確認するのは大変です。
一旦ADK経由でArduinoに搭載したLEDを光らせ、動作確認できるだけのコードを書きます。
RGBそれぞれのSeekBarとボタンを押すと光るという簡素なものです。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/c525190c-6571-3706-ee7b-c12d562a1295.png)

ここまでできれば次はGCMのトークンを取得するコードを作ります。詳しくは参考サイトを御覧ください。

なおGCMのトークンを後述のRuby on Railsで動くサービスに送る作業が必要なのですが、
このソースコードでは行っておらず、手でトークンをコピペする必要があります。


# Webフック用のURLとGCMへ送信を行うサービスを作る
目的のことは「特定のURLを叩く」と「GCMサーバーにリクエストを投げる」です。今回のサービスはRuby on Railsで動き、Heroku上で動かすことを想定して作りました。別にSpringでもSAStrutsでもSlim3でもGoogle App EngineでもAWSでも良いのですが取り合えずそれらにしました。

- ソースコード
 - https://github.com/cattaka/GcmAdkAlertRails
- 参考サイト
 - https://developers.google.com/cloud-messaging/http

とりあえず必要なデータ構造が組み立てられたら良いのでrails g scaffoldで適当に作っています。認証は全く無いと流石にあれなのでAdvise Gemを使って実装しています。

Android側にメッセージを送るには参考サイトの通り、次のURLにHTTPリクエストを送れば送信できます。

> https://gcm-http.googleapis.com/gcm/send

出来上がった画面はこんな感じです。手抜きです。
Webフックとして外部から叩くとき用のキーと、登録されているデバイスの一覧と、コマンドが表示されて、編集することができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/e4388992-b060-e67d-e75c-a1f414b0ab09.png)

最終的には外部から

> https://gcmadkalert.herokuapp.com/exec?cmd=blink_green&key=h87oXXXXXXXXX

を叩くとGCMのサーバーにリクエストが送られ、Androidにもメッセージが届きます。


# 外装を作る

今のままでも光るには光るのですがLEDだけでは味気ないです。なので外装を作ります。外装にはシンクマのフィギュアを作って光らそうと思います。

シンクマを知らない人にシンクマの紹介をしますと、Wantedlyのメッセンジャーサービスである[Sync](https://www.wantedly.com/sync)のマスコットキャラクターです。ちゃんと[プロフィール](https://www.wantedly.com/users/17867033)もあります。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/0730d076-a9d0-9abd-a572-320267e61f80.png)

まずシンクマの画像からBlenderを使って3Dモデルに起こします。このときに3Dプリントデータに変換できるように、穴のない、ちゃんと閉じた立体にすることが大事です。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/f240d0c0-e3d3-13d9-4dec-2ee50e5834ea.png)

作った3Dモデルを3Dプリント用のデータに変換します。私が持っている3Dプリンターはホットプロシード社のBlade-1で、Kisslicerというツールを使って変換します。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/c204f2db-84c0-365a-1659-4f3aa527d7e3.png)

このデータで3Dプリンターで印刷すると次の写真のようになります（左は進捗さんフィギュア）。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/fb694395-5e6d-e40a-99ad-1a2ffad5abb9.png)

3Dプリンターで印刷したままでは不透明なので、このままではLEDで光らせることはできません。なのでシリコンゴムで型を取り、透明なレジンでキャストします。まずは型を取るために型取り用の箱の中にいれます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/f478d80c-1a82-fcdc-ed0a-bf71d096db16.png)

次にシリコンゴムを流し込み、固まるまで数時間待ちます。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/d0b02599-98d5-1111-4c4e-927158fed765.png)

出来上がったシリコンゴムの型はこんな感じです。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/3c308f38-b880-2b76-60f5-d6b9347ddf7e.png)

このシリコンゴムにレジンを流し込み固めます。写真では白と透明の２種類がありますが、どちらも２液式ウレタン樹脂で比較的容易に手に入るものです。２液式のウレタン樹脂は混ぜると十数分で固まって離型できるのでたくさん作るときにも便利です。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/a59610a0-6371-4d10-c700-a6a724c63475.png)

白と透明のシンクマフィギュアができました。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/01fab7b2-63a0-716b-c0b2-68212d3308df.png)

この透明のシンクマフィギュアを前述のLEDを載せたArduinoの上に乗せます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/ac35717c-01ed-1230-f66f-252353627449.png)

箱については手頃な素材がなかったため、ダンボールを使います。ダンボールで包み、上にフィギュアを乗せます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55138/81fd4681-71dd-8e37-db73-58676997fcf5.png)

これで外装は完成です。

# 出来上がったもの
次のようなURLで、Webサービス側で登録したコマンドとキーをリクエストを投げると光るようになりました。

> https://gcmadkalert.herokuapp.com/exec?cmd=blink_green&key=h87oXXXXXXXXX

赤く光ります。ビルド失敗のときに使えそうです
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/8f7d1415-9bba-5ab1-67c0-0efc3765af1f.png)

緑に光ります。ビルド成功のときに使えそうです
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/fb1478c5-7b0e-8edd-95b1-a8c0a6998839.png)

青くも光ります。
![image](https://qiita-image-store.s3.amazonaws.com/0/55138/4e74c6ac-f7af-4279-2787-3d0be59edfe7.png)

# まとめ

今回はURLを叩くと光る置物を作りました。特に今回作ったものはポーリングではなく、GCMを使って、インターネットからの指示で動作するというところが特徴的だったと思います。
IoTやWoTといった形でインターネットに接続する「もの」は今後増えていくと思います。そのための技術基盤やインフラもどんどん整備されていくと思います。ハードウェアの敷居が下がりソフトウェアと同じように組み立てられる時代が来ると思っています。
ソフトウェアエンジニアもハードウェアの世界に踏み入れるべき、とか、たいそれたことをいうつもりではありませんが、単純に作るのが面白いので今後もこの手のものに手を出していきたいと思います。