こんにちは。LINE Thingsの開発を行っている伊藤(@cpulabs)と川田(@hktechno)です。 Advent Calendar 2018の5日目になります。
LINEはソフトウェアの会社だと思われる方も多いと思いますが、これから紹介する内容はLINE Developer Day 2018にて公開したLINE Thingsのハードウェア開発に関する内容です。 LINE ThingsはLINEアプリケーション上でBluetooth Low Energy (以降、Bluetooth LE)に対応したデバイスをLINE Front-end Framework (LIFF)を用いて操作することが出来るIoTプラットフォームです。この記事で紹介するのは、LINE Thingsの概要とその検証・デモのために作成した社内向けにデバイスについてです。

まずは実際に作ったものを見ていただいたほうが早いですね。社内で開発した体重計のデモデバイスの動画を用意したので実際の利用イメージも合わせてご覧ください。
御覧頂いたとおりLINEのアプリ上から計測した体重を見ることができます。現在はまだリリースしていませんが、自動通信を用いて体重計に乗っただけでその値を表示できるようにもなります。
そしてもう一台は電子ペーパーを使用したデバイスです。

必要時以外は電源を切っておくことで無電源のまま表示内容を維持することができます。もともとは電子名刺として使用できるようなデバイスとして開発をしていましたが、 今ではLINEの友達登録のQRコードを表示するデバイスとして使われることが多いです。
LINE Thingsは、利用者目線だけではなくデバイス開発者にとってもメリットがあります。 通常、このようなBluetooth LEを使ったデバイスを作る際、それ専用のアプリも作らなくてはなりませんでした。しかしLINEのLIFFを使うことによって 専用のアプリを作る必要はなく、JavaScriptでLINE ThingsのLIFFを記述するだけで、機能を追加したりUIを変更したりすることが容易にできます。
LINE ThingsとLIFFについて詳しく知りたいという方や、実際にLINE Thingsに対応したデバイスを作りたい方はこちらも参考にしてみてください。
LINE の IoT プラットフォーム LINE Things の Developer Trial を試してみる
Bluetooth LEについて
Bluetooth Low Energyの略です。BLEなどとも言われます。Bluetooth規格の一部として、Bluetooth 4.0から追加されている低消費電力の通信モードです。 現在ではウェラブルデバイスを中心に小型でバッテリ駆動のデバイスで広く使用されています。
GATT ServiceとGAT Profileはそれぞれ固有のUUIDを持っており、Masterとなるデバイス(Bluetooth LEではCentralといいます)はSlave(Bluetooth LEではPeripheral)のUUIDで管理されたCharacteristicを読んだり 書いたりすることで通信をすることができます。なお、LINE ThingsではCentralはLINEアプリ上のLIFFとなり、Peripheralはこれから紹介するようなDeviceです。 Bluetooth LEに対応するデバイスのUUIDはBluetooth SIGによって策定されています。
GATT Services | Bluetooth Technology Website
例えば体重計は予め策定されているUUIDを使用して実装しました。体重計のようにBluetooth SIGで予め定義 されているGATT ServiceのUUIDは16bitで定義されています。 ユーザー独自の規格で作りたい場合や、そもそもBluetooth SIGで策定されていないようなデバイスも作ることができます。 その場合はUUIDは128bitで定義する必要があります。
世の中にはBluetooth LEに対応するデバイスがたくさんあるので、Central側はそのすべてのUUIDのデータベースを持っているわけではありません。 Bluetooth LEではAdvertisingパケットを飛ばすことで、SlaveデバイスがどのようなUUIDを持っているか等を予め送信することが可能です。 これにより、Centralはデバイスが持つUUIDを知り、それにアクセスすることでデバイスと通信を行うことが可能となります。 もちろん、UUIDを知ったからと言ってそのCharacteristicが何を意味しているかなどはCentral側は知るすべがありません。 ここは予め策定しておきCentral側とSlave側で共有しておく必要があります。
Bluetooth LE体重計

ハードウェアの説明
まずはハードウェアについて説明します。Bluetooth LE体重計では、ロードセルというセンサーを使って実際の体重を得ています。

