Genuino 101を使い、BLE(Bluetooth Low Energy)経由で心拍数をAmbientに送って確認する心拍モニターを作ります。

Genuino 101

Genuino 101はArduino LLCが開発したワンボードマイコンです。インテルの32ビットCPU Curie、3軸加速度センサー、3軸ジャイロセンサーとBluetooth Low Energy通信モジュールが搭載され、3.3vで動作します。RAMが24kBと比較的余裕があり、BLE通信ができるので、IoTの実験やプロトタイプ開発には使いやすいボードです。

Genuino 101

プログラム開発はArduino IDEの1.6.7以上を使います。ボードマネージャーで「Intel Curie Boards by Intel」をインストールし、「Arduino/Genuino 101」を選択すればIDEの準備は完了です。

genu-pulse2

genu-pulse3

心拍モニターの構成

心拍センサーには「Pulse Sensor Amped」を使いました。これもスイッチサイエンスさんで購入しました。これをGenuino 101につなぎ、心拍数を計算します。心拍数データーをBluetoothでMacに渡し、MacからAmbientに送信します。

心拍モニターの構成図

Bluetoothで通信する端末のデーターをインターネットに送るには、Bluetoothとインターネットをつなぐゲートウェイが必要になります。Bluetoothとインターネットの通信モジュールが搭載されていてばどんなハードウェアでもいいのですが、ソフトウェアとしてはnode.jsでBLE通信とHTTPリクエストが扱えるので、node.jsが簡単に動かせるものということでMacを使うことにします。

プログラム開発はステップバイステップで

プログラム開発はステップバイステップで、動作を確認しながら進めます。今回は次のようなステップでプログラムを開発しました。

  1. Genuinoで心拍センサーを制御する
  2. GenuinoでBLE通信をおこなう(ダミーデーターを使い、BLE通信の確認のみおこなう)
  3. 1と2を組み合わせ、実データーをBLEで通信する
  4. ゲートウェイ(Mac)でBLE通信をおこなう
  5. ゲートウェイ(Mac)からAmbientにデーターを送信する

ステップ1.Genuinoで心拍センサーを制御する

心拍数の計算はセンサーのメーカーが公開しているプログラムを元に、タイマー割り込みをGenuino 101用に改造したものを使いました。プログラムはGithubに公開しました。

こちらのページ右上の「Clone or download」の「Download ZIP」をクリックするとzipファイルがダウンロードされます。それを展開した中の、examples/Genu_HR/ が心拍数を計算するプログラムです。

心拍センサーをGenuinoのA0ポートにつなぎ、2m秒間隔でセンサーの値を読むと、次のような波形が得られます。底(T)からピーク(P)までの立ち上がりの50%の点を基準点として、基準点間の時間から1拍ごとに心拍数を計算し、10拍の移動平均を心拍数とします。最初は心拍数をシリアルに出力して、動作確認しました。

心拍波形

ステップ2.GenuinoでBLEのペリフェラルを作る

Bluetoothでは、データーを持っている端末をペリフェラル、ペリフェラルにデーターを取りにいく端末をセントラルといいます。通信をする時は、ペリフェラル側が「こんなスペックのサービスがあります」と宣言します(Bluetoothではこの動作をアドバタイズといいます)。セントラル側は周囲にあるペリフェラルをスキャンして、必要なサービスを提供する端末を見つけます。
サービスにはBluetooth SIGによって定義済みのものと、独自に定義するものがあります。心拍数(HeartRate)は予め定義されたサービスの一つです。

