BLE 物理層の詳細とスキャン頻度

BLE(Bluetooth Low Energy) を使う上で、アドバタイズ方式(iBeacon方式)と GATT(Generic Attribute Profile)を使ったコネクション方式があるわけですが、まずは近接しているデバイスを見つけないといけません。iBeacon の場合はスマホアプリから iBeacon の端末を見つけないといけないし、GATT の場合はペリフェラル側のワイヤレスイヤフォン等をスマホアプリから見つけないといけません。

店内にある iBeacon デバイスとか、目の前に接続しようとしているワイヤレスイヤフォンの場合は、アプリを立ち上げた後に “すぐそこにある端末” に接続するまでじっと待つというスタイルになります。これ、当たり前のように思えますが、最初のデバイスを見つける手順はどうなっているのでしょう? ってのが問題です。

この図では、「スマホ」から「iBeacon」に向かって矢印を向けていますが、実際は iBeacon 側から何等かのデータを発信していて、スマホ側のアプリが受け取るという形になります。

こんな風に、iBeacon 側で何度も発信しているものを、スマホ側でなんらかのタイミングで受け取れることができる、ってのが正しいです。

BLE 物理層(PHY) の仕様

BLE の物理層は、2.4 GHz 帯の ISM バンドを使っています。一般的に、広告チャンネル(アドバタイズ)とデータチャンネルの2種類に分かれています。

  • 広告チャンネル(アドバタイズ)が 37,38,39 の 3 チャンネル
  • データチャンネルが 0-36 の 37 チャンネル

合計 40 チャンネルを使っているので、BLE 通信をしているときに、たくさんの端末があってもデータ通信は大丈夫、という仕組みです。
ただし、この3つしかない広告チャンネルってのが問題で、BLE ペリフェラル(発信側)がアドバタイズを行うときには、この3つのチャンネルを順番に使って発信しています。これは、

  • iBeacon や ENA/FolkBears のように、コネクションレスでアドバタイズを行うとき
  • GATT のように、コネクションを確立する前のデバイスを見つけるとき

に重要になります。いや、先の例のように設置してある iBeacon デバイスを見つけるときとか、目の前にあるワイヤレスイヤフォンを見つけるときには問題ありません。スマホアプリを使って接続できるかなぁと暫く待てば、iBeacon もワイヤレスイヤフォンも見つかります。

普通の BLE デバイスの場合は、接続までの時間が 30 秒位あっても問題はありません。確かに店内設置のような iBeacon デバイスを発見するのに 30 秒位掛かると遅くて問題になるかもしれませんが、この発見までの時間は確率的に決まるものなので、早く見つかることもあれば遅く見つかることもあります。これは後述します。

また、接触データの交換をするにしても、最初に相手のデバイスを見つけないといけません。これは BLE のチャンネル自体は 40 チャンネルあってデータ送受信で競合しないようになっていますが、実は相手のデバイスを発見するための広告チャンネルを使うために、3 チャンネルしかないということです。
要は意外と少ないという話です。

さらに、接触確認アプリのようにできるだけ短時間で接触を確認したい場合には、発見までの時間が重要になります。いわゆる発見までの遅延があるわけです。

そういうわけで、接触確認アプリ(m5stack等で作れば接触確認デバイス)を作る場合には、発見までの遅延が重要になります。このあたり、なぜかというと、数秒ですれ違ったりする場合には確率的に相手のデバイスを発見できない可能性があるということです。

  • 広告チャンネルの 3 チャンネルで競合する
  • 発見までの遅延が確率的にある
  • 複数の BLE デバイスが集中する場合、発見しない可能性もある

ということを抑えておく必要があります。

パケットの構造

BLE のパケットの話を少し書いておきます。

最初、BLE データの衝突で、データ落ちがあると思っていたのですが、それはほとんどあり得ません、ということです。

BLE パケットは以下のような構造になっています。

  • Preamble: 1 byte PHY チャンネル識別用
  • Access Address: 4 byte 固定値 0x8E89BED6
  • Header: 2 byte パケット種別、長さ情報
  • Protocol Data Unit (PDU): 0-37 byte ペイロードデータ
  • CRC: 3 byte 誤り検出用

