masato-ka's diary

日々思ったこととか、やったことの備忘録。

TensorFlow Lite for MicrocontrollersとESP32を用いた安価なAI自動運転の検証

1. この記事について

 DonkeyCarなど行動模倣(Behavior Cloning)を行うAI RC CARではカメラ画像を入力とした推論と走行が一般的だ。1。この場合、エッジ側にもそれなりの計算力が必要になり、実機ハードウェアの構成が高額になる。この記事ではカメラを使用せずに単純なセンサ情報のみで同様の仕組みを実現できることをシミュレーション環境と実機での検証を通して確認した。検証では3つの距離センサの値を入力とする3層のニューラルネットワークを用いて自動走行を実現した。さらに実機の検証ではTensorFlow Lite for Microcontrollers2とESP32を使い、安価な構成でニューラルネットワークによるラジコンカーの自動運転が実現できることを示した。

検証で作成したコードは以下のGithubリポジトリで公開している。

github.com

2. シミュレーションによる予備検証

まず初めに、実現の目論見を確認するため、シミュレーションによる予備検証を実施した。

2.1 シミュレーション環境

 シミュレーション環境は詳解確率ロボティクス3に記載の差動2輪ロボットのシミュレーション環境を参考に実装した。別途、コースをあらわす壁と距離センサを実装している。Pytorch版のシミュレーション環境はGistで公開している。TensorFlow版は前述のリポジトリから参照できる。実装フレームワークが違うのみでそれぞれに違いはない。

gist.github.com

 ロボットには3つの距離センサを設置した。それぞれのセンサは前方方向に1つとそれを原点として左右に60度開いて設置している。

 シミュレーションはデータ収集・学習・推論走行の3つのパートに別れている。「データ収集」では比例制御によりコースを自動走行する。比例制御は左右のセンサ値の差分を入力として操舵の制御値を決定する。また学習データとして観測されるセンサの値と対になる制御値の記録を行う。「学習」では学習データを元にニューラルネットワークを訓練を実行する。「推論走行」では学習したニューラルネットワークを使い自動走行を実行し、その評価を行う。

2.2 ニューラルネットワークモデル

シミュレーションで取得した学習データは以下の形でCSV形式で保存した。速度の値は学習データとして記録されるが固定値であるため意味を持たない。各センサの値入力として操舵角と速度を推定する回帰問題として学習させる。

左センサ値,中央センサ値,右センサ値,操舵角,速度

 定義したニューラルネットワークモデルは3層の全結合層から構成される。アクティベーション関数は1層目と2層目にReluを使用し、最終段には設定しない。また、Loss関数はMSEを設定している。以下、TensorFlowでの実装例を示す。

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(8, activation='relu', input_shape=(3,)),
    layers.Dense(8, activation='relu'),
    layers.Dense(2),
  ])

optimizer = keras.optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mse',
              optimizer = optimizer,
              metrics = ['mae'])
model.summary()

2.3 シミュレーション検証の結果

シミュレーションでは実行の様子を動画で確認できる。ここでは結果の画像を掲載する。画像中の円が自動運転車を表している。自動運転車から3本出ている赤い線がセンサの計測方向となる。観測されるセンサの値は各線と壁の接触点と自動運転車との直線距離となる。3000ステップの試行を行い、3000レコードのデータを集めた。

f:id:masato-ka:20200708130329p:plain
比例制御による自動走行(学習走行)

収集したデータを使い訓練したニューラルネットワークを比例制御と置き換えて自動走行を実行した。初期位置をX軸方向にずらして実行している。以下の画像を確認すると比例制御の動きと同じ軌跡で自動運転が行われていることが確認できる。線形制御の出力データからニューラルネットワークがその関数を「近似’している。

f:id:masato-ka:20200708130302p:plain
ニューラルネットワークによる自動走行

いずれも人を介在しない自動走行だが、前者は人が走行できるようにルールをコードベースに落とし込んでいる。しかし、後者はデータから自動的にルールを発見させているという点で大きな違いがある。

3. 実機による評価

 シミュレーションにおいて距離センサ3つの入力のみで行動模倣を実現できることがわかった。実機へも適用できるか検証を実施した。

3.1 検証車両の紹介

 今回実機検証の車両としてRumiCarというオープンハードウェアの車両を用いて検証を行なった。RumiCarは安価なラジコンカーを改造し、ESP32と距離センサVL53L0Xを3つ搭載している。ベースとなるラジコンカーの制約としてスロットルは全身、後進、停止、ステアリングは直進、右、左という離散的な制御しかできない。

www.rumicar.com

3.3 実機に合わせたニューラルネットワークの変更とESP32へのデプロイ

ニューラルネットワークの構成をシミュレーションから実機に合わせて変更した。センサの値から「直進」「左」「右」の3つのクラスを推論するよう分類問題として学習させる。

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(8, activation='relu', input_shape=(3,)),
    layers.Dense(8, activation='relu'),
    layers.Dense(3, activation="softmax"),
  ])

optimizer = keras.optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

