SSブログ

BLE Beacon の初歩 [PSoC]このエントリーを含むはてなブックマーク#

PSoC Advent Calendar 2016の3日目の記事です。

BLE Beacon というアプリケーションは、複数の BLE Beacon からの電波を受信して、受信場所の座標を推定するというものです。 そのため、 BLE Beacon は、 BLE Beacon の座標または座標を調べる事のできる一意な ID を発信します。 この記事では、可能な限り簡単に BLE Beacon を作成する方法をさぐります。

使用するハードウェア

CY8CKIT-145-40XX

今回使用するハードウェアは、 CY8CKIT-145-40XX PSoC® 4000S CapSense Prototyping Kit です。 今回は、このキットの裏側に搭載された EZ-BLE PRoC Module だけを使います。

BLEコンポーネントの設定

回路図

回路図に配置するのは、 BLE コンポーネントだけです。 今回作成する BLE Beacon は、データを入力せず、電波以外の物を出力しないので、端子の設定も必要ありません。


General タブ

まず、 General タブで作成するデバイスの振る舞いを決定します。 BLE Beacon は、他のデバイスとデータのやり取りをするものではなく、一方的にパケットを送信します。 このような用途で使われるデバイスを Broadcaster と呼んでいます。

これに対して、 Broadcaster の電波を受け取る事を目的としているデバイスは Observer と呼ばれます。 BLE Beacon の受信側はスマートフォンなどで行う事が多いのですが、 EZ-BLE PRoC Module を Observer として受信専用にする事もできます。


GAP Settings - General

GAP Setting タブでは、主に送信するパケットの詳細を設定します。 General ノードでは、デバイス ID とデバイス名を設定しています。 ここで設定されたデバイス名は、 BLE Beacon では使われないのでデフォルトのままにしています。


GAP Settings - Advertisement settings

Advertisement settings ノードでは、 Advertisement パケットの送信方法を規定します。 データのやり取りをするわけではないので、 Non-connectable に設定します。 Advertisement パケットの送信周期が指定されていますが、実際には、この周期は使用されていません。

BLE Beacon のパケット構成

GAP Settings - Advertisement packet

Advertisement packet では、BLE Beacon として送信するパケットの構成を指定します。 このパケットは、必須の Flags フィールドと Manufacturer Specific Data フィールドから構成されています。


Manufactrer Specific Data

Manufacturer Specific Data は、 Company ID と Data から構成されています。 Company ID には、 "Apple Inc." の 0x004C が入っています。 別の ID を使うと Android 版のアプリケーションでは認識できるのですが、 iOS 版のアプリケーションでは認識できないようです。 なんでかな?


Data フォーマット

Data には、 BLE Beacon で定められたフォーマットでデータを格納します。 CYALKIT-E02 Solar-Powered BLE Sensor Beacon Reference Design Kit (RDK) が Wireless Sensor Node (WSN) として使用される場合、16バイトの UUID には、アプリケーションの識別子として定められた値 "00050001-0000-1000-8000-00805F9B0131" が入ります。 それ以外に BLE Beacon からの情報を入れられるのは、 Major と Minor と呼ばれる合わせて4バイトのフィールドだけです。

WSN では、 Major 部分に識別 ID が入り、 Minor 部分にセンサから得られた値を入れるようになっています。 サイプレスのアプリケーション BLE-Beacon では、決められた UUID を持つパケットだけを検出するように作成されています。

クロックの設定

高速クロック設定

CPU および周辺回路は、24MHz外部発振子で作られた 24MHz のクロックをそのまま使用します。


低速クロック設定

32.768kHz 外部発振子で作られた WCO クロックは、 Timer0 で 16384 分周され 500ms ごとに割り込みを発生させ、ファームウェアのステートマシンを駆動します。

ソフトウェア

ソフトウェア

ソフトウェアは、以下のようになっています。

#include <project.h>

// Major/Minor フィールドの位置
#define     MAJOR_OFFSET    (26u)
#define     MINOR_OFFSET    (28u)

// Minor フィールドの最小・最大値および変化ステップ
#define     MINOR_MIN       (69u)   //  0℃相当の値
#define     MINOR_MAX       (126u)  // 40℃相当の値
#define     MINOR_STEP      (1u)    // Minor値の変化量

最初は、定数が定義されます。 このプログラムでは、温度情報が入っている場所にある値を変化させて、データの取りこぼしが無いかを確認しています。 MAJOR_MIN から MAJOR_MAX まで MAJOR_STEP 刻みで値を変化させます。 ここでは、0℃相当の値から40℃相当の値まで変化させているので、受信側ではノコギリ波が観測されるはずです。

// Major/Minor フィールドの値
uint8   f_minor = MINOR_MIN;        // Minorフィールドの値
uint8   f_major = 0;                // Majorフィールドの値

// BLE の初期化終了フラグ
uint8   initialized = 0;

// ソフトウェアタイマのカウンタ
uint8   tick = 0;

これだけの大域変数が宣言されています。 f_major/f_minor は、それぞれ Major/Minor フィールドに与えられる値を示しています。 initialized は、 BLE デバイスの初期化が終わったかどうかのフラグになっています。 tick は、タイマ割り込みで使用されるソフトウェアタイマのカウンタになっています。

