toioの磁気センサーを使って上に載せたものを検出する

#サマリ
本記事を読むと、下記の動画の様にtoio™Core Cubeの磁気センサーを使って、キューブの上に載せたものを検出できるようになります。しかもp5.toioを使用しているのでブラウザと磁石があれば、どなたでもお試しは可能です！

 - 例1. ピコトンズの帽子の種類を検出する
 - 例2. ゲズンロイドの紙工作の種類を検出する
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E3%82%B2%E3%82%BA%E3%83%B3%E3%83%AD%E3%82%A4%E3%83%89?src=hash&amp;ref_src=twsrc%5Etfw">#ゲズンロイド</a> の工作物も判定出来ました。これは応用のしがいがあるな。 <a href="https://t.co/5jpi3JpAGY">pic.twitter.com/5jpi3JpAGY</a></p>&mdash; Tetsunori NAKAYAMA | 中山 哲法 (@tetunori_lego) <a href="https://twitter.com/tetunori_lego/status/1314850185445425156?ref_src=twsrc%5Etfw">October 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#成果物
まだ暫定的ですが、[p5.toio](https://github.com/tetunori/p5.toio)の[v0.8.0](https://tetunori.github.io/p5.toio/dist/0.8.0/p5.toio.min.js)に入れておきました。ただAPI Referenceはまだないので、すぐにアクセスして使えるサンプルとして、動画にも使った以下の2つも公開いたします。
 - [p5.toio Sample 11: Magnet function sample1](https://preview.p5js.org/tetunori/present/VBBgYp3f0)
 - [p5.toio Sample 12: Magnet function sample2](https://preview.p5js.org/tetunori/present/1CuCYUF3y)
※ 画面をクリックしてキューブと接続したら、磁石を後述の仕様通りの場所に近づけてください。
![449BB54C-D112-4961-92E4-8D6411F05BA7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/f4a0ad92-5f1e-15a5-5e19-074ea0fc0ea4.jpeg)

#きっかけ
先日、[toioの技術仕様書](https://toio.github.io/toio-spec/)がv2.2.0へ更新され、ゆるゆるとp5.toioに新規機能を追加しています。その中で新たに[磁気センサー](https://toio.github.io/toio-spec/docs/hardware_magnet)が追加されたので、そのアプリケーションとして上に載せたものを検出することにしました。今までtoioを使った表現は主としてキューブ下のマットの読み取りを前提として検討をしていたので、上に載せるものが検出できれば、さらに現実世界で表現出来ることが増えるのではないかと思っています。

# 仕様のおさらい
## HW仕様
まずは、[公式サイト](https://toio.github.io/toio-spec/docs/hardware_magnet)を見ましょう。
サイトによると、HW仕様としては、4mm*4mm*2mmネオジム磁石について配置をかえることで6種類のパターンで検出が可能となっています。
磁石の位置ですが、縦横方向は画像の通りでわかりやすいですが、高さ方向はキューブから少し距離(トップから3.1mm)をあける必要があるので注意です。(ハマりました)

> ![hardware_magnet.svg](https://toio.github.io/toio-spec/docs/assets/hardware_magnet.svg)
> 磁石のレイアウト仕様
> 未装着および以下の仕様に従う 6 つのパターン、合計 7 つパターンを検出できます。
> ![hardware_magnet_layout.svg](https://toio.github.io/toio-spec/docs/assets/hardware_magnet_layout.svg)
>The document is licensed under Creative Commons Attribution 4.0 International License.
>The image is licensed under Creative Commons Attribution-NoDerivatives 4.0 International License.
>Copyright © 2020 Sony Interactive Entertainment Inc.

## SW仕様
次にソフト側のBLE制御仕様ですが、こちらも[公式サイト](https://toio.github.io/toio-spec/docs/ble_magnetic_sensor)をご確認ください。かいつまむと、

 - CharacteristicsはSensor Charを流用する。磁気センサー情報は1st byteで判断する。
 - 後はその他のSensor情報と同様に通知が来る。`0x00`が未装着、`0x01`-`0x06`がそれぞれの装着パターン。
 - なお、基本この機能はオフってあるので、Configuration Charから検出設定をONに変更する必要あり

制御自体はシンプルですが、普段さわらないConfigにアクセスする点は注意ですね。

# 準備
## HW: 磁石
まずは仕様にピッタリの磁石がみつからないと話になりません。その辺に詳しいお友達にヒアリングしたところ、[ネオマグ](https://www.neomag.jp/)さんを紹介されました。結果的に、お値段リーズナブルでほぼ即納、Amazon Pay使えるなどで大変利用しやすかったです。  
ターゲットの品はこちらで、仕様通りの1品です。(※N40とN45の差分はある。)
[ネオジム磁石(N45)、角型、4x4x2(mm)、2mm方向](https://neomag.jp/shop/shoppingcart/itemdetail.php?shape_id=4&categorysOrder=Sorter6&categorysDir=DESC&categorysPage=8&itemno=NB004004002&qty=1)
65円/個 （税抜）
ぼくの注文(10個)では、送料の方が高つきました。なお、注文してから、3, 4日で到着しましたと思います。
![30F51B07-2629-4895-B673-276E2E089405.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/6b804888-6485-f3fd-fb72-d9a7797c669e.jpeg)


なななんと、ネオマグさん、2020/10/11-2020/10/31で[25周年記念お客様感謝キャンペーン](https://www.neomag.jp/companyinfos/companynews27.html)を開催しており、**全てのご注文の送料無料**だそうです。
マジすか。
もう一回買っておこうかな・・・

なお、Qiitaの読者様へは釈迦に説法かもしれませんが、念のため注意書きを。
今回の磁石は特に寸法が小さくかつ磁力が強いため、取り扱いによっては大変危険なものになりますので、小さなお子様やペットのいるご家庭は十分にケアをして取り扱ってください。飲み込んだりすると一大事ですよ！

## HW: スペーサー
前述しましたが、toioのトップ面と磁石の間には3.1mmほどのスペースが必要になります。今回の検出において**この距離がかなりシビア**だったので対応はほぼ必須と考えてください。3Dプリンタとかを持っていれば簡単かもしれませんが、うちにはなく非常に苦労しましたが、**解決策を見つけました**！
なんと、みんな大好きレゴブロックのパネルパーツをスペーサーとして取り付けるだけで、すべて解決しました！
キューブの天面にパネルをつけると、天面からパネルまでの距離が3.2mm位となりますので、ほぼ仕様通りで塩梅が良いです。
(冷静になって考えてみると、toioに同梱されている専用プレートでもよさそうですよね。)
![5D0F4C0A-5320-49D6-B286-EE4251A5B12B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/427abe8b-b534-dab3-905d-c0b9ccb63cd3.jpeg)

なお、レゴのパネルパーツのサイズですが、基本はキューブ天面の、磁石検出付近のリボン型が割れている箇所にパネルが付いていればよいので、1*2, 1*4, 2*4どれでもOKです。
![26BB1CF4-19E3-4314-B710-773DB79945F1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/82097092-6470-dc10-33fd-7a370b3d6d19.jpeg)

ただ、今後キューブに上物をかぶせた時、上物が傾く可能性があるので、下の写真の様に2*4パーツを縦方向に取り付けるか、全面をパネルで覆う方がベターです。
![0A20ECAF-DC65-4311-81DA-F34FCAA3AD50.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/a00afd57-aaa6-90b1-9296-5b14f8aa6ada.jpeg)

このパネルさえあれば、上に磁石を載せるだけで検出できるようになります。

## SW: p5.toioの準備
上記仕様で実装するだけだったので、とくにハマりもせず、すぐにp5.js WebEditorなどで動かせるようになりました。
実装を見たい方は、まだ`main`にマージしていないので、`dev-for-v0.8.0`ブランチの[コレ](https://github.com/tetunori/p5.toio/commit/3d88ee112923533a6df71730ef0b3725dbcf6906)とか[コレ](https://github.com/tetunori/p5.toio/commit/d3b26b8244bc784879b4a39279545a5e111788d1)を参照ください。

また、再掲ですが、アプリとしては下記2つをp5.js WebEditor上に作成しています。
 - [p5.toio Sample 11: Magnet function sample1](https://editor.p5js.org/tetunori/sketches/VBBgYp3f0)：6パターンの磁石検出に応じて、画面に表示されるの背景色と文字を変える。（ピコトンズの帽子や、A-Fキューブスキン検出）
 - [p5.toio Sample 12: Magnet function sample2](https://editor.p5js.org/tetunori/sketches/1CuCYUF3y)：3パターンの磁石検出に応じて、画面に表示される絵文字を変える。（ゲズンロイドの工作物を検出する想定）

# 検出する
## 基礎：A-Fキューブスキン検出
まずは仕様通りの磁石配置で機能を確認したいと思います。磁石の検出位置が本当にシビアなので、毎回合わせるのはつらく、パターンごとにキューブスキンを作って磁石を貼り付けることにしました。
こんな感じ。
![6742617E-E0EC-4744-A459-4352D1EB4105.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/2944d9ef-9da4-9d5c-6f92-d68ec985fbac.jpeg)
![A314A4B4-F4C7-407C-B47C-438F93A550F6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/5b5f3e32-1148-2311-f83f-d065c7e3e54a.jpeg)

これを実際に検出にかけてみると、、良い感じです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">後でQiitaから参照する用。<a href="https://twitter.com/hashtag/toio?src=hash&amp;ref_src=twsrc%5Etfw">#toio</a> <a href="https://twitter.com/hashtag/p5toio?src=hash&amp;ref_src=twsrc%5Etfw">#p5toio</a> <a href="https://t.co/h0K0UIBInu">pic.twitter.com/h0K0UIBInu</a></p>&mdash; Tetsunori NAKAYAMA | 中山 哲法 (@tetunori_lego) <a href="https://twitter.com/tetunori_lego/status/1314876749902016514?ref_src=twsrc%5Etfw">October 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
なかなか反応せず、もどかしい場合や、キューブの個体差があるように感じますが、上々の出来栄えです。

## 応用1：ゲズンロイド工作検出
上記を応用、というか上に工作物載せただけですが、こういう原理でゲズンロイドの工作検出を実現しました。
キューブの上のレゴパネルは必須です。
![31CCC5A3-1AEB-4015-A2E5-B7FAE3C1F885.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/9886e726-6f6c-872f-092e-e1ed294eb303.jpeg)


## 応用2：ピコトンズ帽子検出
こっちは割とテクニカルですが、帽子の中に湾曲させた紙を貼りそこに磁石を取り付けています。
この位置をピンポイントで狙うとパネルパーツなしで検出がうまくいきます。
![03088D87-4E21-49A1-8857-270ACD7E8878.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/6f3e429b-3157-2a6a-d2ee-f306c1dfbde5.jpeg)


## 番外編：おうちにある磁石で検出してみる
家の冷蔵庫にネオジム磁石はたくさん貼ってあるので、それで動作しないのか確認してみました。
結論として、磁力に応じてスペースを変えることを意識すれば、結構問題なく検出できることが分かりました。
これらが、我が家にあったネオジム磁石たち。すべて検出可能でした。
![6EF08A07-0D4A-48BC-BE9C-1D1F3295D8BC.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/53f4f44d-a0ba-282d-596e-b4f355730cfb.jpeg)

意外とイケるんだなと。
なお、フェライト磁石は反応しませんでした。

# 所感と考察
- 最初にピコトンズ帽子の件を種明かしせずにtwitterにあげましたが、どうなっているの？とびっくりいただけた方もいらっしゃったので、それなりにインパクトはあって良かった。
- 磁石位置については、かなりシビアで手作業でやるにはちょっと難しく感じました。どなたか3Dプリンタで磁石の凹み付きのデータ公開してくれるとありがたいなと思いました。
- 磁気センサーはアイディア次第で他にもいろいろできそう。p5.toioなら、ブラウザからアクセスするだけで使えるのでぜひ皆様も。

# 追記 2020/10/12
[磁石を正確に配置できるテンプレート](https://docs.google.com/drawings/d/1mYnnuSxP-rkbueDb2mvCg1yMM7nXsS2IaEpPHJVriKQ/edit)を作成しました。ご自由にどうぞ。
A4用紙に原寸でコピーして使用してください。
👇はサンプルの画像です。あしからず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542654/b8d36046-9d90-7d0e-8fbb-960f68868569.png)