Arduinoに、心拍数を答えるBLEペリフェラルのサンプルプログラムがあるので、それをGenuino 101で動かします。A0からデーターを読むようになっていましたが、一旦、ダミーデーターを返すように変更します。

    int hr = 0; // ダミーデーターの定義を追加

    void updateHeartRate() {
    /* Read the current voltage level on the A0 analog input pin.
       This is used here to simulate the heart rate's measurement.
     */

    // int heartRateMeasurement = analogRead(A0);
    int heartRateMeasurement = hr++; // A0の値を読む代わりにダミーデーターを使う
    if (hr > 1023) hr = 0;
    ...

先ほどGithubからダウンロードしたもののうち、examples/Genu_HR_BLE_dummy/ がダミーデーターでBLE通信するプログラムです。

Genuino 101でプログラムを動かすと、アドバタイジングが始まります。セントラル側はiPhoneの「nRF Toolbox」というアプリを使いました。iPhoneで「nRF Toolbox」を立ち上げると、アドバタイジングしているGenuino 101を見つけます。

nRF ToolboxがGenuinoを見つけた

それを選択すると、通信が始まるのが確認できました。

genu-pulse7

BLEでダミーデーターを受信し始めた

ステップ3.心拍数をBLEで送る

ステップ2ではダミーデーターでBLE通信の動作確認をしました。これにステップ1で作った心拍数を計算するプログラムを組み合わせ、実際の心拍数データーをBLEで答えるプログラムにし、iPhoneのnRF Toolboxでデーターを読みます。examples/Genu_HR_BLE/ が心拍数をBLEで通信するプログラムです。

Genuinoからの心拍数を受信

ちゃんと動いています。これでGenuino側は完成です。

ステップ4.MacでBLE通信を行なう

Node.jsにnobleというBLE通信を行うパッケージがあるので、これを使うことにします。
まずMacにnode.jsをインストールします。インストール方法はいろいろなブログに書かれているので、
ここでは繰り返しません。私は以下のサイトを参考にしました。

node.jsのインストールが終わったら、先ほどGithubからダウンロードして展開したディレクトリーでnpm installを実行します。

    $ npm install

これでnobleとnoble-deviceというBLE通信のパッケージがインストールされます。noble-deviceを使って心拍数を受け取るセントラル側のサンプルプログラムがダウンロードされているので、それを動かしてみます。

    $ node node_modules/noble-device/examples/hrm-device HeartRateSketch

Genuino 101でペリフェラル側のプログラムを動かすと、hrm-deviceがペリフェラルを検出し、通信するのが確認できました。

genu-pulse10

ステップ5.node.jsでAmbientに通信する

Node.jsでAmbientに通信するライブラリー(ambient-lib)を作りました。このライブラリーも先ほど実行した npm install でインストールされています。

このAmbientライブラリーをステップ4で作ったプログラムに組み込みます。
hrm-device.jsではmeasumentChangeというイベントで心拍数をコンソールに出力していました。

    device.on('measumentChange', function(data) {
        console.log("update measument: " + data);
    });

ここにAmbientへの送信を組み込みます。Ambientへの最短送信間隔が5秒なので、5秒以上経過したらAmbientに送信するようにします。

    device.on('measumentChange', function(data) {
        console.log("update measument: " + data);
        var _t = new Date();
        var current = _t.getTime();
        if ((current - previous) > 5000) {
            ambient.send({d1: data}, function(err, res, body) {
                if (err) {
                    console.log(err);
                }
                console.log(res.statusCode);
            });
            previous = current;
        }
    });

また、プログラムの先頭近くでAmbientサーバーに接続しています。

    ambient.connect(100, 'WriteKey');

実際にプログラムを動かす時にはチャネルIdとライトキーを、ご自分のAmbientのチャネルIdとライトキーに変更してください。

プログラムを動かすと、心拍数データーがGenuino 101からMac経由でAmbientに送られ、グラフ化されていることが確認できました。

genu-pulse11

今回作ったArduinoとnode.jsのプログラムはGithubに公開しました。

examples/Genu_HR: 心拍センサーで心拍数を測定し、シリアルに出力
examples/Genu_HR_BLE_dummy: ダミーデーターをBLEで通信
examples/Genu_HR_BLE: 心拍センサーで測定した心拍数をBLEで通信
hrm-ambient.js: 心拍数データーをBLE端末から受け取り、Ambientに送信

Genuino 101からBLE経由でAmbientにデーター送信できるようになりました。その過程でnode.jsからAmbientにデーター送信するライブラリーも作りました。これらを使っていろいろと試してみたいと思います。