// 500msごとに Advertisement パケットを開始・停止する
void Wdt_Callback(void) {
    if (initialized) {
        // 初期化がされた
        if (tick == 0) {
            // 最初の500msで Advertisement パケットを送信する
            
            // Major フィールドの設定
            cyBle_discoveryData.advData[MAJOR_OFFSET] = f_major;
            
            // Minor フィールドの設定
            if ((f_minor < MINOR_MIN) || (f_minor > MINOR_MAX)) {
                f_minor = MINOR_MIN;
            }
            cyBle_discoveryData.advData[MINOR_OFFSET] = f_minor;
            f_minor += MINOR_STEP;

            // Advertisement パケットの送信を開始する
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            tick = 1;
        } else {
            // 次の500msで Advertisement ポケットの送信を止める
            CyBle_GappStopAdvertisement();
            tick = 0;
        }
    }
}

500ms ごとに割り込みがかかると、このコールバックルーチンが呼び出されます。 コールバック関数の設定は、メインループで行われています。

BLE の初期化が終わっていたら、 BLE の動作処理をおこないます。 一周期は二つの 500ms 割り込みで構成されています。 前半の 500ms では、 Advertisement パケットの送信を開始します。 送信内容は、コンポーネントの設定で使用した値に Major/Minor フィールドの値を加えたものです。 最後に CyBle_GappStartAdvertisement() 関数で Advertisement パケットの送信を開始します。 実際には、割り込み処理が終了してメインループに戻った時にパケットの送信が行われます。

一方、後半の 500ms では、 Advertisement パケットの送信を禁止しています。 通常 Advertisement パケットを送信する時には、コンポーネントで設定された周期にしたがって、 Advertisement パケットを送信します。 このアプリケーションでは、 Advertisement パケットの送信間隔をタイマで管理することで、精密な送信間隔を実現しようとしています。

こうして、1秒間に一回、 BLE Beacon から Advertisement パケットが送信されます。

// BLE スタックの処理ハンドラ
void StackEventHandler(uint32 event, void *eventParam) {
    switch (event) {
        // スタックが立ちあがったまたはデバイスが切断されたら初期化終了とみなす
        case CYBLE_EVT_STACK_ON:
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            initialized = 1;
            break;
        // それ以外のイベントは無視する
        default:
            break;
    }
}

BLE が状態の変化を検出した時に呼び出されるのがイベント処理ハンドラですが、ここで対応しているのは、ふたつのイベントのみです。 いずれも、 BLE の初期化が終わった時に発生するイベントなので、 initialized フラグを立てて、初期化終了を知らせます。

// メインループ
int main() {
    CYBLE_API_RESULT_T apiResult;       // エラーコード

    // 割り込みを許可する
    CyGlobalIntEnable;
    
    // 低速タイマ Timer0 のコールバック関数を設定する
    CySysWdtSetInterruptCallback(CY_SYS_WDT_COUNTER0, Wdt_Callback);

    // BLE デバイスの初期化を行う
    apiResult = CyBle_Start(StackEventHandler);
    // 初期化が正常に終わったかを確認する
    CYASSERT(apiResult == CYBLE_ERROR_OK);

    for(;;){
        // BLE スタックへのイベントを処理する
        CyBle_ProcessEvents();
    }
}

メインループでは、タイマのコールバック関数を指定し、 BLE コンポーネントの初期化を行ったあと、 BLE のイベント処理を行うループに突入します。 これだけで、 BLE デバイスの出来上がりです。

観測結果

観測結果

プロジェクトが完成したら、スマートフォンで観測してみましょう。 使用するのは、 Cypress が提供する BLE-Beacon というアプリケーションで、 Android 版は Google Play から、 iOS 版は Apple Store から入手できます。

私の Android 端末では、このように表示されました。 ここで作成したデバイスは、1秒ごとにパケットを送信しています。 Android 端末でも Log 上では、1秒ごとにパケットを受信している事がわかるのですが、 Graph 表示にすると5秒に一回しかプロットしてくれません。 どうも、描画処理が間に合っていないそうです。 一方、 iOS 版では、1秒ごとにプロットが出力されます。

プロジェクトアーカイブ

この記事で作成したプロジェクトは、このファイルの拡張子を "zip" に変更すると再現できます。

参考サイト

S6SAE101A00SA1002 Solar-Powered IoT Device Kit
太陽電池で動作する Wireless Sensor Node (WSN) を開発するためのキットです。 BLE Beacon としての動作には代わりがありませんが、サイプレスの Company ID が使用されています。
CYALKIT-E02 Solar-Powered BLE Sensor Beacon Reference Design Kit (RDK)
WSN をばらまく時に使われるハードウェアを備えた設計例です。 今回の記事は、このキットから BLE Beacon の部分を抜き出しています。
CY8CKIT-145-40XX PSoC® 4000S CapSense Prototyping Kit
今回の記事で使用したハードウェアです。 本来は、 PSoC 4 S-Series の開発キットなのですが、裏側に EZ-BLE PROC Module が付いているので、これを利用させてもらいました。
EZ-BLE PRoC Module (Bluetooth Smart)
今回の記事のターゲットとなったデバイスです。 無線モジュールとして供給されていますが、 PSoC Creator では、単体のデバイスと同等に扱われます。

参考商品

PSoC 4 BLE

PSoC 4 BLE

  • 出版社/メーカー: スイッチサイエンス
  • メディア: エレクトロニクス

nice!(1)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 1

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました