【重要】LINBLE-Z2量産販売開始およびLINBLE-Z1使用部品変更予定のお知らせ

センサ値をBLEビーコンのアドバタイズパケットとして発信する方法(ソフトウェア編)【第4回】

こんにちは。ムセンコネクト三浦です。

第3回の記事では「センサ搭載BLEビーコンのハードウェア構成」について解説しましたが、第4回となる今回は「BLEビーコンのファームウェア」について解説します。

【この記事の要点】

ビーコンは、センサ値などのデータをBLEの「アドバタイズパケット」に載せて発信します。本記事は発信側のソフトウェア(アドバタイズの設定・生成)の実装を、照度センサを例に解説します。正しく飛んでいるかは受信して確認します。受信は、パソコンに挿すだけで受信内容(BDアドレス・UUID・RSSI)を1行出力する『ビーコンドングル』を使うと、開発中の動作確認が手早く行えます。

目次

概要・前提条件

今回はnRF5 SDKのビーコンのサンプルファームウェアをベースに、ムセンコネクトの「オープンセンササービス」を配信するファームウェアについて解説します。配信するセンサデータは、照度(データ種別:0x13)です。

本記事は、nRF52シリーズをnRF5 SDKで開発した経験があるエンジニアを対象としています。
開発環境の構築方法は、ノルディックの公式サイト等を参照してください。

ビーコンのデモボード構成

発信側はBLEモジュール(nRF52系)+センサで構成し、取得した値をアドバタイズに載せて一定間隔で発信します。

構成型番メーカー
DKボードPCA10040(nRF52832)Nordic Semiconductor
照度センサBH1745NUCROHM Semiconductor
センサ搭載BLEビーコンのデモボード

ハードウェアの詳細はこちら

開発環境

IDESegger Embedded Studio v5.42a
nRF5 SDKnRF5_SDK_17.1.0_ddde560
ベースサンプルhttps://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/ble_sdk_app_beacon.html

動作仕様

発信間隔・アドバタイズ種別・載せるデータ(照度センサ値)などの仕様を定義します。

BLE関連

ベースサンプルのまま変更なしとしています。

項目
アドバタイズPDUタイプADV_NONCON_IND
アドバタイズインターバル100ms

アドバタイズパケットフォーマット

今回は配信するセンサデータが「照度(データ種別:0x13)のみ」であるため、フォーマットは下記の通りです。

OffsetSizeFieldDescription備考
010x0BLength
110x16Service Device data type value
220xFCBEOpen Sensor Serviceオープンセンササービスでは固定値0xFCBEを利用します
410x01Data Schema Version現状は固定値0x01を利用します
540xXXXXXXXX個体識別番号4バイト固定
910x13データ種別=照度(2byte)
1020xXXXX照度データ2バイト unsigned 単位:0.1lx

照度センサ関連

項目
通信方式I2C
スレーブアドレス0x39(ADDR=1)
測定周期(Measurement time)160ms
測定値読み出し周期1,000ms

なお、照度センサの制御方法については、本記事では割愛します。
BH1745NUCのウェブサイトを参照してください。

ソースコード解説

アドバタイズの初期化と、センサ値に応じたアドバタイズデータの更新をコードで実装します。

アドバタイズモジュールの初期化

次の関数でアドバタイズモジュールを以下のパラメータで初期化します。

  • アドバタイズPDUタイプ:BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED (ADV_NONCON_IND)
  • アドバタイズインターバル:NON_CONNECTABLE_ADV_INTERVAL(100ms)
  • アドバタイズデータを格納する構造体( m_adv_data )のポインタ

サンプルでは、アドバタイズモジュールの初期化とアドバタイズデータの生成処理を同じ関数 ( advertising_init )内で実行していますが、アドバタイズデータを一定周期で更新するため、アドバタイズデータの生成処理は別の関数( advertising_update )に分けました。

static void advertising_init(void)
{
    uint32_t      err_code;

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 0;       // Never time out.

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
    APP_ERROR_CHECK(err_code);
}

アドバタイズデータの生成・更新

