JavaScript
Node.js
websocket
bluetooth
node-red
Node-REDDay 16

あなたやわたしやあの子のドキドキと気持ち - BLE心拍センサの可視化、配信

TL;DR

  • 市販心拍センサーは、BLE GATT標準プロファイルで、毎分心拍数や、「気持ち」が反映される心拍のゆらぎまで取れる
    • 今回はPolar H7を使用
  • Node-REDのカスタムノードで簡単にそれらを扱える(npm: node-red-contrib-ble-heart-rate)
  • 他の機能、ノードと組み合わせて可視化したり、配信したり色々したら楽しかった
  • 今回はnode.jsスクリプトからのカスタムノードを作ったが、流れを掴めば想像より簡単だった

はじめに

Boom, Boom, Boom, b-b-boom...My heart beats! 懐かしいなと思ったら再生しながらどうぞ。

トレッドミルの耳たぶクリップセンサや、スマートウォッチでワークアウト時に負荷を測る、など身の回りで自分の鼓動を使う例も多くなってきました。

しかし、それらは主に、予め用途別に用意され、閉じられたアプリケーションの中で使います。 MOTTAINAI.

主なBLE(Bluetooth Low Energy)心拍センサは、標準のプロファイルから主要なデータを読み取ることができ、自分で活用できます。

例えば、

  • ゲームやスポーツ配信に自分の心拍をのせるもよし
  • ためて自分の感情や眠りの様子を分析するもよし
  • 毎分心拍数だけでなく、機種により感情(自律神経の状態)が反映された心拍のゆらぎがとれることも

ということでNode-RED Advent Calendar 2017 12/16のテーマはハートビート、Node-REDを使って心拍からのぞく、あなたやわたしやあの子のドキドキと気持ちです。

とりあえず試す: 自分のドキドキと気持ちのうつろいを眺める

必要なもの

  • BLE心拍センサー
  • Node-RED導入済み、かつnobleを使いBLE接続できるPC等

ステップ

  1. 心拍センサーを準備
  2. ble heartrateノードを導入
  3. 簡単なフローで動作確認
  4. リアルタイムでグラフ化
  5. その他のアイデア
    1. 配信
    2. キューイング

心拍センサーを準備

今回はPolar H7心拍センサーを使います。
胸囲にバンドを巻き、心臓近くの皮膚に密着した電極から心電を取り、それを分析した毎分心拍数、心拍のゆらぎを1秒ごとにBLEとして飛ばしてくれます。

polarH7.jpg

ほかにも下記を買う、とか友達に借りるなりすると動く(はず)。

ble heartrateノードを導入

一般にBLEセンサーデバイスからデータには、Services/Characteristicsといった「番地」が定められています。ベンダ独自のものと、用途に応じてベンダ共通で定められているものがあります。今回はベンダ共通のものを使います。

参考 心拍についてのベンダ共通のとりきめ

BLE GATT profile: heart rate service
BLE GATT profile: heart rate measurement

Node-REDを動かしているPC等の近くに、BLE GATTプロファイル準拠した心拍センサがいたら、上の仕様に従い、データを取り出してNode-REDで使えるようにしてくれるカスタムノードを作り、今回公開しました。(それなりの試行錯誤があったので、需要があればまたの機会にまとめます。)

そのノードを、npmからインストールします。

$ cd .node-red
$ npm i node-red-contrib-ble-heart-rate

ノードの中身、詳細が気になる方は、こちらを参照ください。使うだけなら飛ばして大丈夫です。

npm: node-red-contrib-ble-heart-rate

github: tomo-makes/node-red-contrib-ble-heart-rate: A contributed Node-RED node, that retrieve data from BLE heartrate monitors.

簡単なフローで動作確認

Node-REDを立ち上げ、左のパレットに ble heartrate というノードが取り込まれていることを確認します。
まず、下記のようにdebugへ直接流すシンプルなフローを組み、デプロイします。

20171216_advent_simple_debug.png

ble-heartrate ノードは下記インジケータを持ちます。

ステータス 説明
scanning 近くのBLEデバイスを探す
discovered 近くにBLEデバイスが見つかった
connected BLEデバイスに接続した
disconnected BLEデバイスから切断した
waiting 次のscanまで10秒待つ

装着した心拍モニタをonにしてしばらくすると scanning -> discovered -> connected とstatusが変わり、debugが出力されはじめます。
( ble-heart-rate v0.2.0 では、debug、consoleどちらも確認できます)
遷移しない場合、Node-REDの稼働するPC等のBluetooth機能off/onを試してください。

余談: 案外ばらついている心拍、ゆらぎとは

  • console.log例