model.compile(optimizer='adam', 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.summary()

訓練後のモデルをTensorFlow Lite for microcontrollers向けに変換する。TensorFlow Lite形式で保存したモデルをxxdコマンドを使い、バイト配列として出力する。出力されたバイト配列をファームウェアの一部としてESP32といった低リソースのマイコンへデプロイする。TensorFlow Lite for microcontrollersの詳細な利用方法については公式を参照[^2]。

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert() #量子化はせずFP32のまま処理していことに注意!
open("converted_model.tflite", "wb").write(tflite_model) #TFLite形式で保存


!apt-get install xxd
!xxd -i converted_model.tflite > airc_model.cpp  #xxdコマンドでモデルをC言語で参照可能なバイト配列として出力する。

TensorFlow Lite microcontrollersはCPUやフレームワークといった利用する組み込み環境に合わせて自分でビルドする必要がある。Arduino フレームワークとESP32の組み合わせはビルド済みのライブラリがリリースされており、Arduino IDE, PlatoformIOのライブラリ管理から「TensorFlowLite_ESP32」でインストールできる。今回はこちらのライブラリを利用して実装を行なった。

github.com

詳細な実装コードついては冒頭のリポジトリを参照してほしい。

3.4 実機検証結果

 実機の検証においても比例制御による自動走行で学習データを収集した。前述の制御の制約に合わせるため出力結果をルールベースで各命令に対応させている。ニューラルネットワークの訓練と形式の変換はGoogle Colaboraotryで行い、ESP32へプログラムとともに書き込む。

 以下が実機検証の動画である。コースは紙を山折りにした物を円形に配置し作成した。実機でもニューラルネットワークがセンサのデータから制御値を推論して走行できていることがわかる。

youtu.be

4. まとめ

この記事では距離センサ3つのみという構成で、ニューラルネットワークによる自動走行が可能であることをシミュレーションを通して検証した。また、TensorFlow Lite for microcontrollersを利用することで、ESP32を搭載した実機のラジコンカーで自動走行が可能であることを検証した。今回は単純な制御則でも十分に制御できるが、コースを逸脱しないように走行するという抽象的表現を人がプログラミングでルールとして落とし込むのではなく、データから演繹的に自動的にルールを作り出せること、さらにそれを「マイコンレベルで実現できる」という点が非常に面白い。今後マイコンを利用したセンサデータと複雑なルールの組み合わせが単純だが高度なことができるデバイスの登場を予感させる。

IoT・AIなデバイスを開発するのにAndroid Thingsが控えめに言って最高だった話

更新

2019年2月12日付けで以下のアナウンスがありました。内容としてはAndroidThingsはスマートディスプレイ向けに再フォーカスするとの内容です。一応当面はRaspberry Pi3Bは利用できるとのことでしたが、非商用での利用です。 2019年以降はCloud IoT CoreやCloud IoT Edgeを利用してくださいとのことです。

https://android-developers.googleblog.com/2019/02/an-update-on-android-things.html?m=1

この記事について

 この記事ではAndroid Thingsを触ってみた感想をつらつらと記載している。あくまで個人的な感想を記載してあり、異論は多々あるだろう。しかし控えめに言ってAndroid Thingsは最高だった。1ヶ月ほど遊んでみてこれは面白いことができそうという感想しか出てこない。現在、IoTデバイスのトレンドはAIをはじめとするエッジヘビーな処理、デバイス管理、セキュリティなど求められるものが多くなっている。そしてAndroid Thingsはいとも簡単にこれらの要件を叶えてくれる。ちなみにAzure IoT EdgeとかAmazon Free RTOSなんかはこれから触りたい候補に入っているので「それ['Azure IoT Edge' | 'Amazon Free RTOS']でもできるよ」という話は知りたいし、たくさん突っ込んでほしい。

1. なぜAndroid Thingsなのか?

 2018年5月にGAから1.0.0正式リリースになったのを機にAndroid Thigs使ってみるかという機運になった。またGCPのCloud IoT Coreとかその辺りを触っていて、エッジ側のOSとかの使い勝手も知りたくなり手を出してみた。最初は軽い遊びのつもりだったけど本気になってしまった。反省はしていない。

2. Android Thingsプロフィール

まずはAndorid Thingsのプロフィールについて見ていこう。

2.2. Android Things

 大雑把に説明するとAndroid ThingsはAndroid Oから派生して作られている。Android のCore framework APIにI/Oなどを直接コントロールできるようにしたThings APIを追加したものになる。これ以外にAndroidとは以下のポイントが違う。

  1. 設定などを行うシステムアプリがないこと
  2. 1つのアプリケーションしか実行できない
  3. 起動時にアプリケーションが自動的に立ち上がる

こうすることでにAndroid Thingsは組み込みアプリケーションを実行するプラットフォームとして最適化されている。AndroidスマホをIoTデバイスとして使おうとかそういう甘っちょろい考えとはそもそも次元が違うのである。ただし開発環境は普通のAndroid と同じようにAndroidStudioが利用できる(利用せざるおえない)。私はIntteliJ IDEAを使っているけど問題なく使える。

Overview  |  Android Things  |  Android Developers

2.3. Android Thingsで使える。ハードウェア

 Android Thingsが動くハードウェアは決まっている。一番入手しやすいのはRaspberry Pi 3 Bだろう。それ以外でホビー用だと公式入門キットに付属しているNXP Pico i.MX7Dが使えるそうだ。商用ではSnapdragonなんかも動くようだ。自分はおとなしくRaspberry Pi 3 Bを使っている。自分で用意するのであれば一択な気がする。

Supported hardware  |  Android Things  |  Android Developers

2.4. Android Thingsのインストールについて

Android ThingsのインストールはAndroid Things Consoleにユーザ登録するところから始まる。ユーザ登録後、インストールツールがダウンロードできるのでツールを使いSDカードへOSを書き込むことができる。Android Things Consoleはツールのダウンロードだけでなく、カスタムイメージの作成やアプリケーションの配布がきでる。(後述)

3. Android Thingsが最高なポイント

じゃあ、Android Thingsの何が最高なのか、何ができるのかを見ていきたい。

3.1. Peripheralの操作ができて最高

 I/O, I2C, SPI, UART, I2Sなど一通りのペリフェラルを扱うことができる。最近のプロトタイピングボードを使ってやりたいことはそのまま実現できる。しかもこれがAndroidの開発環境から開発できる。Javaさえ書ければ思いのままに扱うことができる。さらにAndroidStudioのデバッグ機能が使えるので、ソフトウェア周りのデバックはこれで十分である。printfデバッグのためにひたすらprint文を埋め込んだりしなくていい。AndroidThingsを始めるにはRainbowHATを買うのがオススメ。2018年7月22日現在スイッチサイエンスでは在庫切れだ。Amazonでは割高で売られている。なんとか在庫復活してほしさある。

www.switch-science.com

 RainbowHATはAndroidThingsのcodelabやチュートリアルで採用されているボードなので、一通りの機能をすぐに触ることができる。

f:id:masato-ka:20180722193802j:plain

しかしRainbowHATだけで遊ぼうと思ってたらいつの間にかディスプレイとカメラを買っていた。ただただ最高かよ。

3.2. ユーザドライバ開発ができて最高

 Androdi ThingsではAndroidデバイスドライバをUser-space driversという形でアプリケーションの一部に実装することができる。例えばPeripheralにGPSや加速度センサを接続してアプリケーションから直接UARTやI2Cを叩いて情報を取ることができる。しかしUser-space-driverとしてこれらの処理をラップすると普通のAndroid端末と同じようにAndroidのframeworkを介してそれぞれの値を取得できるようになる。例えばSPI接続の安いRasPi用ディスプレイはSPIでタッチパネルのデータを受け渡す。これをUser-space-driverを介さずに利用しようとすると、SPIでX,Yの座標を受け取り、UIの座標と当たり判定して。。。と実装する必要がある。しかしHIDのポインティングデバイスドライバとしてSPIをラップして書けば、通常のAndroid端末のタッチパネル操作と何ら変わりなくただViewを実装すればHIDの処理はOS側がイベントとして処理してくれる。SPIでとってきたデータを意識する必要はない。ちなみにこれを1.0.1向けに実装したのものは以下のリポジトリにある。

github.com

動くとこんな感じなる。

User-space-driverはLocation HID Sensor, LoWPANなど4種類サポートされている

 IoTサービスの初期検討ではデバイスがないのでAndroidスマホで実装する。そのフィードバックを元にハードウェア要件を固めAndroidThingsで実装する。スマホで作ったアプリのソフトウェア資産をAndroidThingsに移植することでソフトウェア開発を簡素化できる。こういったIoTのプロジェクトを進める上でとても強力な開発プロセスを提供してくれるのではないだろうか。IoTサービス開発にも役立って最高かよ。

3.3. BLEが使えて最高

 Android ThingsはもちろんBLEも使える。Raspberry Pi 3BのBLEも制御することができるらしい。らしいというのはまだ触っていないのでこの部分については語れる部分がほとんどない。1ヶ月以上遊んでてもまだ試すことが多いの最高かよ。

3.4. カメラが使えて最高

 Android Thingsではカメラを使うことができる。Raspberry Piの公式カメラを利用することができる。ただしUSBカメラを接続して使うのはRaspberry Piでは今の所できないようだ。少々残念なところだけどUSBのカメラのドライバを用意するなどAndroidでは難しい部分もあるのだろうか。もちろん撮影した画像はファイルに保存できるし、画面に表示することもできる。画像が取れることで画像認識など夢が広がりまくって最高かよ。

3.5. デバイスでのAIが簡単すぎて最高

画像認識

 Androidtensorflow-liteFirebase ML Kitといったモバイルデバイス向けディープラーニングフレームワークを使い物体認識などを実装することができる。同じ方法でAndroid Thingsも利用することができる。サンプルも豊富にあって既存モデルを使うだけであればすぐに実行することができる。例えば一般物体認識のサンプルは以下。Raspberry Piでも動く。

GitHub - androidthings/sample-tensorflow-imageclassifier: Classify camera images locally using TensorFlow models

 大きくtensorflow-liteを直接実行する方法とFirebase ML Kitを使う方法があるが後者をおすすめしたい。どちらもtensorflow-liteとそのモデルを利用するみたいだが(と思ってる)Firebase ML Kitでは何種類かのよくありそうな認識モデルを提供してくれる。OCRや顔発見、シーン認識、ランドマーク認識だ。もちろんtensorflow向けに用意したカスタムモデルを圧縮して使うこともできる。ここまで読んでRaspbianでも同じことできると思ってしまう。しかしtensorflow-liteのビルドなど面倒な環境構築作業が必要だ。Android Thingsでは環境構築をすっ飛ばして目的のアプリケーション実装に取り組めるところにアドバンテージがある。さらにFirebaseからモデルファイルをアプリケーションへ配信してデバイスのモデルを更新することができる。こういった管理機能まで含めて利用することができるのだ。そして、Android Things上での実装も数十行で終わる。たとえばFirebase ML Kitだとこうなる。もちろん実際にはカメラで画像をとってくるなど処理はあるが。

private void recongnizeText(FirebaseVisionImage image){
        FirebaseVisionTextDetector detector = FirebaseVision.getInstance().getVisionTextDetector();
        Task<FirebaseVisionText> result = detector.detectInImage(image)
                .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
                    @Override
                    public void onSuccess(FirebaseVisionText firebaseVisionText) {
                        StringBuffer sb = new StringBuffer();
                        sb.append("Result: ");
                        for (FirebaseVisionText.Block block : firebaseVisionText.getBlocks()) {
                            sb.append(block.getText());
                            sb.append(", ");

                            Log.i(LOG_TAG, "Recognize text: " + block.getText());
                        }
                        textView.setText(sb.toString());
                    }
                }).addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.e(LOG_TAG, "failed recognize text", e);
                            }
                        }
                );
    }