ロードセルは圧力が加わると抵抗値が変化する素子です。非常に安価でありながら比較的高い精度が出るため、市販の体重計でもよく使用されています。 今回は4つ使用してブリッジ接続をするようにしています。
ロードセルで得られる抵抗値の変化は非常に微弱なので、そのままマイコン内臓のADCで読んでしまうと 分解能が足りなく精度が落ちてしまいます。そのため、通常このようにアナログな値を出すセンサをマイコンに繋げる場合はOPAMPなどを使用してマイコンのADCの電圧レンジ に合うように増幅します。しかし、このような回路を作ってしまうとどうしても部品数が多くなり、作るのも大変になります。そして調整もしなくてはなりません。 幸い、HX711というロードセル用のOPAMPとADCが内蔵されたICが市販されています。どうやら体重計や小型のスケール向けに作られているICのようで、今回はそのICを用いて制作しました。
体重計の回路図はこのような感じになります(回路図:ws-sch)。
回路図に書いてある部品のうち、いくつかは機能検証のために実際には実装して
使用したマイコンはNordic SemiconductorのnRF52832というデバイスです。このマイコンはBluetooth LEモジュールが搭載されているマイコンですが、このデバイスを Bluetooth LEを使う目的でそのまま使用するのは電波法的に問題があります。通称技適(技術基準適合証明)を取得しないと簡単にはそのデバイスを使用できません。 今回はそのnRF52832が搭載されているRaytac社が開発したMDBT42Qというモジュールを使用しました。このモジュールはすでに技適を取得済みなので、安心して使用することができます。 nRF52832以外にもESP32というマイコンもBluetooth LEモジュールを内蔵しており、安価なことからホビー用途で広く普及しています。ただ、このマイコンはBluetooth LEだけではなくWifiモジュールも搭載しており今回の用途には オーバースペックであるということと、nRF52832よりも消費電力が大きいようなので今回の用途には適しませんでした。
電源はPCのマザーボードなどでもよく使われていて入手性も比較的良いCR2032にしました。そのため、回路自体は3Vの電源で動作しています。CR2032は容量があまり多くないのですが、 Bluetooth LEや他に使用している部品の消費電力も問題ないことから採用しました。

この体重計ではキャラクタディスプレイで体重を表示することもできます。しかし、一般的に出回っているキャラクタディスプレイは5V仕様になっており、今回電源で使用している3Vでは表示することはできません。 キャラクタディスプレイで使用している液晶のロジック部は3.3Vでも動きますが、問題は液晶モジュールです。液晶の表示にはある程度の電圧差が必要みたいなのですが、今回はICL7660というチャージポンプICで-3Vを生成して、 電源電圧である+3Vとの電位差を生成することで表示するようにしました。少しトリッキーではありますが、ホビーユーザではよく知られた方法です。

