mbed の環境で Bluetooth LE アプリを書いてみる

The next challenge is, writing my own Bluetooth LE application in the mbed development environment.

前回までで、無事に BLE Nano を使って Bluetooth LE (BLE) アプリを動かすことができましたので、次は自分自身で考える仕様に基づいて BLE ペリフェラルのアプリを書いてみたいと思います。BLE の仕様では、ハートレートモニタや自転車のケイデンスメーターのような典型的(?)アプリについては予め仕様(プロファイル)が決まっていますが、われわれ設計者の現実では、このようなプロファイルに合致しない独自のアプリを書くことが多いかと思います。前回取り上げた Nordic 社の SDK にはいくつかサンプルコードがあるのですが、独自のアプリを書く方法についてはあまり情報が多くありません。

実はその後の調査で、独自アプリの書き方に関するアプリケーションノートを見つけたのですが、私は最初、見つけられませんでした。Nordic SDK の、例えばハートレートモニタ(サービス)のサンプルコードを読んでみると分かりますが、どこまでが SDK の要求仕様で、どこからがアプリケーションの要求に基づくコードなのか、正直言って分かりづらいです。後で分かってみれば、Nordic 社が親切心で用意した ble_sensorsim モジュールが混乱の種ではないかと思ったりします。ble_sensorsim を SDK  に含めてしまうと、ちゃんとしたドキュメントでもない限り、初心者は混乱するのではないかと思います。

そこで、私は ARM Cortex-M0 自体の経験が少なかったこともあり、まずは巷で人気の mbed 開発環境を試してみることにしました。mbed の開発環境は、ツールをローカルのパソコンにインストールする必要がなく、コンパイルはオンラインで実行され、またライブラリやサンプルコードをネット上で比較的容易に検索して取り込むことができるのが特徴です。実際に込み入ったアプリケーションを設計しようとするといろいろ問題もありますが、初心者が最初に ARM Cortex-M0 のマイコンでプログラムを動かすには便利にできているようです。

mbed 開発環境のチュートリアルはたくさんあるのでここでは説明を省きますが、今回は Nordic 社 nRF51 用の BLE サンプルコードを紹介したいと思います。mbed の環境を立ち上げ、ターゲットに RedBearLab BLE Nano(あるいは Nordic nRF51822)を選びます。そしてプロジェクトのインポート機能を使って、Programs の中で「BLE」というキーワードで検索します。すると、次のようにサンプルプロジェクトが見つかります。

スクリーンショット 2015-03-23 17.11.23

今回はこの中から、BLE _HeartRate プログラムを参考にすることにしました。

実際に import してからコードを眺めると、mbed (や Arduino Sketch)の特徴である、C++ に基づくオブジェクト指向言語環境であることが分かります。そのためもあってか、アプリケーションとライブラリが(比較的)綺麗に分けられていて、main.cpp は非常にコンパクトな実装になっています。

プログラム自身は、ある程度経験のある方なら読めば理解できると思いますが、main() 関数の最初のほうで、ハードウェアの設定やハートレートモニタのサービスを登録した後は、以下のような単純なループとなっています。

while (1) {
    // check for trigger from periodicCallback()
    if (triggerSensorPolling && ble.getGapState().connected) {
        triggerSensorPolling = false;

        // Do blocking calls or whatever is necessary for sensor polling.
        // In our case, we simply update the HRM measurement. 
        hrmCounter++;
            
        //  100 <= HRM bps <=175
        if (hrmCounter == 175) {
            hrmCounter = 100;
        }
            
        // update bps
        hrService.updateHeartRate(hrmCounter);
    } else {
        ble.waitForEvent(); // low power wait for event
    }
}

つまり、Ticker(周期コールバックのタイマクラス)を使って 1秒毎にメインループをスケジュールした後は、BLE のコネクションが張られている間、hrmCounter という変数で心拍数をシミュレートしながら(Heart Rate Monitor サービスの)hrService オブジェクトに対して心拍数の更新をかけるだけ、というシンプルな実装です。

現実には、mbed の開発環境には「ツールの背景や動作の仕組が分かりにくい」とか「ライブラリが汎用性を狙い過ぎていて複雑」というような欠点があることに後で気づくのですが、私はこのオブジェクト指向設計の「綺麗さ」に惹かれ、まずは自分のアプリケーションを mbed で実装してみることにしました。

Nordic 社も、これくらい利用者の視点に立ったサンプルコード、またドキュメントを用意してくれていたらなあ、という気持ちになりますが、次回は、実際に mbed で BLE ペリフェラルアプリを書いてみた経験談(失敗談)を書きたいと思います。(実際には、Nordic 社の評価ボードを持っていないと、mbed 以外での開発はやや取っ付きづらいかな、とも思います。)

今日はここまで。