顔認識をやりたければDetectorの種類を変えるだけだ。さらにクラウドAPI を使う処理にしたい場合もそれ用のDetectorを使えばいいだけだ。リファレンスがなくてもかける気がする。簡単に最新のAIをIoTデバイスに取り込めるの本当に最高かよ。

TPU対応(8月1日追記)

先日行われたGoogle Cloud Nextでは「Edge TPU」と呼ばれるTensorFlow-Liteを実行するための組み込み向けASICが発表された。また開発ボードが秋に発売され、対応OSはDebianとAndroidThingsになるそうだ。また同時に発表されたCloud IoT EdgeではEdge上でのML機能のを実現するランタイムとそれをGCPのプラットフォームをつなげる機能が提供されるようだ。詳細わかり次第また記載をしたい。 また、AndroidIntel Movidiusにも対応しているらしい、AndroidThingsでも使えるのか検証したい。

音声対話アシスタント

今はやりの音声対話アシスタントもAndroid Thingsで作ることができる。こちらはVoice KitのソフトウェアをAndroid Thingsで動かせるようだ。まだ試していないがぜひやってみたい。マイクやスピーカも使えるっぽい。Peripheralにモータとセンサをつなげればコミュニケーションロボットも簡単に作れそうで最高かよ。

3.6. クラウド連携が至れり尽くせりで最高

当然、クラウドとの連携も充実している。

アプリケーションとしてクラウドを使う

Google Cloud IoT Coreとの連携にはクライアントライブラリが公開されている。これを使うと簡単にGoogle Cloud IoT Coreと接続することができた。これでAndroid Thingsで取得したセンサデータや画像認識の結果をGoogle Cloud IoT Coreに投げCloud Dataflowを経由し、BigQueryに投げ込むことができる。後のデータ処理や可視化は思いのままだ。

developers-jp.googleblog.com

Googleクラウドプラットフォームへのコネクティビティが整備されてて最高かよ。

