RSSI(Received Signal Strength Indicator)は、受信側でBLEデバイスの信号強度をdBm単位で測定する数値指標です。RSSI値は-30 dBm(デバイスが近くにある)から-100 dBm(検出限界)までの範囲です。Bluetooth Core Specification 5.4(2023)は、RSSIを各アドバタイジングパケットおよびデータパケットで利用可能なオプションパラメータとして定義しています。RSSIは距離推定と信号レベルによるデバイスのフィルタリングに使用されますが、不正確な指標です:障害物、マルチパス伝搬、アンテナの種類の影響を受けます。正確な位置特定には三角測量とKalmanフィルタリングが使用されます。
重要ポイント
RSSI(Received Signal Strength Indicator)は、パケット受信時にBLE受信機が受信した無線信号電力の測定値です。BLEでは、RSSIは各アドバタイジングパケットと接続後の各データパケットについて測定されます。RSSIは対数スケールであり、1 dBmの各ステップは信号電力の約1.26倍の変化に相当します。
RSSIはハードウェア依存の指標です:異なるBLEチップ(nRF、TI、Dialog、Broadcom)や異なるアンテナは、同じ信号に対して異なるRSSI値を示すことがあります。したがって、異なるデバイス間でRSSIを比較することは不適切です。同じOSの同一のスマートフォン2台でも、同じビーコンに対して2~5 dBmの差を示すことがあります。
アドバタイジングパケットでは、RSSIは3つのチャンネル(37、38、39)のそれぞれについて測定されます。周波数干渉のため、チャンネル間で値が3~10 dBm異なることがあります。最新のBLEスタックは、全チャンネルの平均RSSIまたはパケットごとの個別RSSIを報告します。iOS Core Bluetoothは平均RSSIを提供し、Androidは最後のパケットのRSSIを提供します。
BLEの典型的なRSSI範囲は-30 dBmから-100 dBmまでです。この範囲外の値は極めて稀です:-20 dBmはデバイスがスキャナーアンテナに文字通り接触していることを意味し、-105 dBmは信号が完全にないことを意味します。チップメーカーは範囲を制限することがあります:例えば、nRF52832は-40~-105 dBmのRSSIを報告します。
| RSSI(dBm) | 信号品質 | おおよその距離 | 推奨 |
|---|---|---|---|
| -30~-50 | 優秀 | 0~1 m | デバイスが近くにある |
| -51~-70 | 良好 | 1~5 m | 部屋内 |
| -71~-85 | 普通 | 5~15 m | ビーコンとして許容範囲 |
| -86~-95 | 弱い | 15~30 m | 信頼性の低い接続 |
| -95未満 | 致命的 | 30 m以上 | 検出限界 |
TX Power Levelは、アドバタイジングパケット(AD Type 0x0A)で示される送信電力であり、推定値の調整を可能にします。TX Power +4 dBmのデバイスからのRSSI -70 dBmは、信号が74 dB減衰したことを意味します。TX Powerが不明な場合、正確な距離推定は不可能です。iBeaconは、距離校正のためにManufacturer Data構造にTX Power(1バイト)を含めています。
Path Lossモデル(伝搬損失)は、RSSIから距離を推定するために使用されます。基本式:RSSI = TX_Power - 10 × n × log10(d)。ここでnは減衰係数(自由空間では2.0、障害物のある屋内環境では3.0~4.5)、dはメートル単位の距離です。実際には、実環境での推定精度は±2~5 mです。
モデルを校正するには、既知の距離(通常1 m)でRSSIを測定し、TX Power基準値を計算する必要があります。iBeaconでは、このパラメータはパケットに格納されています。Eddystoneも同様のメカニズムを使用しています。校正後、距離を計算できます:d = 10 ^ ((TX_Power — RSSI) / (10 × n))。
Apple Core Bluetooth Programming Guide(2024)によると、iBeaconの距離推定精度は以下の通りです:immediate(0.5 m未満)— RSSIが校正値を上回る場合、near(0.5~3 m)— RSSIが校正値の3~6 dB以内の場合、far(3 m超)— 微弱な信号の場合。追加処理なしでは、どの数学モデルも±1 mを超える精度を提供できません。
RSSIはノイズの多い指標であり、その精度は多くの要因に依存します。誤差の主な原因:障害物(壁、家具、人)はそれぞれ信号を3~15 dB減衰させ、マルチパス伝搬(壁での反射)は一部の地点で信号を強め、別の地点で弱め、アンテナの向きはデバイスを回転させるとRSSIを3~10 dB変化させます。
人体はBLE信号の最も強い吸収体の一つです。ビーコンとスマートフォンの間に人がいると、RSSIは10~20 dB低下する可能性があります。人体の水分は2.4 GHzの電波を効果的に吸収します。そのため、店舗のドアにあるビーコンは、身長や体格の異なる顧客に対して異なるRSSIを示すことがあります。
追加要因:隣接チャンネルのWi-Fi干渉はRSSIを3~5 dB低下させる可能性があり、BLEチップの温度はRSSI測定精度に影響し(一部のチップでは最大1 dB/°Cのドリフト)、ビーコンのバッテリー劣化はTX Powerを低下させ、受信機でのRSSI低下につながります。
生のRSSIは正確な計算には適していません— ノイズや外れ値が多すぎます。安定した距離推定値を得るためにフィルタリング手法が使用されます。最も簡単なのは移動平均です:直近N個のRSSI値の算術平均を取ります。短期変動を平滑化するには、通常N = 5~10で十分です。
// RSSI用カルマンフィルター
class RssiKalmanFilter(
private val processNoise: Double = 0.01,
private val measurementNoise: Double = 1.0
) {
private var estimate: Double = 0.0
private var errorCovariance: Double = 1.0
fun filter(rawRssi: Double): Double {
// 予測
errorCovariance += processNoise
// 更新
val kalmanGain =
errorCovariance /
(errorCovariance + measurementNoise)
estimate = estimate +
kalmanGain * (rawRssi - estimate)
errorCovariance =
(1.0 - kalmanGain) * errorCovariance
return estimate
}
}
Kalmanフィルターは、RSSI変化のダイナミクスを考慮し、移動平均よりも遅延が少ない、より高度な手法です。固定ビーコンの場合、移動平均で許容可能な結果が得られます。移動デバイスの場合、変化に迅速に適応するKalmanフィルターが望ましいです。さらに、外れ値を除外するために中央値フィルターを使用することもできます。
iOS Core Bluetoothは、RSSI読み取り完了後にperipheral.rssiプロパティ(NSNumber)を介してRSSIを提供します。アドバタイジングパケットのRSSIを取得するには、advertisementData[CBAdvertisementDataRSSIKey]を使用します。iOSは3チャンネルの平均値としてRSSIを返します。継続的なRSSI監視の場合は、1秒に1回以下の間隔でreadRSSIを呼び出します。
// iOSでRSSIを取得
func centralManager(
_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any],
rssi RSSI: NSNumber
) {
let signalStrength = Int(truncating: RSSI)
// 弱い信号をフィルター
guard signalStrength > -90 else {
return
}
print("デバイス " +
"\(peripheral.name ?? "unknown") " +
"RSSI: \(signalStrength) dBm")
}
Androidは、onScanResultコールバックを介してRSSIを提供します:result.getRssi()。RSSI値は最後のアドバタイジングパケットのRSSIであり(平均ではありません)。安定した測定値を得るには、複数の値を蓄積してフィルタリングを適用する必要があります。Androidはまた、アドバタイジングパケットで送信されている場合、result.getScanRecord().getTxPowerLevel()を介してTX Power Levelも提供します。
// AndroidでRSSIを取得
private val scanCallback = object : ScanCallback() {
override fun onScanResult(
callbackType: Int,
result: ScanResult
) {
val rssi = result.rssi
val txPower = result.scanRecord?.
txPowerLevel ?: -128
// カルマンフィルターを適用
val filtered = kalmanFilter.
filter(rssi.toDouble())
Log.d("BLEScanner",
"RSSI: $rssi, " +
"Filtered: $filtered, " +
"TX: $txPower")
}
}
位置特定にRSSIを使用するアプリケーションを開発する際は、以下の点に注意してください:iOSではハードウェア校正によりRSSI値がより安定しており、Androidではノイズが多くデバイスメーカーに依存します。クロスプラットフォームプロジェクトでは、各プラットフォーム用の設定可能なパラメータを使用してアプリケーション側でフィルタリングを実装することをお勧めします。
よくある質問
いいえ、RSSIは実際の条件では±2~5 mの精度でおおよその推定しか提供しません。正確な位置特定には、複数のスキャナーによる三角測量、Kalmanフィルタリング、TX Powerの考慮が必要です。
マルチパス伝搬と無線信号の変動のためです。壁や物体での反射が干渉を生み出し、信号が強まったり弱まったりを繰り返します。静止デバイスでの5~10 dBのRSSI変化は正常です。
iOSはreadRSSIを1秒に1回以上呼び出さないことを推奨しています。あまりに頻繁なリクエストはデータパケットの損失につながる可能性があります。スキャン中のRSSI監視には、各アドバタイジングパケットで利用可能なCBAdvertisementDataRSSIKeyを使用してください。
TX Power Levelは、アドバタイジングパケットで示されるdBm単位の送信電力です。RSSI + TX Power = 送信機から受信機までの総信号減衰量です。TX Powerが分かれば、より正確な距離推定が可能です:RSSI - TX Power = Path Loss(経路損失)。
固定ビーコンの場合 — 5~10値のウィンドウを持つ移動平均。移動デバイスの場合 — 低プロセスノイズ(0.01~0.05)のKalmanフィルター。外れ値を除外するには、2標準偏差を超える値を除去する中央値フィルターを追加します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。