こちらがメイン基板です。メイン基板といったのには理由があります。実はこの体重計の筐体はすべて基板で作られています。 人が乗る部分のパネルも3.2mmの分厚い基板を2枚、センサーを取り付けるために底上げしている部品も1.6mmの基板を数枚重ねています。 基板で作る必要性はなかったのですが、ある程度強度があり形を自由に整形出来ること。そして比較的安価に作ることができます。 納期や注文までのフローも経験上わかっていたため、今回はこのようにしました。
ファームウェアの説明
nRF52832はArduinoに対応ているので、今回のようなデバイスを簡単に作成できます。 実際に体重計とこのあとに詳しく紹介する電子ペーパーディスプレイはAdafruitが公開しているnRF52832用のArduino環境を用いています。 それらの詳細に関してはこちらを参考にしてみてください。
adafruit/Adafruit_nRF52_Arduino: Adafruit code for the Nordic nRF52 BLE SoC on Arduino
ファームウェアでやることは至ってシンプルです。ロードセルで得られた体重データをBluetooth LEのCentralに送ることとキャラクタディスプレイに表示をするということだけです。 しかし、小容量のバッテリ駆動ということもあって、いくつか工夫している点があるのでそれを紹介していきたいと思います。
まず、家庭用電源に接続されるような機器であれば問題ないのですが、電池は電池残量が減るに従って電圧も下がってしまうという特性があります。 ロードセルから得られるセンサの値はアナログであり、電源電圧の補正などもないため、電池残量が減るとセンサから得られる体重の値が変化してしまいます。 そのため、キャリブレーションしたデータを使用していても、電源電圧が変化してしまえばそのままその値を使用することができません。 ハードウェア的な解決方法として、電圧を一定にする電源レギュレータや、DC-DCなどを使うのもよいのですが、比較的効率の良いDC-DCであっても変換効率は80~90%ほどで、残りは熱として消費されてしまいます。 そのため、今回は電池の電圧をそのまま使用し、ソフトウェア的に解決するという
まずはじめに電圧の変化に伴い測定値がどのように変化するかを確認しました。その結果、電圧の変化に対して得られる測定値はリニアに変化することがわかり、 電圧に応じて単純に係数をかけるだけで電圧変化に対して安定した体重を得ることができました。 このように、ハードウェア、ソフトウェアともに解決方法がありますが、場合によって最適な方法を探さなくてはなりません。それが組み込みの面白さですね。 次に行った対策は根本的に、ロードセル周りの消費電力を減らすことです。普通に自宅で使用する体重計といえば、使用前にいちいち電源スイッチなんて押さないですよね? 体重計に乗ったら自動的に電源がついて(ついたように見せかけて)体重が液晶に表示されます。今回作るデバイスもそのようにしたかったので、常時電源ONでソフトウェア的に電力を減らす仕組みを持っています。 まず、ロードセルは微弱ではあるものの値を読むために常に電流を流しています。しかし、体重計として使用する上でセンサの値を高速に読み続ける必要はありません。 一定期間ごとにセンサ周りの回路の電源を入れ値を読むようにしています。こうすることでセンサとセンサのアンプ周りの消費電力を一気に落とすことができます。
次に、Bluetooth LEでCentralとどのように通信を行っているかについて説明します。 体重計デバイスは予めBluetooth SIGが策定しているBluetooth Serviceを使用しました。 体重計なのでUUIDは 0x181D
と定義されています。
Centralがデバイス側の値を読む手段としては、CharacteristicのRead, Indicate, Notifyなどがあります。
- Read : 単純に読むことが出来る
- Notify : デバイス側がCentralにデータを送りつける
- Indicate : ReadとNotifyの組み合わせ (デバイス側がデータを送ることも出来るしCentralが読むことも出来る)
例えばWeight MeasurementはIndicateがMandatoryとなっているので、デバイス側から測定した体重データを送信し、 Central側も任意のタイミングでその値を読み込めるように実装する必要があります。 その他、Battery Service (UUID : 0x180F
)も実装しています。これは電池で動いているデバイスの電池残量を0~100%でCentralが 知ることが出来るサービスです。
体重計は予め定義されているATT ServiceのWeight ScaleとBattery Serviceで実装したと書きましたが、 それに加えて独自のサービスを追加することができます。その場合は独自に生成した128bitのUUIDで実装する必要があります。 実際、社内で作ったこれらのデバイスでは、LINE Thingsがデバイスを個別に認識するためにProduct Specific Device Id (PSDI)のサービスを追加で実装しています。 Developer Trialでは、PSDIサービスのためのUUIDは固定のService/Characteristic UUIDが指定されていて、この仕様に則りサービスを提供する必要があります。 LINE DevelopersサイトのLINE Thingsのドキュメントから取得できるので、それを使用するようにしてください。 なお、PSDIはデバイスごとに固有の値が必要なので、nRF52832のDevice IDをそのままPSDIとして使用しています。
LIFF アプリ

LIFFアプリは上記の動画でも登場しましたが、今回はあくまでコンセプトなので、体重やBMIを表示する事ができるシンプルなものです。静的なHTMLとJavaScriptだけを使って表示を実現しています。 デバイスからくるNotifyのコールバックを受けて、その値を反映しているだけです。 LINE ThingsではHTMLでUIを記述できるので、Bluetoothを使うアプリでも、簡単にきれいなUIを実現することが出来ますね。LIFFなので、ここで測定した値をそのままLINE Botに送信したりすることもLIFF上から出来ます。
Bluetooth LE電子ペーパーディスプレイ