管理方法としてクラウドを使う

クラウドとの連携はアプリケーションだけではなく、デバイスの運用においても力を発揮する。Android Thingsをインストールするときに利用したAndroid Things Consoleを使えばアプリケーションの配信やアップデートができるようになる。また、OSの更新はOTAで実行できるようになる。つまりプロダクトとして実運用に入っても至れり尽くせりになっている。この部分は先ほどのFirebaseのAIモデルの配信も同じだろう。そもそも向こうはスマホアプリを対象としているのでこういう機能がないと実用として使えないのだろう。デバイスの数が増えても最高かよ。

IoT端末のソフトウェアを管理できるツール「Android Things Console」を使ってみました - GIGAZINE

3.7. IoTデバイスとしての取り回しが楽で最高

 AndroidThingsは電源を入れたらOSが立ち上がり、そのままアプリが起動する。電源一発ぽんだ。変なアプリケーション立ち上げ操作やそのための設定は必要ない。また、デバイスの電源はそのままデンプチできる。これでOSは壊れることはない。(一応そういうことになっている。)そのためにOSの設定をする必要はない。まさにIoT向けOSで最高かよ。

4. Android Thingsの弱いところ

ここまでAndroid Thingsの最高なところを見てきた。しかし光あれば影がある。最高じゃない部分だって多々あるのだ。

4.1. LTE接続や3Gサポート

Raspberry PiだとLTEモデムドライバなどサポートがない。QualcommがSnapdragonあたりで使えるようにするみたいなニュースがあるようだがRaspberry Piでもなんとかならんだろうか。今後に期待したいところだ。

Qualcomm to announce LTE chipset for Google’s IoT, Android Things

 またUSBやUARTのLTEモデムを接続し、ATコマンドで無理やりSMS送ってる人はいる。自分でドライバとか書けばなんとかなるんだろうか修羅の道な気もする。 これにSORACOMつなげたいんじゃと思いつつ、SORACOM Kryptonでソラコムのサービスにつなぎ込むんでいくのがいいのかもしれない。

4.2. Javaで開発

 Androidなので開発言語はJavaJavaだと辛い人は辛い。ただしIDEを使えばそこまで辛くはないと個人的には思っている。AndroidStudioはIntteliJ IDEAをベースにしているので開発環境としてもいい方だと思っている。このIDEの使い方を知ればむしろJavaを書くのが楽しくなると思う。どうしてもJavaとか嫌だという人はKotlinを使うことができる。

4.3. Androidの知識

 これまで最高ポイントで「Android開発と同じ知識で」や「Androidと同じソースで」などと書いた。しかし裏を返せばAndroid開発の知識やスキルを強制的に求められるのだ。これはAndroid開発初心者には学習コストが必要になる。しかし、幸いにも世のAndroid 開発者は多い。トラブル発生時のググラビリティは非常に高い。また、Googleのcodelabなど上質なチュートリアルやドキュメントも揃っている。Androidだけなら書籍もあるのでそんなに困らない。事実私はAndroid開発ほぼ初心者だがAndroid Thingsは難なく使えるようになった。もちろんAndroid Things 固有の問題だと辛いけどPeripheral周りとかかな。

4.4. まだ少し不安定

1.0.0とはいえこの安定性はどうなんだという状況がたまに発生する。まず最初に遭遇したのがWiFiの問題だ。家でWiFiを設定すると突然再起動を繰り返すようになった。WiFi設定後だったので電源の問題かと3AのACに変えたが状況が変わらずだった。途方に暮れてバグとして報告をした。

https://issuetracker.google.com/issues/110793391

結果として類似の報告が上がっているらしく、特定の設定のWiFiアクセスポイントが近くにあると起こる問題とのこと。。。家の中で別の部屋に移動するだけで再起動は発生しなくなった。また外に持って作業することもあるが今の所外では発生しない。本当に特異な状況だったのだろう。再起動をかなりの回数繰り返すうちにOSが起動しなくなる事象も確認している。この辺りも電プチが原因なのか、再起動ループが原因なのかは不明だ。今後改善されることを願う。

4.5. 対応ハードウェの選択肢が少ない。

Raspberry Pi 3 Bが使えればそんなに困りはしないが、もう少し選択肢があってもいい気がする。また新しいボードに対応するまでのタイムラグもきになるところだ。ちょっと前まではIntel Edisonなども使えていたようだが奴のことはもう忘れよう。これからシングルボードコンピュータが新規に作られたらぜひAndroid Things対応ボードにしてほしい。

5. まとめ

Android Thignsは最高だった。確かに難はあるしイロモノ感も否めない。しかし、控えめに言って最高かよだった。盛り上がりはイマイチな気がする。もちろん使ってる人もいるにはいるが、よく見るって感じでもない。正式リリースされてまだ日が浅いというのもあるかもしれないが、これから日本でも盛り上がって欲しい。この記事を見てAndroid Thingsに興味を持ってくれたら嬉しい。また、Android Thingsのもくもく会を企画してみたので実際に触って見たくなったら是非参加して欲しい。

connpass.com

このブログでもAndroid Thigsは追っていきたいテーマだ。

Azure、SORACOM、Futabaのサーボで金賞をもらった話。

この記事について

この記事ではIoT ALGYAN(あるじゃん)さん主催のFutaba製コマンド方式サーボIoTアプリコンテストに参加 して、考えたことや審査会当日では語りきれなかったことなどを記録として残しています。記録しないと忘れちゃう。

イベントの概要

イベントの募集ページは以下です。

algyan.connpass.com

双葉電子工業様から参加者にコマンド方式サーボモータRS304MDが配られ、2ヶ月でサーボとMicrosoft Azureを使ったIoTアプリケーションを組み上げる というのがお題でした。それ以外のテーマは自由です。

コマンド方式サーボRS304MDについて

ホビー用2足歩行ロボットにも使われているコマンド方式サーボモータです。サーボモータは通常PWMのパルス幅で角度を指定しますが、このサーボはシリアル通信で指示角度を与えて制御します。また、モータを動かすだけでなく、現在角度の取得、トルクのON/OFFやコンプライアンス制御(バネのように動かす)、モータ負荷(電流値)や電圧、温度を取得することができます。  アクチュエーションだけでなく、センシングに活用できそうというのがアイディアを考える点でもキーポイントとなりました。

www.futaba.co.jp