Flag: 22  HBR:73  RRI1:870  RRI2:NaN
Flag: 22  HBR:72  RRI1:878  RRI2:NaN
Flag: 22  HBR:72  RRI1:895  RRI2:824
Flag: 22  HBR:72  RRI1:878  RRI2:NaN
Flag: 22  HBR:72  RRI1:882  RRI2:NaN
  • HBR:毎分心拍数[回/分]
  • RRI1: 心拍と心拍の間隔[ms]

が毎秒出力されます。心拍と、取得タイミングにより、RRIが2データ(RRI1, RRI2)出力されることがあります。
HBRではさほど変動がないように見えますが、RRIでは変化が見えます。これが心拍のゆらぎです。

リアルタイムでグラフ化

数値だけではピンとこないので、ダッシュボードを導入します。

node-red/node-red-dashboard: A dashboard UI for Node-RED

$ cd .node-red
$ npm i node-red-dashboard

ダッシュボード用のノードが追加されていることを確認し、例えばこのように配置します。

20171216_advent_1.png

ダッシュボード(ゲージや、ラインチャート)は、 msg.payload に入った数値をそのまま表示するため、 ble heartratechart ノードなどの間に、payloadから特定の値のみを取り出す function ノードをはさみました。

  • 例 HBRを取り出す
var newmsg = { "payload": msg.payload.hbr };
return newmsg;

見栄えの調整などをすると、このように、リアルタイムでドキドキを表示できました。

20171216_advent_2.png

上が毎分心拍(ゲージ、ラインチャート)、下が心拍変動=ゆらぎ(ラインチャート)です。上に比べ、下が高精細なデータが取れているのがわかります。

運動したら心拍数が上がる、下がる、は当たり前として、面白いのは:

  • 冷たいビールとかを飲むと、心拍一瞬(数秒のオーダで)早くなる
  • 横になると、心拍がすっと下がる
  • 呼吸に応じた上下が観察される

など、思った以上に自分の心臓が生きている!(当たり前)=環境に対して変動している、ということです。

先に述べた通り、心拍のゆらぎは自律神経の活動を反映しているとされ、周波数解析などを行うと、緊張、リラックスの状態などを推定することもできます。

その他のアイデア

配信する

WebSocketノードを追加すると、離れたクライアントに心拍ストリームを送ることができます。
何の意味があるのでしょうか。

  • 遠距離カップルがLINE常時通話に加えて心拍を共有したり
  • ゲーム配信に心拍がのったり

UIはボタンからタッチスクリーン、声へ変わりましたし、写真、ビデオを超えて自分のバイタルまでコンテンツ化するのですね。きっと。
言うだけならタダです。

下のようにやります。今回は、WebSocketクライアント側はNode-RED上での簡易確認までです。

  • 配信側

20171216_advent_3.png

  • 受信側

20171216_advent_4.png

メッセージキューの導入

信頼性ある心拍配信をしたい場合(あるのか?)メッセージキューを入れることもできるでしょう。

node-red-contrib-msg-queue

$ npm i node-red-contrib-msg-queue

おまけ: カスタムノードの作り方

ここからは、今回contribノード ble-heartrate を作成するにあたって考えたこと、ログです。
カスタムノード作成から公開までの流れは、こちらの記事に非常に詳しくまとまっています。

Node-REDのノードをつくる手順 - Qiita

今回とった流れ

以前にスタンドアロンのnode.jsスクリプトとして、BLE心拍センサからデータを取得し、ごにょごにょするのを書いていました。
今回はその

  • 「あんこ(=元スクリプト)」を

カスタムノード化するため

  • 「もち(=Node-REDカスタムノードのお作法)」でつつみ
  • 「大福もち(=完成したカスタムノード)」を作り
  • 「お店に陳列(=githubおよびnpm公開)」

したという感じです。

もち(=Node-REDカスタムノードのお作法)

  • 三点セット: node-red-contrib-{name}.js, node-red-contrib-{name}.html, package.json
  • js
    • 自前node.jsスクリプトを包む
      • module.exports = function(RED) {}
        • function xxx(config) {}
          • RED.nodes.createNode(this,config);
          • var node = this;
          • (もともとのnode.jsスクリプト)
        • RED.nodes.registerType("xxx",xxx);
  • html
    • 見た目と、プロパティ変数などの定義
    • 設定画面用のhtml
    • 説明文
  • package.json
    • npm initで生成
  • その他

まとめ

  • 市販心拍センサーPolar H7で、毎分心拍数や、「気持ち」が反映される心拍のゆらぎまで取れた
  • カスタムノード化により、他の機能、ノードと組み合わせ(可視化、配信など)を簡単に行えた
  • カスタムノード作成も、流れを掴めば想像より簡単