このデバイスはLINE上から表示したい白黒ビットマップ画像を転送し、それを表示できるデバイスです。 もともとBluetooth LEは低消費電力向けに設計されており、通信速度は従来のBluetoothに比べて非常に低速です。 大容量のデータ転送には向いていないので、一画面すべてを転送する場合15秒程度かかります。 ちなみに、本体にASCIIフォントを内蔵しているので英数字であればすぐに表示させることもできます。 使用方法としては、電池消費を抑える目的から書き換える前にデバイス上のAdvertiseボタンを押して、Bluetooth LEのAdvertisingを開始します。 一定期間CentralからアクセスがないとSleepモードに入って消費電力を抑えます。 ちなみに、Sleepモードのときは0.1mA程度しか消費していません。
ハードウェアの説明
主要部品は電子ペーパーディスプレイです。今回はWave Share社が販売している2.13インチのディスプレイモジュールを使用しています。 このモジュールは少々外付け部品が必要なのですが、SPIでアクセス出来るため非常に使い勝手が良いです。
回路図はこのようになります。(回路図:eink-sch)とてもシンプルでディスプレイの駆動回路とマイコン意外大したものはありません。 このデバイスも電源はCR2032を使用しています。
ディスプレイ周りはWave Shareが公開しているリファレンス・デザインを参考にしているのですが、それで使用されている MOSFETが入手困難で別の部品を使用しています。
このMOSFETと、それにつながるショットキーダイオードは電子ペーパーの最低動作電圧に関わる部分で非常にシビアです。 ここを適当な汎用部品で作ってしまうと、電源電圧が少し下がっただけでもディスプレイリフレッシュ時に真っ暗になってしまいます。 試行錯誤し、現在はその中で一番良い結果であったものを使用しています。
ファームウェアの説明
ファームウェアで行っていることはBluetooth LE経由で送られてきたデータをディスプレイに表示するだけです。もちろん電子ペーパーディスプレイ などというGATT ServiceはBluetooth SIGで策定されていないので、ディスプレイに関する操作は独自のUUIDを定義して 実装しています。 このデバイスも体重計と同じように小容量のCR2032バッテリを使用するために低消費電力にする仕組みを持っています。まず、必要のないマイコン内のモジュールはすべて電源を切っています。使用しているnRF52852は低消費電力にする機能が 非常に豊富です。SPIやUART、TIMERなどの内蔵しているモジュールごとにそれぞれPower ON/OFFがソフトウェア的に行うことができます。 さらに、このマイコンは外付け部品は必要ですが、内部のCPUコア電圧を供給する電源レギュレータの代わりに、内蔵DC-DCを使用して 供給することもできます。その他、割り込みが入るまでCPUをSleepにさせたり、不要なRAM領域の電源をOFFにできたり等非常に高機能です。このような機能を使うために、今回作ったデバイスではAdvertiseボタンが押されるまでCPUはBluetooth LE通信モジュールを含め不要な内蔵モジュールを切り、 Sleepモードにしています。ボタンが押された段階で割り込みから復帰して必要なモジュールをONにします。 そして、ボタンが押されてから3分以内にBluetooth LE経由でアクセスがない場合は再びSleepモードに入って電池の消費を最小限に抑えるようにしています。
LIFF アプリ

電子ペーパー向けのLIFFアプリは、LINEプロフィール情報の表示ができるモード、自由にテキストが配置できるモード、好きな白黒画像を表示できるモードの3つを用意してみました。 また、複数デバイスの同時接続に対応していて、同時に複数台の表示を書き換えることも出来ます。
上記の画像は、LINEプロフィール情報を表示している様子です。名札のように使うことができるようになっています。LINEのアカウントと簡単に連携できるのは、LIFFならではの機能だと思います。 LINEアカウントの情報は、LIFFのAPIを利用して取得できるので、デバイスとの連携も簡単にできます。
今回利用した電子ペーパーモジュールは、階調表示に対応しておらず、解像度も特殊なため、白黒の画像へ2値化とリサイズをCanvasをつかってLIFF上で行っています。このLIFFも、HTMLとJSのみで、サーバー側で動的な処理は行っていません。スマホのパワーとAPIを使って画像処理まで出来てしまうのも、LINE Thingsの利点ですね。
まとめ
いかがだったでしょうか? 「LINEってハードウェアやってるんだ」と意外に思った方も多いかもしれません。 実際、業務中に社内ではんだ付けするのは少し勇気がいりましたけどね!
もちろん、LINE Thingsとしてリリースしているのはプラットホームではあるのですが、このようにデモデバイスがあることで リリース前に必要な機能のチェックや利便性の追求ができました。今回紹介したデバイスはLINE Thingsの機能の一部を使用したデバイスですが、 皆さんも自分自身で実際に作って確かめてみることができます。 LINE Things Starter を用意しているので皆さんも是非試してみてくださいね。
これからも LINE Things のハンズオンやイベントなどを開催する予定でいるので、そのときには上記のデバイスを触っていただける機会があると思います。 興味がある方は、そのときにぜひ私達 LINE Things のメンバーに声をかけてみてください。 みなさんが LINE Things で作ってくれたものも、ブログや Twitter を利用して公開していただけると嬉しいです。
明日の記事は、くじ@uturned さんによる「ExcelのピボットテーブルをElasticSearch+Kibanaにしてみた」です。