応募したもの

今回のコンテストで作成したアプリの詳細は以下の当日の資料をご覧ください。

サマリー

  • 小物を管理するアプリケーション
  • モータでリフター機構を作成
  • 上に乗せたものの重さをセンサーレスで計測する。
  • Microsoft Azure、SORACOMを利用する。

結果について

今回のイベントは順位がつきます。今回私は金賞をいただくことができました。 双葉電子工業様から賞状をいただきました。金賞も嬉しい話ですが、他の方の発表の中で公開したサーボモータのライブラリが思ったよりも利用いただいていたことが印象的でした。嬉しかったです。(中にはこれで間に合ったと言っていただける方もありがたや!)

f:id:masato-ka:20180320114945j:plain

コンテスト応募の動機とお題に対して考えたこと

コンテスト応募の動機について

コンテストに応募する上で自分の動機はIoTっぽいものを作ってみたいという純粋な動機とともにまだ触ったことのない新しい技術やサービスを習得したいというモチベーションがあったためです。また、自分自身同じ趣向の人と仲良くなりたいというモチベーションがあったため、交流をキーワードに参加しました。

新しい技術という点ではAzureとSORACOMを利用したアーキテクチャを自分なりに作れていけたのでよかったかなと思います。また、サーボモータのライブラリを開発し公開を行いました。このライブラリは他の参加者からのフィードバックもあり、今後も育てていきたいなと思っています。

github.com

モータのライブラリ詳細については以下の記事です。

masato-ka.hatenablog.com

交流をキーワードに積極的にコミュニティに関わっていこうと考えて行動しました。上記のように協力をいただいたり、アドバイスや次に繋がりそうなお話もいただいたりとよかったと思います。ただ、より色んな人と話したり、Azureやクラウド周りの部分も意見が欲しかったなと若干不完全燃焼感が残っています。この部分はまた別の機会でチャレンジしていきたいです。貪欲に生きたい。

お題に対して考えたこと

応募作品を考える上で以下の3つをテーマにしました。

  1. モータからの取得情報を活用したIoTサービスを考える。
  2. Microsoft Azureを触ってIoT系のサービスやServerlessといった技術の勘所を抑える。
  3. 利用方法が明確になってなかったWioLTEとSORACOMを利用する。

これに加えて、生活の課題を解決しようというテーマで一人ブレストを行いテーマを検討しました。その他のネタとしては腕のリハビリテーションマシンなどがありましたが、機構の面白さなどから今回のネタを採用しました。

自分の作品の売りポイント

1. リフトアップ機構

ものを持ち上げる。持ち上げたものの重さを測ることができる。をキーワードにいくつかの機構を考えましたが、最終的に今回のリフト機構を採用しました。機械設計は素人なのですが、10年以上前の大学の製図の時間を思い出し、見よう見まねでOSXKeynoteで図面を起こしました。加工は東急ハンズの工房で行いました。

  • プロトタイプ2の組み立て

f:id:masato-ka:20180307114957j:plain

以下は機構の動作動画です。動画の後半は副賞としてもらった高トルク版のRM303に差し替えています。 今まで厳しかった500mlのペットボトルも余裕。ええもんもろた。

www.youtube.com

2. Azure IoT Hub とSORACOMの連携

ここはいずれ別の記事に起こそうと思っています。タイミングよくSORACOM BeamとAzure IoT Hubの下り制御ができるようになったため、活用しました。また、SORACOM SIMのIMSIをAzure IoT HubのIDとして利用しています。そのため、認証情報はSORACOM Beamにあり、Azure IoT Hubに接続するために必要なデバイスIDもSORACOMのメタデータサービスから取得することができます。したがって次のような利点があります。

  1. バイスに固有の情報を書き込む必要がない(書き込みと設定が楽)
  2. 管理アプリケーション側からのデバイス追加処理を簡略化できる。

f:id:masato-ka:20180320110719p:plain

他の参加者さんの作品で特に面白いと思ったアイディア

並び順に意味はありませんが当日見てなるほどなと思ったもの

1. ボトルマネージャー(すながわさん)

 サーボモータでボトルを振って、その時のサーボの負荷から水量を推定するというもの。個人的にIoT居酒屋を将来やってみたいと思っているのでこの装置は使えるなと思いました。是非資料公開いただきたい。

2. IoTアロマディフューザー bluewell(ブルーウェルさん)

 アロマオイルの瓶を複数装置の中に設置しておく。サーボモータで空気の流路を変え、遠隔から部屋の香りを制御できるというアイディア。これも何かに使えそうと思ったアイディアでした。

3. 金庫番サーボ 情報科学専門学校 IoTゼミさん

サーボモータダイアル式金庫のダイアルに使えるというものでした。遠隔からのロックや、スマホからの暗証番号設定を行えるとのこと。個人的にはワンタイムパスワードのように毎回、開錠番号が変わったりするともっと面白いのかなと思いました。

4. フライ バイ ワイキー 高瀬さん

飛行機のフライバイワイヤ方式に習って、シリンダー錠をフライバイワイヤにしたもの。フライバイワイヤってロマンがありますよね。

上記に挙げた方以外の作品もどれも力作ぞろいでしたので、コンテストの時しか見れないのは惜しいものばかりでした。どこかで一挙展示とかすると面白そうです。

Arduino ファンもくもく会について

実は準備期間中Arduinoファンもくもく会というものにも参加していました。参加の動機は前述の交流がメインでしたが、実は他の参加者の方もきており、ここでの情報交換やいただいたアドバイスがかなり参考になりました。今後も参加していきたい活動のひとつです。

arduinofun.connpass.com

感想

全体を通して大変おもしろかたです。でも準備に時間(あとお金も)をかなり使ったなと思いまいました。ここを無駄にしないためにも今後につなげていきたいです。やってみてまだ自分もこんなもの作る根気があるんだなと思ったので、これからもいろいろ挑戦していければと思います。あとチーム組んで参加できたら面白いだろうなと思いました。また今回スポンサーだった双葉電子工業さんと主催のIoT ALGYAN(あるじゃん)さんにはチャレンジの場を提供いただきかつ素晴らしい結果までいただいて感謝しかありません。これからも是非面白い企画を作っていただきたいです。参加するだけでなく企画や運営、ネタの提供などお手伝いする機会があればより嬉しいと思っています。(貧欲に生きたい。)

