BLEと組込み無線
コイン電池で数年動くセンサをBLEで作れるようになる。GAP/GATTの役割分担、アドバタイズと接続、サービスとキャラクタリスティック、低消費電力設計を原理から押さえ、無線スタックとアプリを正しく分離できる。
- 1.BLEは2層構造で理解する。GAPが「発見と接続」(アドバタイズ・スキャン・役割)を、GATTが「データの構造と読み書き」(サービス/キャラクタリスティック)を担う。GAPで線をつなぎ、GATTでその線に何を流すかを決める。
- 2.低消費電力の本質は接続間隔とスリープ。接続イベントの一瞬だけ無線を起こし、残りは深いスリープで過ごす。接続間隔・スレーブレイテンシ・アドバタイズ間隔が平均電流を支配し、コイン電池で年単位の寿命を出す。
- 3.無線スタックとアプリは物理的に分離される。コントローラ(PHY/リンク層、厳密なタイミング)とホスト(L2CAP/ATT/GATT)がHCIで結ばれ、アプリはGATTのイベントだけ見ればよい。この分離が認証取得と移植性の前提になる。
BLEを「発見層」と「データ層」に分けて捉える
Bluetooth Low Energy(BLE)は、コイン電池で年単位に動くことを最優先に設計された近距離無線です。同じ Bluetooth の名を冠しながら、音声ストリーミング用の Bluetooth Classic とはプロトコルもチップ内実装も別物で、BLE は「たまに少量のデータを送る」用途に全振りしています。この BLE を理解する最短経路は、機能を2つの層に割って見ることです。
一つは GAP(Generic Access Profile)。デバイスをどう見つけ、どう役割を決め、どう接続を張るかという「発見と接続」を司ります。もう一つが GATT(Generic Attribute Profile)。つながった相手との間で、データをどんな構造で持ち、どう読み書きするかという「データの表現とアクセス」を司ります。GAP で通信路という線を引き、GATT でその線に何を流すかを決める——この分業が BLE 設計の背骨です。両者は独立に設計判断ができ、混同すると「接続はできるのにデータが読めない」「アドバタイズは見えるのに役割が噛み合わない」といった典型的な躓きを生みます。
GAP:アドバタイズ・スキャン・接続
GAP はまずデバイスに 役割(ロール) を割り当てます。接続前は、自分の存在を周期的にばら撒く アドバタイザ と、それを探す スキャナ の2役。接続が成立すると、接続を主導した側が セントラル、待ち受けていた側が ペリフェラル になります。センサやウェアラブルは電池側=ペリフェラル、スマホやゲートウェイは電源に余裕のある側=セントラルになるのが定石です。
接続前の通信はすべて アドバタイジング で行われます。ペリフェラルは 3 本の専用チャネル(37/38/39ch。Wi-Fi の混雑帯を避けて配置)で、一定の アドバタイズ間隔 ごとにパケットを放ちます。セントラルはこれらのチャネルを スキャン して受信します。ここでスキャナは受信するだけの パッシブスキャン と、アドバタイザに追加情報を要求する アクティブスキャン(スキャンリクエストを投げ、スキャンレスポンスを得る)を選べます。
BLE 接続確立までの流れ:
[ペリフェラル] [セントラル]
アドバタイズ間隔ごとに 3チャネルをスキャン
ADV パケット送信 ── 37/38/39ch ──► 受信して発見
│ │
│ (必要なら)スキャン要求
│ │
◄──────── 接続要求(CONNECT_IND)────┘
│
└─► 以降はデータチャネル(0〜36ch)へ移り、
接続イベントを周期的に繰り返す
接続要求が届くと、両者はアドバタイズチャネルを離れ、37 本のデータチャネルを 周波数ホッピング(毎接続イベントで規則的にチャネルを変える)しながら通信します。これにより特定チャネルの干渉を回避し、多数の BLE デバイスが同じ帯域で共存できます。アドバタイズ間隔を長くすれば消費電流は下がりますが発見までの遅延(レイテンシ)は延びる——この時点で早くも電力とレスポンスのトレードオフが顔を出します。
BLE は必ずしも接続を張る必要はありません。ビーコン(店舗の位置通知など)は接続せず、アドバタイズパケットのペイロードにデータを載せてブロードキャストし続けるだけで成立します。接続確立の往復もコネクションの維持も不要なので、送信側の消費電力を極限まで下げられます。「まず接続」と思い込まず、片方向・少量なら非接続のアドバタイズで足りることは多くあります。
GATT:サービスとキャラクタリスティック
接続が張れたら、データのやり取りは GATT の世界に入ります。GATT はすべてのデータを アトリビュート(属性) という統一形式で表現します。各アトリビュートは「ハンドル(16bit の通し番号)」「タイプ(UUID)」「値」「アクセス権限」を持ち、その集合をツリー状に組み立てたものが GATT データベースです。この属性群を意味のある単位にまとめる階層が、サービスとキャラクタリスティックです。
- サービス(Service): 関連する機能のまとまり。例「心拍サービス」「バッテリーサービス」。標準化されたものは 16bit の短い UUID を持ち、独自機能は 128bit のカスタム UUID を割り当てます。
- キャラクタリスティック(Characteristic): サービス内の個々のデータ項目。実際の値(心拍数、電池残量など)と、その扱い方を示すプロパティ(Read/Write/Notify/Indicate)を持ちます。
- ディスクリプタ(Descriptor): キャラクタリスティックに付随するメタ情報。特に重要なのが CCCD で、後述の通知をオン/オフする設定を保持します。
| 操作 | 方向 | 確認応答 | 用途と特徴 |
|---|---|---|---|
| Read | セントラル→ペリフェラル要求 | 値を返す | セントラルが能動的に現在値を取得 |
| Write | セントラル→ペリフェラル | あり(Write Request) | 設定変更など確実に届けたい書き込み |
| Write Without Response | セントラル→ペリフェラル | なし | 応答を待たず高速。取りこぼし許容の連続書き込み |
| Notify | ペリフェラル→セントラル | なし | 値変化をペリフェラル主導で通知。低オーバーヘッド |
| Indicate | ペリフェラル→セントラル | あり(受信確認) | 確実に届けたい通知。応答待ちで遅い |
実務で最も多用されるのが Notify です。センサ値が変わるたびにペリフェラルからセントラルへ押し込む方式で、セントラルが周期的に Read で問い合わせる(ポーリング)より無駄がありません。通知を有効にするには、セントラルが対象キャラクタリスティックの CCCD(Client Characteristic Configuration Descriptor) に「通知有効」を書き込みます。ここが BLE 実装で頻出の落とし穴で、「Notify プロパティを付けたのに値が飛んでこない」原因の大半は、セントラル側が CCCD を有効化していないか、ペリフェラルのアプリが CCCD の状態を見ずに送信していることです。
Notify は確認応答なし(送りっぱなし)で高スループット、Indicate は1件ごとに受信確認を待つため確実だが遅く、応答が返るまで次を送れません。頻繁に更新するセンサ値(加速度・心拍)は Notify、確実に届ける必要のある少数のイベント(アラート・設定完了)は Indicate、という使い分けが原則です。全部 Indicate にすると往復待ちでスループットが落ち、消費電力もかえって増えます。
低消費電力設計:接続間隔とスリープが命
BLE が「Low Energy」たりうる核心は、無線をほぼ常に眠らせておける点にあります。接続中も回線を張りっぱなしにするのではなく、接続イベント と呼ぶ短い交信の瞬間だけ送受信し、それ以外は無線を止めて深いスリープに入ります。この周期を決めるのが接続パラメータです。
- 接続間隔(Connection Interval): 接続イベントの周期。7.5ms〜4秒の範囲で設定。短いほど低遅延・高スループットだが、起きる回数が増えて電流も増える。
- スレーブレイテンシ(Slave/Peripheral Latency): ペリフェラルが送るデータを持たないとき、応答を何回スキップしてよいかの回数。これにより「接続は維持したまま、実質的に起きる頻度を下げる」ことができる。
- スーパービジョンタイムアウト: この時間だけ交信が途絶えたら接続断とみなす上限。接続間隔とレイテンシから整合の取れた値を選ぶ必要がある。
平均電流を決める要素(接続時):
実効ウェイク周期 ≒ 接続間隔 ×(スレーブレイテンシ + 1)
(送るデータが無ければレイテンシ分イベントをスキップできる)
例: 接続間隔 30ms, スレーブレイテンシ 4
→ データ無しなら最大 30ms×5 = 150ms ごとにだけ起床
平均電流 ≒ (1イベントの電荷 + スリープ電流×間隔) / 実効ウェイク周期
→ 「起きる回数」を減らすほど平均電流は下がる
考え方は組込み全般の低電力設計と同じで、支配するのは平均電流です。各起床で無線 IC が消費する電荷は、送受信そのものより 無線を立ち上げてキャリブレーションし、受信ウィンドウを開く固定コスト が大きい部分を占めます。だから「1回あたりを軽くする」より「起きる回数を減らす」ほうが効き、スレーブレイテンシを効かせて不要なイベントを飛ばす設計が要になります。電源ドメインやスリープ階層、平均電流の見積り手法そのものは /embedded/low-power-sleep-modes/ が原理から詳しく、無線イベントを取りこぼさず起床させる割込みの仕組みは /embedded/interrupt-handling-isr/ が扱います。
接続パラメータの最終決定権はセントラル(スマホ側など)にあります。ペリフェラルは「この範囲が望ましい」と接続パラメータ更新要求を出せますが、拒否されることもあります。実機では、スマホ OS が電池や互換性の都合で独自の接続間隔を強制し、ファームの想定より頻繁(または低頻度)に起こされて消費電流や遅延が設計値からずれるのが典型的なハマりどころです。狙った電力を出すには、実接続で実際に採用された間隔を必ず実測して確認します。
無線スタックとアプリの分離:コントローラ/ホスト/HCI
BLE のソフトウェアは、明確に階層化されたスタックとして実装され、アプリケーションはその最上段だけを見れば済むように分離されています。この分離は単なる整理ではなく、電波法規制上の認証(技適・FCC 等)と移植性のために本質的です。
| 層 | 担当 | 主な責務 | タイミング要求 |
|---|---|---|---|
| コントローラ | リンク層 / 物理層(PHY) | 変調・チャネルホッピング・接続イベントの正確な送受信タイミング・CRC/暗号化 | 極めて厳密(µs 単位・専用HW/RF) |
| HCI | ホストとコントローラの境界 | 両者を結ぶ標準コマンド/イベントのインタフェース | — |
| ホスト | L2CAP / ATT / GATT / SM / GAP | 属性プロトコル・ペアリング・接続管理・データの構造化 | 緩やか(ソフトで処理) |
| アプリケーション | プロファイル実装 | サービス/キャラクタリスティックの定義と業務ロジック | アプリ次第 |
下段の コントローラ は、電波を扱うリンク層と物理層を受け持ちます。接続イベントの送受信は数マイクロ秒単位の精密なタイミングが要求されるため、専用の無線ハードウェアと密結合した固定ファームで実装され、認証もこの層に対して行われます。上段の ホスト は、属性プロトコル(ATT)、その上の GATT、暗号鍵交換を行うセキュリティマネージャ(SM)、そして GAP を含み、ソフトウェアで動きます。両者を結ぶのが HCI(Host Controller Interface) という標準インタフェースです。
この境界が標準化されているおかげで、実装形態を選べます。ワンチップ SoC ではコントローラとホストが同一チップ上で動き HCI は内部 API になりますが、外付け BLE モジュールを UART で繋ぐ構成では、ホスト(アプリ側 MCU)とコントローラ(モジュール)が物理的に別チップとなり、HCI コマンドが実際に線上を流れます。後者ではホストとコントローラ間の伝送に UART などのシリアルバスが使われ、その物理層は /embedded/bus-i2c-spi-uart/ が扱う近距離バスそのものです。いずれの構成でも、アプリケーションは GATT のイベント(接続、書き込み受信、通知有効化)だけを見ればよく、電波のタイミングを一切意識せずに済みます。この徹底した関心の分離が、BLE を「アプリ開発者が無線の専門家でなくても使える」技術にしています。SoC 全体でこれらの層がどう同居するかは /embedded/microcontroller-architecture/ の周辺統合の視点とつながります。
まず GAP と GATT の役割分担を即答できること——GAP=発見と接続(アドバタイズ/スキャン、セントラル/ペリフェラル)、GATT=データ構造(サービス/キャラクタリスティック、Read/Write/Notify/Indicate)。次に「Notify と Indicate の違い」=確認応答の有無。「通知が来ない時に疑う設定」=CCCD の有効化。「低消費電力を決めるパラメータ」=接続間隔とスレーブレイテンシ。「コントローラとホストを分ける境界」=HCI。この5点は BLE の頻出ポイントです。
まとめ
- BLE は GAP(発見と接続) と GATT(データの構造とアクセス) の2層で捉える。GAP でアドバタイズ・スキャンして接続を張り、セントラル/ペリフェラルの役割を決め、GATT でサービス/キャラクタリスティックとしてデータを読み書きする。
- 接続前はアドバタイズチャネルで周期送信、接続後はデータチャネルを周波数ホッピングして干渉を避ける。接続を張らずアドバタイズのペイロードだけで完結するビーコン用途もある。
- データ操作は Read/Write/Notify/Indicate の4系統。頻繁な値更新は応答なしの Notify、確実に届けたい少数イベントは Indicate。通知はCCCD の有効化が前提で、ここが実装の頻出落とし穴。
- 低消費電力の核心は「起きる回数を減らす」こと。接続間隔とスレーブレイテンシが実効ウェイク周期を決め平均電流を支配する。最終決定権はセントラルにあるため実測が必須。
- スタックはコントローラ(PHY/リンク層、厳密なタイミング)/ホスト(L2CAP/ATT/GATT/SM/GAP)/アプリに分離され、境界の HCI が SoC 内部にも外付けモジュール構成にも対応する。アプリは GATT イベントだけを見ればよい。
組込み・IoT Article
BLEと組込み無線を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
組込み
比較で見る軸
難易度: advanced / カテゴリ: 組込み・IoT / タグ数: 6
導入後に効く点
低消費電力の本質は接続間隔とスリープ。接続イベントの一瞬だけ無線を起こし、残りは深いスリープで過ごす。接続間隔・スレーブレイテンシ・アドバタイズ間隔が平均電流を支配し、コイン電池で年単位の寿命を出す。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- 組込み・IoT
- タグ数
- 6
判断チェックリスト
- 自社の用途が「組込み / BLE」に近いか確認する。
- 強みである「BLEは2層構造で理解する。GAPが「発見と接続」(アドバタイズ・スキャン・役割)を、GATTが「データの構造と読み書き」(サービス/キャラクタリスティック)を担う。GAPで線をつなぎ、GATTでその線に何を流すかを決める。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。