一般的に 32 バイトの BLE データと言っているのが、Protocol Data Unit の部分です。だいたい、データとして利用できる範囲は 31 byte 程度です。これが無線でデータとして飛んできます。周波数なので 0/1 のビット列で飛んでいき、これを受信してチェックするわけです。

データ長自体は、たかだか 47 バイト程度です。データ通信の場合はもう少し多くなるのですが、ここでは広告アドバタイズ(iBeacon)や GATT の最初のデバイス検出だけを考えてみましょう。

BLE 1M PHY では、1 Mbps となるので、47 bytes のデータを送ると概ね 400 μs 程度で送信できます。0.4 ms 以下ですね。実に短く一瞬のうちに終わります。

実に短時間で 47 byte のデータが飛び交っているので、3 チャンネルしかない広告チャンネルであっても、iBeacon デバイスが 100 台ぐらいあっても衝突はほとんど起こりません。これは、データ自体が 0.4 ms 程度の短時間で送受信されるためです。

つまり、接触確認アプリを持ったひとたちが 100 人位ぎゅうぎゅうに集まったとしても(コンサートとか満員電車とか)、BLE の広告チャンネルでの衝突はほとんど起こらない、ということです。

これ、現象として、たくさんの人たちが集まると携帯電話が繋がりにくいという現象とは異なることがわかります。携帯電話の場合は、基地局と常に通信することになるので、BLE の広告アドバタイズとは発見タイミングが異なるということです。

アドバタイズ間隔とデータ量

さて、iBeacon の発信や、GATT のデバイス発見のためのアドバタイズが、常に発信できる(常にセントラルで発見できる)状態になっているとは限りません。と言いますか、広告アドバタイズは、どのように発信されているのでしょうか?

実は、47 bytes のデータが常に発信されているわけではなく、一定間隔で発信されています。この間隔をアドバタイズ間隔(Advertising Interval)と言います。

  • 広告間隔(Advertising Interval)
    – 最小 20 ms、最大 10,240 ms
    – デフォルトは 100 ms 程度
  • アドバタイズデータのデータ量
    – 最大 47 バイト程度
    – 実質的に 0.4 ms 程度で送信可能
  • アドバタイズの揺らぎ advDelay
    – 0 〜 10 ms のランダムな遅延が追加される

送信している時間は 0.4 ms と短いのですが、それが常に送信されているわけではありません。広告間隔(Advertising Interval)によって、一定の間隔で送信されています。この他に誤差ではありますが、アドバタイズの揺らぎ(advDelay)として、0 〜 10 ms のランダムな遅延が追加されています。これはきっちりとした間隔で送信してしまうと、受信側で同期していしまってアドバタイズが受信できなくなってしまうからです。このあたりは BLE アドバタイズの仕様ですね。

つまりは、こんな風に iBeacon デバイスが発信しているときにうまくスマホアプリが受信していないといけないわけです。

このあたり有線通信ではなくて無線通信ってところがミソです。無線通信の場合は、発信側と受信側が常に同期しているわけではないというのと、発信側のバッテリーの問題があります。特に iBeacon 発信デバイスはバッテリーが少ないので、できるだけ発信回数を減らすことが求められます。
つまりは、電力消費の観点から、できるだけ広告間隔(Advertising Interval)を長くしたい、ということです。

スキャン間隔とスキャンウィンドウ

では、iBeacon や GATT のデバイス発見のために、スマホアプリ側はどのように受信しているのでしょうか?
これも常に受信状態にあるわけではなく、スキャン間隔とスキャンウィンドウという仕組みで受信しています。

  • スキャン間隔(Scan Interval)
    – 最小 2.5 ms、最大 10,240 m
    – デフォルトは 100 ms 程度
  • スキャンウィンドウ(Scan Window)
    – 最小 2.5 ms、最大 10,240 ms
    – スキャン間隔以下の値に設定する必要がある
    – デフォルトは 100 ms 程度

緑の部分がスキャンウィンドウ(Scan Window)で、ここで受信を行っている状態です。その Scan 状態も常に続いているわけではなくて、スキャン間隔(Scan Interval)が空いています。
つまり、iBeacon がうまく送信時間になっているときに、スマホアプリのほうがうまく Scan Window の時間に入っていないと受信できない、ということです。
実に絶妙なタイミングが必要なわけです。