RS304をWio LTEで動かすライブラリを書いてみた。

この記事について

この記事ではFUTABA社製のホビー用サーボモータRS304をWio LTE(Arduino)で動かすためのライブラリを紹介します。 現在のところWio LTE, Arduino Leonardoでの動作を確認しています。まだまだ作成中ですのですが、最低限の機能が実装できたので公開します。

ライブラリのインストール

   ライブラリは以下のGitHubリポジトリで開発しています。ダウンロードしたzipをArduino IDEに読み込ませるか、ライブラリフォルダにおくことで使えます。 利用方法はreadmeをサンプルを確認してください。

github.com

現在対応しているサーボの動作は以下の通りです。

  1. サーボの角度指定
  2. トルクのON, OFF, BREAK
  3. 角度の取得

サーボとArduinoの接続回路

以下、先人の回路を参考にして下さい。74HC125で半二重全二重の変換回路を組みます。

制限事項

 現在のところサーボのコンプライアンス制御や細かい設定は実装していません。徐々に実装していく予定です。また、最低限の動作しか確認していませんので、動作は保証できません。さらにハードウェアシリアルの利用が必要です。ソフトウェアシリアルは現在は対応していませんが、今後対応してく予定です。

まとめ

 使ってみて不具合や対応してほしい、提案などあればコメント欄やGitHubのIssueにあげていただけるとありがたいです。未実装機能の中で希望があれば、優先して実装していきたいと思います。また、プルリクエストや提案があれば対応いたします。現在のところ@lutecla16vさんがLeonardoでの動作報告とESP32へのインポートを検討されています。

AMG8833のデータを簡易サーモグラフィぽくブラウザで可視化(前編)

この記事について

この記事ではサーモパイルセンサ(温度センサアレイ)を利用し、サーモグラフィを作成した内容を記載しています。今回は赤外線温度センサアレイとしてAMG8833を利用しています。スイッチサイエンスさんから購入することができます。なお、この記事はデバイス側の実装までを紹介した前編です。サーバ側の実装は後編で紹介しています。(2017/01/06追記)

masato-ka.hatenablog.com

AMG8833について

AMG8833は赤外線温度センサが8x8の2次元アレイになっているセンサです。Panasonicから発売されています。エアコンなどに搭載し、室内の人の位置などを検知することを目的に作られているようです。計測温度は0度〜80度です。電源とI2Cの端子のみでデータを取得することができます。ブレークアウト基板に実装されたものは1万円程度するものがほとんどです。そんな中スイッチサイエンスさんから4000円代でContaと呼ばれるスイッチサイエンス社規格の拡張ボード向け部品として発売されています。

www.switch-science.com

もちろん、端子を使えばブレットボードに直差しで動かすことが可能です。今回はこのモジュールから取得したデータをサーモグラフィ画像ぽくヒートマップを表示します。

ヒートマップ表示の検討

初期検討

GUIのプログラミングをするのが面倒だったので、WEBブラウザで簡易的なヒートマップを作成することにしました。そのため、AMG8833からI2Cで取得したデータを何らかの方法でWEBブラウザに送る必要があります。基本方針としてはマイコンで取得したデータをWEBサービスに送り、そこからWEBブラウザに表示するようにしました。デバイスからサーバ間はHTTPでデータを送信します。デバイスからのセンサ値をサーバ側で受診後、すぐにWEBブラウザを更新したいため、サーバとWEBブラウザの通信はリアルタイムな通信を利用したいと考え、今回はSSE(Server sent event)を採用しました。まとめると今回の構成は以下の図のようになっています。

f:id:masato-ka:20180105164439p:plain

バイスの実装

AMG8833からのデータ取得

データ取得にはESP8266(WROOM-02)を利用しています。I2Cで取得したデータを外部のサーバに送りたかったのとある程度のCPUパワーが欲し句、手持ちで使えそうなものを選択しました。今回はこれ以外にもデバック用にOLEDディスプレイをI2C経由で接続しています。上記で紹介したAMG8833はI2C用のプルアップ抵抗が付属していないのでI2CのSDAとSLCラインそれぞれにプルアップ抵抗(10kΩ)を入れています。OLEDディスプレイ側についてるのでなくても問題ないかもしれませんが、念のため入れておきます。

ライブラリの利用

AMG8833はAdafruitからライブラリが公開されています。今回はこちらのライブラリを利用しました。Arduino IDEを利用している場合はIDEのライブラリの管理からインストールすることができます。

github.com

AMG8833はI2Cのアドレスを入力ピンへの入力で0x68と0x69のどちらかに指定することができます。Adafruitのライブラリはデフォルトで0x69が指定されていますが、スイッチサイエンスのボードは0x68が設定されています。(基板上に実装されている端子をショートすることで切り替えできます。)そのため、ライブラリを利用する場合はアドレスを明示的に指定する必要があります。データを読み出し、OLEDにヒートマップを読み出すコードは以下のようになります。

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#include "SSD1306.h"

const int pixel_array_size = 8*8;
const float thd = 29.0;
float pixels[pixel_array_size];

Adafruit_AMG88xx amg;
SSD1306  display(0x3c, 4, 5);

void setup() {
    Serial.begin(115200);
    bool status = amg.begin(0x68);//(1)
    Serial.println("-- Thermal Camera Test --");
    if(!status){
        Serial.println("AMG88xx is not available. Please connect the sensor.");
        while(1);
    }
    //OLED Initialize.
    display.init();
    display.flipScreenVertically();

}

//Draw rectangle to OLED.
void black_rect(int x, int y, int size){
    display.drawRect(x,y,size,size);
}

//Draw rectangle to OLED.
void circle(int x, int y, int radius){
    int r = radius/2;
    display.drawCircle(x+r, y+r, r);
}

//Draw X to OLED.
void cross(int x, int y, int size){
    
    for(int i=0; i < size; ++i){
        display.setPixel(x+i, y+i);
        display.setPixel(x+size-i, y+i);
    }
}

//Draw fill rectangle to OLED.
void white_rect(int x,int y, int size){
    display.setColor(WHITE);
    display.fillRect(x,y,size,size);
}

