マイコン不要・スマホからサーボモータを簡単に動かそう【GlueMotor×Swift】

#はじめに

この記事は、[Life is Tech ! アドベントカレンダー2017](https://qiita.com/advent-calendar/2017/lit-mentor) 22日目の記事です.

はじめまして岐阜のiPhoneメンターこと __[ぬっきー](https://watakemi725.github.io/index)__です.
普段は岐阜にあるIAMASという学校に住んでいる大学院生です.
そんな私は１年前に[iPod20台を通信/制御/連携してみた【Max × Swift × OSC】](https://qiita.com/watakemi725/items/b8090c7f09de68516f19)ということでクラブ空間での新しい演出に繋がらないかと
真面目()に取り組んでいました.

大量に光らせることに満足できず、次は大量に動かしたいなと思い、
この一年は大量にサーボモータをiPodから稼働させていました.
![](https://media.giphy.com/media/3o6nV4sEGYBdbSG6ac/giphy.gif "")
ゴム手袋の中にサーボモータ２つを入れて画面を操作する不気味な…

技術的におもろい点としてはArduinoなどのマイコンを一切使わず
iPod端末からサーボモータ２つを制御することができるGlueMotorです.

そんなことがiOS端末からできちゃうん！？
そんな楽しいワクワクを思う存分今年は紹介したいとおもいます


#本記事について
GlueMotorまわりの基礎をおさえ、ハードを自作&自作アプリから制御できるまでが本記事のゴールです.
回路やらSwiftの基礎についてはあまり触れません、ごめんなさい.

* GlueMotorとは
* GlueMotorを自作
* GlueMotorを制御するアプリを実装
* 実践例

#GlueMotorとは
![GlueMotor_Logo.png](https://qiita-image-store.s3.amazonaws.com/0/59590/949602c2-184f-7b06-d904-fccddeb33192.png)

GlueMotorとは、[寺崎和久さん]()によって開発された、端末のイヤホンジャックにプラグを差し込むだけで、サーボモータを制御できてしまう魔法のようなケーブルのことです.

『Arduinoなどのマイコンを一切使わずに老若男女だれでも簡単にモノとモノを糊のようにくっつけることができればいいな』という素敵な想いが込められたんだとか…涙

共立プロダクトさんからは[プチロボS2](http://prod.kyohritsu.com/WR-S2ESi.html)として商品化もされています.

![スクリーンショット 2017-12-22 23.52.38.png](https://qiita-image-store.s3.amazonaws.com/0/59590/82b10442-6c70-2b82-6c00-7d010d1df5e4.png)


このケーブルとセットでstoreに存在するアプリをインストールすることですぐに使い始めることができます.
[GlueMotor2(iOS)](https://itunes.apple.com/us/app/gluemotor2/id662820229?mt=8)
[GlueMotor(iOS)](http://itunes.apple.com/app/id526429691?mt=8)(iOS4の場合)
[GlueMotor(Android)](https://play.google.com/store/apps/details?id=com.ktlaboratory.GlueMotor)

またGlueMotorは米国シリコンバレーの Maker Faire Bay Area にて５年連続の受賞や米国版『Make:』magazine では製作記事も掲載されるほど素晴らしいのです.

そして何より素敵なのが…

__GlueMotorのハードもアプリも自作できてしまうということ！！__

[GlueMotor公式サイト](https://sites.google.com/a/gluemotor.com/wwwj/home)では自作する方法が書かれていて、githubに[アプリのコード](https://github.com/GlueMotor/GlueMotor)も記載されています.
Android,JavaScript,iOSの3つが含まれています.



本記事ではその自作手順を、中高生でもハード初心者でも分かるように + 個人的な知見を含みつつ解説していきたいと思います！


ほな

#GlueMotorを自作してみよう【ハードウェア編】
###原理
まずそのGlueMotor原理についてですが、端末のイヤホンジャックから特定の周波数を発生させサーボモータに伝えることで特定角度の制御をしているということです.
これは偶然にもラジコン用サーボモータの制御信号がオーディオの周波数帯域に当てはまるということだからだそうです.しゅごい.

###必要な物
* [3.5mm ステレオミニプラグ 3極](http://akizukidenshi.com/catalog/g/gC-02401/)
* 電池ボックス
* ケーブル([コネクタ付だと尚良い](http://akizukidenshi.com/catalog/g/gC-09734/))


さて以下が電子回路図です.

![GlueMotorCable_Schematics.png](https://qiita-image-store.s3.amazonaws.com/0/59590/69e29bf5-15fb-b157-2f0d-eb1e1b77d1df.png)
(サイトより引用)
######(※ここで注意しておきたいのがC1,C2のコンデンサーについてですが、基本的にはiOS端末であれば特に必要ありませんが故障などを防ぐためにつけておくとbetterですね)


さぁこれを作ろう！！

回路図初心者向けにはイメージ図を用意したので参考にしてみてください

![gluemotor回路2.jpg](https://qiita-image-store.s3.amazonaws.com/0/59590/08c727ca-db60-6fc1-3413-a335e4385c44.jpeg)




これをあとははんだ付けすればOK

###サーボモータについて
サーボモータについてですが、相性がどうやらあるみたいでサイト内では[Futaba S3003標準サーボモーター](http://www3.towerhobbies.com/cgi-bin/wti0001p?&I=LXH288&P=ML)（$10.99）や[Parallax（Futaba）標準サーボ](http://www.parallax.com/tabid/768/ProductID/101/Default.aspx)（$12.99）が紹介されています.

個人的に苦学生でありながら大量のサーボが必要だったため、様々なモーターを試した結果一番安く、動作の確認もできたのが[Vstone 標準サーボモータ](https://www.vstone.co.jp/robotshop/index.php?main_page=product_info&cPath=72_95_105&products_id=3569)(¥648)でした.
webからの購入もできますし、秋葉原での直接購入も可能ですのでご参考までに

###+α 給電方法

特に必須ではないですが、電池ボックスじゃ足りんという方はUSB二股とDCケーブルとDCジャックを用いて端末に給電しながらモーター給電も可能なので、よければ実践して見てください.
<img width="1281" alt="スクリーンショット 2017-12-17 18.34.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/59590/ab5290c8-3be0-2dbc-c361-70131a7a75f8.png">

* USB-DCケーブル(対応した内径) ¥200 	
* DCジャック(対応した内径) ¥80
* USB(オス)=USB×2口(メス) ¥250 (変換名人)





#GlueMotorを自作してみよう【アプリ編】

続いてアプリの実装です.
今回はiOS端末からサーボモーターを制御するのでAndroid,JavaScriptはまた別のタイミングorどなたかぜひ書いてみてください.

###導入手順

1.はじめの方に共有したGitHubの[ページ](https://github.com/GlueMotor/GlueMotor)からファイルをまずはダウンロードしてきてください.

2.ファイルの中身を見てもらうとわかる通りObjective-Cのコードのためswiftで使用する場合はbridgingheaderを作ります.



オリジナルのプログラムの中で"GlueMotorCore"というグループを作成してください.



<img width="712" alt="スクリーンショット 2017-12-22 19.57.11.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/59590/27905698-681e-cc49-3daf-a296f653c8e2.jpeg">

次にそのグループの中に"GlueMotorCore.h"と"GlueMotorCore.m"の２つをdrag & drop しちゃいましょう.(ちゃんとグループの中につっこむことが大事



<img width="1452" alt="スクリーンショット 2017-12-22 19.52.33.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/59590/00ecdb62-37a4-84c6-9471-ad0696b58147.jpeg">

するとbridgingheaderを作れるようになります.(詳しいことは[こちら](http://tech.admax.ninja/2014/09/26/about-bridging-header/))

<img width="1176" alt="スクリーンショット 2017-12-22 19.52.55.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/59590/a0701a20-2238-ec95-e175-ac693df7d324.jpeg">

うまくいくと、以下のようにBridging_Header.hが追加されています
<img width="1006" alt="スクリーンショット 2017-12-22 19.53.23.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/59590/66742578-7330-90a5-cf2a-f9b35a29ab66.jpeg">


出来上がったBridging_Header.hファイルの中に次のように書きましょう

```(プロジェクト名)_Bridging_Header.h
#import "GlueMotorCore.h"
```

これで導入は完了しました、続いて中身を実装していきます.

###実装

####UIの作成
アプリの見た目をまずは作っていきましょう、サーボモータ2つを制御するのでUISliderを2つ用意するのと、その値を表示するためのUILabelも一緒に

<img width="1218" alt="スクリーンショット 2017-12-22 23.22.44.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/59590/acb9c333-df5a-2f8b-f213-c3ceb2c9ee3b.jpeg">


このときに気をつけることはUISliderの設定値です
__Value : 0.0015__ 
__Minimun : 0.0006__ 
__Maximum : 0.0025__ 

続いて中身をごりごり書いていきます.
なるべく細かくコメントを挟んでみました.

```ViewController.swift
import UIKit

class ViewController: UIViewController,GlueMotorCoreDelegate/*GlueMotorのデリゲートまわり*/ {

    
    //UILable,UISliderまわりの宣言
    @IBOutlet var servoALabel:UILabel!
    @IBOutlet var slideMotorA:UISlider!
    
    @IBOutlet var servoBLabel:UILabel!
    @IBOutlet var slideMotorB:UISlider!
    
    //GlueMotorまわり
    var glueMotor:GlueMotorCore!
    var servoAPulseWidth:TimeInterval!
    var servoBPulseWidth:TimeInterval!
    
    //角度調整用値
    var angleAmountA = 0.0000001
    var angleAmountB = 0.0000001
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        glueMotor = GlueMotorCore.sharedInstance() as! GlueMotorCore
        glueMotor.delegate = self
        
        //待機状態の数値をsliderに反映させる 初期値は0.0015
        slideMotorA.value = Float(0.0015)
        slideMotorB.value = Float(0.0015)
        
        //モータへの周波数にも反映させる
        servoAPulseWidth = TimeInterval(slideMotorA.value)
        servoBPulseWidth = TimeInterval(slideMotorB.value)
        
        //ラベルにも表示させる
        servoALabel.text = "A:"+String(format:"%f", servoAPulseWidth * 1000)
        servoBLabel.text = "B:"+String(format:"%f", servoBPulseWidth * 1000)
        
        //周波数をupdate
        self.updatePulseWidth()
    }
    
    @IBAction func slidercahngedA(_ sender : UISlider){
        //Sliderが変更された時に周波数も変更
        servoAPulseWidth = TimeInterval(sender.value)
        self.updateLabels()
    }
    
    @IBAction func slidercahngedB(_ sender : UISlider){
    
        print(sender.value)
        servoBPulseWidth = TimeInterval(sender.value)
        self.updateLabels()
    }
    
    //周波数をupdate
    func updatePulseWidth(){
        glueMotor.setPulseWidth(servoAPulseWidth, forServo: 1)
        
        glueMotor.setPulseWidth(servoBPulseWidth, forServo: 0)
    }
    
    //labelの表示変更
    func updateLabels(){
        servoALabel.text = "A:"+String(format:"%f", servoAPulseWidth * 1000)
        servoBLabel.text = "B:"+String(format:"%f", servoBPulseWidth * 1000)
    }
    
    //glueMotorお約束
    func glueMotorCoreWillStartPWMCycle(_ glueMotor:GlueMotorCore){
        // NOTE: this delegate method will be called in Audio Queue thread, so don't call the UI related API from here.
        self.updatePulseWidth()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}


```

これであとは関連付けをしっかりと行ってあげるとしっかりと動くはずです.




![](https://media.giphy.com/media/3o6nUUZCUohcM7TH8I/giphy.gif "")

おつかれさまでした！！

あとは自動的に角度を制御したり、OSCを受けて無線で動かしたりとか、なんでもできるようになりましたね.


#実践例
一つの手段をお見せしたに過ぎないので、でできることは未知数です

とある方々はサーボモータの動作確認をするために、GlueMotorコードとアプリだけでarduinoなしに確認ができるから便利だとか

あるいはサーボモータを使った制作物の動きの簡単なプロトタイピングにもおすすめです.

私は修士の修士の習作と修士作品で使わせていただきました、よかったら見てみてください〜

###＜ [crawlMob2 (2016)](https://watakemi725.github.io/app_crawlmob2) ＞
はじめてGlueMotorを用いた制作、この時は電池を持たせてOSC通信によって無線で繋がらせ、群れを作ろうとしました.
![](https://media.giphy.com/media/l1IBjxNaAvyG4z1S0/giphy.gif "")



###＜[node hands (2017)](https://watakemi725.github.io/app_nodeHands) ＞
修士作品として制作したnode hands はサーボモータ２つを用いて人の親指の動きを制御する簡易ロボットハンド20台によるインスタレーション作品です.詳しくはタイトルのリンクで飛んでみてみてください.
![](https://media.giphy.com/media/3oFzmnet5H7DNElpaU/giphy.gif
 "")



##最後に
最後まで読んでいただきありがとうございます、

今回の記事を作成するにあたり、寺崎さんに感謝申し上げます.

GlueMotorに出会わなければ作れなかった作品ばかりの自分としては、少しでも多くの方にこの技術が広まれば嬉しい限りです！

明日はデザインもモーショングラフィックもエンジニアリングもなんでもできるフルスタック王子のシオン君です、お楽しみにー！