ただし、さきほど書いたように送信時間自体は 0.4 ms と非常に短い状態です。
これに対してスマホの Scan Window は最小の設定でも 2 ms 程度はあるし、もっと長くすることも可能です。
バッテリーの問題として、データの発信には電力が必要ですが、データの受信にはあまり電力が必要ではありません。よって、発信は短く、受信は長くしておくのがセオリーです。実際 BLE の送受信はそういう仕組みになっています。

しかし、図のように、必ずしも BLE のアドバタイズのデータがスマホ側の Scan Window にあてはまるとは限りません。真ん中のデータはうまく受信していますが、左のデータは Scan Window の外側で発信されているために受信できていません。

BLE アドバタイズの取りこぼし or 遅延の原因

この Scan Window, Scan Interval と Advertising Interval の関係で、BLE アドバタイズの取りこぼしや発見遅延が発生します。つまりは、確率的に、最初の一発目で受信できることもあれば、なかなか受信できないという現象が発生するわけです。

概算する式的にはこんな感じになります。

発見遅延 = Advertising Interval / Scan Duty Cycle
Scan Duty Cycle = Scan Window / Scan Interval

例えば、Advertising Interval が 100 ms、Scan Interval が 100 ms、Scan Window が 50 ms の場合、Scan Duty Cycle は 0.5 となり、発見遅延は 200 ms となる。つまり、平均して 200 ms 後に発見されることになります。200 ms 後に発見されるならばまだ誤差として良い方です。

例えば、相互のバッテリー消費を少なくするために、次のような設定をしたとします。

  • Advertising Interval: 1000 ms
  • Scan Interval: 2000 ms
  • Scan Window: 100 ms

この場合、Scan Duty Cycle は 0.05 となり、発見遅延は 20,000 ms となる。つまり、平均して 20 秒後に発見されることになります。

これの意味は、20 秒後に必ず発見されるという意味ではありません。
iBeacon デバイスや BLE ワイヤレスイヤフォンのように、その場に居続ける端末の場合にはいいのですが、近接接触確認アプリのように相互に歩いていたり、席から離れたりするときには 20 秒後には居なくなっている可能性もあります。特にすれ違いの場合はいなくなっています。すれ違いなんって距離を含めれば 5 秒もないでしょう。
なので、発見遅延を考えると、20 秒の発見遅延を許す場合は、すれ違いの発見は実質できないということなります。正確に言えば、すれ違いを発見したり、発見しなかったり、という現象が発生します。

これも、必ずしも発見できないわけではなく、確率的に発見できない可能性があるということです。逆に言えば、接触データを調べたときに、接触データがないなかといって接触がなかったとは限らない、という状態です。いわゆる、信頼区間というものがあるのです。
また、この例でいえば、平均 20 秒程度の遅延が発生するわけですから、接触データの時刻に接触したという訳ではないということです。それよりも平均 20 秒前には既に接触している、という意味になります。

Advertising Interval と Scan Duty Cycle のバランス

というわけで、Advertising Interval と Scan Duty Cycle のバランスが重要になります。
店舗などの入店確認では 1 分程度の遅延が許されるが、接触確認アプリではどのくらいの遅延が許されるのかを考えないといけません。

  • 発見遅延が大きい場合(1,2分とか)、すれ違いの場合は検出できない?
  • 発見遅延が小さい場合(数百 ms)は、電力の消費がどのくらいなのか?
  • 発見遅延が小さい場合、数十台の端末が集まったときはどうなるのか?

ということをシミュレーションする必要がでてきます。

余談

ただし、このあたりは物理層としての電波の発信/受信の問題だけでなく、OS 側の BLE スタックの実装(特に セントラル側のスキャン動作)にも依存すると思われます。

よって

  • 電波の到達だけでなく、実働として OS 側の BLE スタックの動作も調査する必要がある
  • 電波は届いているが、発見遅延により検出されない
  • 電波は届いているが、ペリフェラルの端末が多いため、検出されない(プログラムの問題?)

という違いが出てくる。これを実機で確認する必要がでてきます。

このあたり、スマホ端末での BLE が不意に止まってしまう現象を次の話題にします。特に Android の機種によっては、連続した BLE 運用は考えていないらしく、途中で BLE が止まってしまいます。

カテゴリー: 開発, FolkBears パーマリンク