//Draw heatmap image.
void draw_display(float pixels[], float thd){
    int x=0;
    int y=0;
    int size = 7;
    for(int i =0; i < pixel_array_size; ++i){
        if(i%8==0){y+=size;x=0;}
        x = size * (i%8);
        if(pixels[i] > 24 && pixels[i] <= 29){
            cross(x,y,size);
        }else if(pixels[i] > 29 && pixels[i] <= 34){
            circle(x,y,size);
        }else if(pixels[i] > 34){
            white_rect(x,y,size);
        }else{
            black_rect(x,y,size);  
        }
    }
    Serial.println("");
}

void loop() {
    amg.readPixels(pixels);//(2)
    Serial.println(" ");
    delay(1000);
    display.clear();
    draw_display(pixels, thd);
    display.display();
}
  • (1) AMG8833のイニシャライズ時にI2Cのアドレスを指定します。
  • (2) readPixelsメソッドにサイズが64のfloat型配列を渡し、計測値を取得します。

実行すると以下のようにOLEDに8x8のデータが表示されます。温度に応じて表示される図形が変わります。

f:id:masato-ka:20180104162232j:plain

まとめ

最終的に実装したデバイス側のソースコードGitHubに公開しています。

github.com

64要素のfloat型配列をそのままJSONとしてサーバ側に送信し続けるコードになっています。次回はこのデータを受けて、ブラウザにヒートマップを表示する実装を紹介します。

RN4020でI2Cの値を読み取る

この記事について

この記事ではRN4020のI2Cを利用する方法について紹介します。RN4020にはI2Cポートが付いています。EEPROMなどを接続しデータを一時的にためておくために利用できます。もちろん他のマイコンと同じようにI2Cポートをもったセンサを接続することができます。そこで、RN4020のI2Cポートに温湿度センサを取り付けて動作させてみました。

RN4020のI2C仕様について

 RN4020は21Pinと22PinがI2Cのポートとなっています。データシート上では21PinがSDA, 22PinがSCAになっていますが、実際には22PinがSDA, 21PinがSCAと逆になっています。(2017/10/16現在)秋月電子のボードも他のブレークアウトボードもデータシートにならって軒並み逆に記載されています。そのため基板の印字と回路図を比較する必要があります。おそらく逆につければ大丈夫です。I2Cバスのプルアップ抵抗はRN4020についていないません。そのため、センサモジュールについていなければ別途つける必要があります。ロジックレベルは3.3Vです。  また、RN4020のI2Cはファームウェアのバージョンが1.20以降で利用できます。現在販売されているものは1.23が多いようです。(最新はバージョン1.3)念のため、シリアルからVコマンドを使ってバージョンを確認しておきましょう。  RN4020はI2Cのマスタとして動作します。スレーブ動作は設定できません。また、EEPROM の読み書きを実行するコマンドがありますが、それ以外は指定データをシリアルバスにそのまま流す低レベルなAPIしかありません。

I2Cのコマンド

RN4020でI2Cを利用するためには以下の5つのコマンドを覚えれば大丈夫です。以下の5つのコマンドの組み合わせでI2Cのスレーブにアクセスします。

コマンド 用途
]A I2Cポートの初期化
]C I2Cのイベント制御
]Z I2Cポートの開放
]W データの書き込み
]R データの取得

I2Cコマンド利用方法

 今回はHDC1000と呼ばれるI2Cインタフェースの温湿度センサから温度の値を読み取る方法を例にとり、コマンドの使い方を説明します。 このセンサは前まで秋月電子通商で手に入りましたが最近は廃盤になったようです。センサのアドレスは7bitアドレスで1000000を持っています。上記のコマンドを使ってHDC1000から温度データを取得するには以下のように実行します。

]A,1,2 //(1)
]C,0 //(2)
]W,80020000 // (3)
]W,8000 //(4)
]C,1 //(5)
]W,81//(6)
]R,02 //(7)
6541 //16進数表記
  • (1) I2Cの初期化

最初の引数1はI2Cのクロックスピードです。100kHzを指定します。4を指定すると400kHzになります。また2番目の引数はGPIOを1,2,3,4,7で指定します。指定したGPIOは出力モードとなり、I2Cのスタート時にHighになります。スレーブの電源として利用することで、普段は電源を切っておくことができます。今回はGPIOを使わずに実験のため3.3Vの電源に直接接続しています。

  • (2) I2Cのスタート

]Cの引数に0コマンドをつけ、I2Cのスタートビットをバスに流します。この時、I2Cの初期化で指定したGPIOがHighになります。

  • (3) HDC1000の初期化

HDC1000はデータの取得方法など個別に細かく設定することができます。起動時に0x02のレジスタに値を書き込みます。今回は0x0000を書き込みます。詳細は以下のデータシートを参考にしてください。

]Wコマンドは指定されたバイト列をMSB側からバスに出力するコマンドです。データにバスを流すためのコマンドですので必ずしもスレーブへのWrite要求を出すコマンドではありません。そのため、I2Cの先頭バイトには7bitのスレーズ指定のアドレスと1byteのRead(1)/Wrie(0)を指定する必要があります。今回、HDC1000は2進数7bit表記で1000000がアドレスになります。最後にWriteを表す0をつけることで書き込みを表します。その後、書き込み先レジスタアドレス0x02と書き込みデータ0x0000を付与します。  実際にこの時の出力をロジックアナライザで確認すると以下の図のようになっています。

f:id:masato-ka:20171017075459p:plain

もしデバイスアドレスが8bit表記であれば左へ1bitシフトしたものにRead/Writeのbitを付け足します。(MSB側は必ず0になっているはず。。。)

引き続き]Wコマンドでレジスタ0x00へアクセスします。HDC1000ではこのジレスタにアクセスすることで、センサないのA/Dが温度の値を変換することになっています。Write要求ですが特にデータは書き込まず問題ありません。同じようにいかに信号の状態を出力しておきます。

  • (5) I2Cリセット

温度を読み取るまでのRN4020側の書き込みは完了したため、一度I2Cのバスを解放します。

(4)から(5)までのロジックアナライザ上での動作になります。

f:id:masato-ka:20171017075506p:plain

  • (6) リード要求

RN4020からリード要求を出します。この場合もバスに信号を流すため]Wコマンドを利用します。0x81はアドレス1000000のLSB側にRead要求の1を足したものになります。 I2CバスにREAD要求のコマンドが出力されます。

  • (7) データの読み取り