次の配列でサービスデータの16bit UUID以降のデータを定義します。

#define DATA_SCHEMA_VERSION   0x01                   /**< Reserved area. */
#define DEVICE_IDENTIFIER     0x11, 0x22, 0x33, 0x44 /**< Temporary value. */
#define DATA_TYPE_ILLUMINANCE 0x13                   /**< Illuminance (unit:0.1lux). */
#define ILLUMINANCE_LUX       0x00, 0x00             /**< Illuminance value. */

static uint8_t m_beacon_info[] =
{
    DATA_SCHEMA_VERSION,
    DEVICE_IDENTIFIER,
    DATA_TYPE_ILLUMINANCE,
    ILLUMINANCE_LUX,
};

次の関数で、新しい照度値でアドバタイズデータを再生成し、アドバタイズモジュールが参照する構造体( m_adv_data )を更新します。

本関数実行後に配信されるアドバタイズから、新しいアドバタイズデータが適用されます。

本関数をタイマー割り込みで実行することで、一定周期でアドバタイズデータを更新しています。

static void advertising_update(uint16_t illuminance_0_1lux)
{
    uint32_t err_code;

    ble_advdata_t advdata;

    m_beacon_info[6] = (uint8_t)((illuminance_0_1lux >> 8) & 0x00FF);
    m_beacon_info[7] = (uint8_t)((illuminance_0_1lux >> 0) & 0x00FF);

    ble_advdata_service_data_t service_data;
    service_data.service_uuid = OPEN_SENSOR_SERVICE;
    service_data.data.p_data = &m_beacon_info[0];
    service_data.data.size = sizeof(m_beacon_info);

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.p_service_data_array = &service_data;
    advdata.service_data_count   = 1;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);
}

今回解説したBLEビーコンのファームウェアのソースコードは下記リンクからダウンロード可能です。

これでBLEビーコンのハードウェア、ソフトウェア解説は終了です。

よくある質問(FAQ)

BLEのアドバタイズパケットとは?

接続を確立せずに周囲へ一方向に配信するBLEのブロードキャスト用パケットです。ビーコンはこれを一定間隔で発信し、受信側は接続不要でデータを受け取れます。iBeaconもこのアドバタイズを使った仕組みです。

アドバタイズのデータフォーマット(advertising data format)は?

「長さ+AD種別(AD Type)+データ」の組(AD構造)を複数連ねた形式です。1パケットの有効データは基本31バイトで、センサ値は主にManufacturer Specific DataやService Dataの領域に格納します。

アドバタイズに載せられるデータ量は?

1つのアドバタイズパケットの有効ペイロードは基本31バイトです。それを超える情報はScan Responseの併用や、Extended Advertising(拡張アドバタイズ)で拡張します。

発信したアドバタイズを受信して確認するには?

受信機でパケットを取得します。手早く確認するなら、USBに挿すだけで受信内容(BDアドレス・UUID・RSSI等)を1行出力する『ビーコンドングル』が便利で、開発中のデバッグツールとして使えます。

アドバタイズ発信(beacon advertiser)を自作するには?

BLEモジュールのファームウェアでアドバタイズ設定(間隔・種別・ペイロード)を実装します。発信できたら、受信側で正しく飛んでいるかを確認する工程が必要です。受信の確認はUSB受信アダプタを使うと開発が速くなります。

第5回となる次回はBLEビーコンが発信したセンサ値を受信するためのWindowsアプリについて解説します。

発信できたら、次は受信で確認。

『ビーコンドングル』はパソコンやRaspberry PiのUSBに挿すだけで、受信パケットの内容(BDアドレス・UUID・RSSI)を1行出力。開発中の動作確認ツールに最適です。iBeaconや各種BLEビーコンに対応し、Bluetooth認証はムセンコネクト取得済み。まずは評価機の貸出でお試しいただけます。

▶ 評価機の貸出・技術相談はこちら

製品の詳細を見る:iBeacon・各種BLEビーコン受信アダプタ『ビーコンドングル』

よろしければシェアをお願いします
目次