I2Cのデータの読み取りはリードコマンド]Rを使います。引数は受信するバイト数でここでは2バイトを表します。HDC1000の場合結果は4桁の16進数で帰ってきます。これを指定された式で計算して温度値を読み取ります。

(5)から(7)までのロジックアナライザ上での動きは以下の通りです。前述の説明と照らし合わせてみてください。

f:id:masato-ka:20171017075453p:plain

以上でRN4020のI2Cの値の読み取りになります。]Wと]Rの使い方に気をつければ他のデバイスやアクセス方法でも問題なく利用できると思います。ロジックアナライザの出力とコマンドを照らし合わせると出力がどうなるか理解できるかと思います。

I2Cスクリプトサンプル

I2Cはもちろんスクリプトモードからも利用できます。上記の例を参考に温度データを一定間隔でNotifyするスクリプトです。キャラクタリスティックには2byteでRead Notifyが指定されています。スクリプトとプライベートサービスの詳細は過去記事を御覧ください。

masato-ka.hatenablog.com

@PW_ON
A

@CONN
]A,1,2
]C,0
]W,80020000
]W,8000
]C,1 
SM,1,00002710

@TMR1
]W,81
$VAR1=]R,02
SHW,000B,$VAR1
SM,2,00002710

@TMR2
]W,8000
]C,1
SM,1,00002710

@DISCON
]Z
A

上記例では温度の変換命令''']W,8000```と読み取り命令を別のタイマーイベントとし、相互に繰り返すようになっています。(お互いのタイマーイベントを指定している。)これはHDC1000の温度変換の結果がくるのを少し待たないといけないためです。(ハードウェア割り込みもありますが今回は不使用です。)

まとめ

今回はRN4020でI2Cを利用してみました。I2Cもスタンドアローンで利用できるので、I2Cのセンサをつないでお手軽に利用することができます。簡単なセンサーデバイスはすぐに作れそうです。注意点としてはデータシート状のI2CのピンSDAとSCLが逆になっている点、]W,]Rのそれぞれの使い方です。ここさえ押さえればすぐに利用できます。データシートは何年もほったらかしのようですが、いつか修正されるのでしょうか。。。

Web Bluetooth APIと自作BLEデバイスで戸締り確認をしてみる。

この記事について

 この記事ではWeb Bluetooth API戸締り確認アプリを紹介します。デバイス側はRN4020を使って実装しました。Web Bluetooth APIとRN4020を使ってBLEのアプリを作ってみたかったので、製作しました。実用性はありませんが、それぞれの使い方を覚えるのには大変良さそうな題材です。

戸締り確認アプリ

戸締り確認アプリは大まかに以下の仕様になっています。

  1. BLE経由で鍵の開閉を確認することができる。
  2. 鍵の状態が変わったらBLE経由で通知が来る。
  3. 鍵が開場した場合にブザーが鳴る。

バイスの紹介

今回RN4020で作るBLEデバイスにはホール素子とブザーが付いています。ホール素子は磁石が近づくと信号を出力するセンサです。自転車の速度計などに利用されています。また、ブザーについてはRN4020のデジタル出力で直接駆動できないため、トランジスタで増幅しています。抵抗値などはかなり適当です。

f:id:masato-ka:20171001123639j:plain

実体配線図っぽいのは以下の通りです。

f:id:masato-ka:20171001132146p:plain

RN4020のサービスとキャラクタリスティックは以下のように設定しました。一つのサービスに開閉のデータを送るキャラクタリスティックとブザーを制御するためのキャラクタリスティックの2つを設定しています。また開閉のキャラクタリスティックについてはReadとNotifyの2つを設定しています。後ほどスクリプトでRN4020のIOポートとつなげるため、データ長は1バイトにしています。(単純な動作なので)

  • サービス
    • UUID 123456789012345678901234567890FF
    • 鍵開閉のキャラクタリスティック
      • UUID 12345678901234567890123456789011
      • Mode Read,Notify
      • Length 1byte(0x02の場合ロック,0x00の場合アンロック)
    • ブザーのキャラクタリスティック
      • UUID 12345678901234567890123456789022
      • Mode Write(応答なし)
      • Length 1byte(0x04の場合に発音,0x00の場合に消音)

実際のコマンドは以下のように設定します。

PS,123456789012345678901234567890FF
PC12345678901234567890123456789011,12,01
PC12345678901234567890123456789022,04,01

実際に指定したスクリプトは以下のスクリプトを設定しました。

@PW_ON
|O,04,00
|O,04,%000E
A

@CONN
SM,1,000F4240

@TMR1
$VAR1 = |I,02
SHW,000B,$VAR1
SM,1,000F4240

@DISCON
A

スクリプトやその他設定の方法については以下を参照してください。

masato-ka.hatenablog.com

Webブライザ側のアプリケーションについて

Webブラウザ側のアプリケーションについては以下のUIを作りました。AugularJSとを利用して作成しています。

f:id:masato-ka:20171001120601p:plain

connectを押すとBLEの接続要求が実行されます。またreadやSubscribe/Unsubscribeでデバイス側のホール素子の値を取得します。

ソースコード全体については以下のリポジトリに置いてあります。

github.com

アプリの実行

アプリの実行時の動作を動画にしてみました。ブザーの音がするので音量は控えめにしてください。

www.youtube.com

バイスへの接続ご、サブスクライブ(デバイスからのNotifyをスタート)を行い、画面上のLock Unlock表示が変わります。また、Alertをセットすることで、Unlock時にブザーが鳴るようになります。

まとめ

Web Bluetooth API とRN4020を使うことで簡単にBLEを使ったアプリケーションを作ることができました。今回は半日程度で両方実装できたので非常にお手軽だったと思います。BLEで何かしようと思った場合、スマフォなどのアプリは作れるけど、そもそも取り扱えるBLEデバイスの種類がないので面白いことができないといった場合にはRN4020でサクッとデバイスを作ってしまうのもいいかもしれません。また、自作のBLEデバイスを作ってみたけれど、コントロールするスマフォアプリを作れない、市販デバイスを気軽にハックしたいという場合はWeb Bluetooth APIを利用するとサクッと見栄えのいいアプリが作れると思います。コンセプトを試したいときなどアイディアの試作に利用できそうです。

今回の作例を使ったワークショップを2017年10月20日に開催予定です。どなたでもご参加いただけます。

connpass.com